Webhook 进程在另一个 goroutine 上运行

我想在另一个 goroutine 中运行一些缓慢的例程,这样做是否安全:


func someHandler(w http.ResponseWriter, r *http.Request) {

   go someReallySlowFunction() // sending mail or something slow

   fmt.Fprintf(w,"Mail will be delivered shortly..")

}


func otherHandler(w http.ResponseWriter, r *http.Request) {

   foo := int64(0)

   bar := func() {

      // do slow things with foo

   }

   go bar()

   fmt.Fprintf(w,"Mail will be delivered shortly..")

}

这样做有什么问题吗?


SMILET
浏览 114回答 2
2回答

潇湘沐

为每个 http 请求提供服务在其自己的 goroutine 中运行(更多详细信息)。您可以从您的处理程序启动新的 goroutine,它们将同时运行,独立于执行处理程序的 goroutine。需要注意的一些事项:新的 goroutine 独立于处理程序 goroutine 运行。这意味着它可能在处理程序 goroutine 之前或之后完成,如果没有显式同步,您不能(不应该)假设与此有关的任何事情。处理程序的http.ResponseWriter和http.Request参数仅在处理程序返回之前有效且安全使用!这些值(或它们的“部分”)可以重复使用 - 这是一个实现细节,您也不应该对其进行任何假设。一旦处理程序返回,您不应该触摸(甚至不读取)这些值。一旦处理程序返回,响应就会被提交(或者可能随时提交)。这意味着您的新 goroutine 不应尝试使用http.ResponseWriterafter this 发回任何数据。这在某种程度上是正确的,即使您不触摸http.ResponseWriter处理程序中的 ,处理程序的不恐慌也被视为成功处理请求,因此返回 HTTP 200 状态(参见示例)。您可以将http.Requestandhttp.ResponseWriter值传递给其他函数和新的 goroutine,但必须注意:如果您打算从多个 goroutine 读取/修改这些值(或者您想要从多个 goroutine 发回数据)。请注意,如果您的处理程序 goroutine 和新的 goroutine 都只是读取/检查http.Request,这似乎仍然可能是有问题的。是的,多个 goroutine 可以在不同步的情况下读取同一个变量(如果没有人修改它)。但是调用 的某些方法http.Request也会修改http.Request,如果没有同步,就不能保证其他 goroutine 会从这个变化中看到什么。例如Request.FormValue(),返回与给定键关联的表单值。但是这个方法调用ParseMultiPartForm()并ParseForm()在必要时对其进行修改http.Request(例如,他们设置了Request.PostForm和Request.Form结构字段)。因此,除非您同步您的 goroutine,否则您不应将Requestand传递ResponseWriter给新的 goroutine,而是从Request处理程序 goroutine 中获取所需的数据,并仅传递例如struct保存所需数据的 a。你的第二个例子:foo := int64(0)bar := func() {   // do slow things with foo}go bar()这很好。这是一个闭包,它所引用的局部变量只要可访问,就会继续存在。请注意,您也可以将局部变量的值作为参数传递给匿名函数调用,如下所示:foo := int64(0)bar := func(foo int64) {   // do slow things with param foo (not the local foo var)}go bar(foo)在这个例子中,匿名函数将看到并使用它的参数foo而不是局部变量foo。这可能是您想要的,也可能不是您想要的(取决于处理程序是否也使用foo以及是否需要任何 goroutine 所做的更改对另一个可见 - 但这无论如何都需要同步,这将被通道解决方案取代)。

隔江千里

如果您关心邮件的确认,那么发布的代码将无济于事。在单独的 goroutine 中运行代码使其独立,即使由于 goroutine 函数中的某些错误导致邮件未发送,服务器也会回复成功。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go