我有一个处理程序函数,用于处理对我的 API 端点的 POST 请求。在这个处理函数中,我希望有一个并发的 go 例程来调用另一个系统(大约需要 20 分钟),同时,无论该 go 例程的进度如何,我都想返回 201 成功结果.
/// createKitchenWork in reality makes calls to different systems and roughly takes 20 minutes to finish.
func createKitchenWork(wg *sync.WaitGroup, params OrderParams) {
defer wg.Done()
for i := range params.Quantities {
kitchen.client.CreateWork()
}
}
func Order(params orderParams) orderResponse {
wg := New(sync.WaitGroup)
wg.Add(1)
createKitchenWork(wg, params)
return orderResponse{
http.StatusOk
}
}
我的目标是在调用Order函数后能够立即发送orderResponse,并希望在返回orderResponse的情况下,go例程createKitchenWork也能继续运行。
我想过在 go 例程之后和 return orderResponse 语句之前添加 wg.Wait() ,但这意味着 go 例程将阻塞 return orderResponse 语句。
func Order(params orderParams) orderResponse {
wg := New(sync.WaitGroup)
wg.Add(1)
createKitchenWork(wg, params)
wg.Wait() //This will block my goal to return the orderResponse right away after the Order() is triggered since the createKitchenWork go routine will take roughly 20 min.
return orderResponse{
http.StatusOk
}
}
我也想过在 return orderResponse 语句之后添加 wg.Wait(),但 linter 表明这种方法不起作用。
func Order(params orderParams) orderResponse {
wg := New(sync.WaitGroup)
wg.Add(1)
createKitchenWork(wg, params)
return orderResponse{
http.StatusOk
}
wg.Wait() // the Order() had exited before coming to this line.
}
知道如何重构/重写这个处理函数来实现目标吗?
只需在处理程序中创建一个 goroutine,然后返回:
func Handler(w http.ResponseWriter, rq *http.Request) {
request:=readRequest()
go processRequest(request)
}
在
processRequest
中,您可以处理任何请求。有以下几点需要注意:
rq.Context()
功能中使用 processRequest
。当处理程序返回时,该上下文将关闭。ResponseWriter
。