I know this question was posted 4 years ago, but I hope someone can find this useful.
Here is a way to do that
There are something called worker pool https://gobyexample.com/worker-pools Using go routines and channels
But in the following code I adapt it to a handler. (Consider for simplicity I'm ignoring the errors and I'm using jobs as global variable)
package main
import (
"fmt"
"net/http"
"time"
)
var jobs chan int
func worker(jobs <-chan int) {
fmt.Println("Register the worker")
for i := range jobs {
fmt.Println("worker processing job", i)
time.Sleep(time.Second * 5)
}
}
func handler(w http.ResponseWriter, r *http.Request) {
jobs <- 1
fmt.Fprintln(w, "hello world")
}
func main() {
jobs = make(chan int, 100)
go worker(jobs)
http.HandleFunc("/request", handler)
http.ListenAndServe(":9090", nil)
}
The explanation:
main()
- Runs the worker in background using a go routine
- Start the service with my handler
- note that the worker in this moment is ready to receive a job
worker()
- it is a go routine that receives a channel
- the for loop never ends because the channel is never closed
- when a the channel contain a job, do some work (e.g. waits for 5 seconds)
handler()
- writes to the channel to active a job
- immediately returns printing "hello world" to the page
the cool thing is that you can send as many requests you want and because this scenario only contains 1 worker. the next request will wait until the previous one finished.
This is awesome Go!
http.StatusAcceptedthere instead ofhttp.StatusOK– 200 implies you've serviced the request. 202 tells the client that you intend to service the request, but you've not necessarily done so yet. 204 (http.StatusNoContent) is also sometimes acceptable, but I probably wouldn't use it in this case. - Dustin