如何重构这个函数,使得handler函数返回后goroutine可以继续运行

问题描述 投票:0回答:1

我有一个处理程序函数,用于处理对我的 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.
}

知道如何重构/重写这个处理函数来实现目标吗?

go concurrency goroutine waitgroup
1个回答
0
投票

只需在处理程序中创建一个 goroutine,然后返回:

func Handler(w http.ResponseWriter, rq *http.Request) {
   request:=readRequest()
   go processRequest(request)
}

processRequest
中,您可以处理任何请求。有以下几点需要注意:

  • 您无法在
    rq.Context()
    功能中使用
    processRequest
    。当处理程序返回时,该上下文将关闭。
  • 处理程序返回后,您无法使用
    ResponseWriter
© www.soinside.com 2019 - 2024. All rights reserved.