Skip to content

Instantly share code, notes, and snippets.

@Apurer
Created May 11, 2023 09:17
Show Gist options
  • Save Apurer/fcf7a3c1128761abf64c8a05666248a4 to your computer and use it in GitHub Desktop.
Save Apurer/fcf7a3c1128761abf64c8a05666248a4 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"net/http"
"sync"
"time"
)
type Task struct {
IP string
IsDone bool
Done chan struct{}
Request *http.Request
}
type Queue struct {
LastTask *Task
Mutex sync.Mutex
}
var queues sync.Map
func longRunningTask(task *Task) {
// Simulate a long running task
time.Sleep(5 * time.Second)
// Mark the task as done
task.IsDone = true
close(task.Done)
queues.Delete(task.IP)
}
func requestHandler(w http.ResponseWriter, r *http.Request) {
ip := r.RemoteAddr
value, _ := queues.LoadOrStore(ip, &Queue{})
queue := value.(*Queue)
queue.Mutex.Lock()
defer queue.Mutex.Unlock()
// If there's an ongoing task for the IP, replace the request in the queue with the current request
if queue.LastTask != nil && !queue.LastTask.IsDone {
queue.LastTask.Request = r
http.Error(w, "Request queued, waiting for ongoing task to finish", http.StatusAccepted)
return
}
// Start a new long-running task with the current request
task := &Task{
IP: ip,
IsDone: false,
Done: make(chan struct{}),
Request: r,
}
queue.LastTask = task
go longRunningTask(task)
// Send a response to the client
fmt.Fprintf(w, "New task started for IP: %s\n", ip)
}
func main() {
http.HandleFunc("/", requestHandler)
http.ListenAndServe(":8080", nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment