I am writing a web application where I have a long running goroutine. I want to delegate all HTTP requests to this goroutine via channels. The pattern that I have come across is:
// Internal long running goroutine
for{
select{
case e := <-event: //web request
req := e.req
// do something
....
select {
case <-ctx.Done():
//log
default:
e.replyTo <- result
}
}
}
// Web handler
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
//decode request etc
...
replyTo := make(chan interface{}, 1)
ctx, cancel := context.WithCancel(context.BackGround())
event <- Event{req: req, ctx: ctx, replyTo: replyTo}
select{
case <-time.After(time.Second):
cancel()
//return 500
case r := <-replyTo:
// return some response
}
})
I do see that there is one single go-routine at the end, so parallelism is lost but I am okay with it.
Is this pattern the right way of doing this? What other approaches can be suggested?