Webhook 进程在另一个 goroutine 上运行

2023-12-07

我想在另一个 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..")
}

这样做有什么陷阱吗?


为每个 http 请求提供服务在其自己的 goroutine 中运行(有关于此的更多详细信息)。您可以从处理程序启动新的 goroutine,并且它们将同时运行,独立于执行处理程序的 goroutine。

需要注意的一些事项:

  • 新的 goroutine 独立于处理程序 goroutine 运行。这意味着它可能在处理程序 goroutine 之前或之后完成,如果没有显式同步,您不能(不应该)假设与此相关的任何内容。

  • The http.ResponseWriter and http.Request处理程序的参数仅在处理程序返回之前才有效且可以安全使用!这些值(或其中的“部分”)可以重复使用 - 这是一个实现细节,您也不应该假设任何内容。一旦处理程序返回,您不应触摸(甚至不读取)这些值。

  • 一旦处理程序返回,响应就会被提交(或者可以随时提交)。这意味着你的新 goroutine 不应尝试使用以下方法发回任何数据http.ResponseWriter在这之后。即使您不触摸http.ResponseWriter在您的处理程序中,处理程序不会出现恐慌被视为成功处理了请求,因此会发回 HTTP 200 状态(看一个例子).

您可以通过http.Request and http.ResponseWriter其他函数和新 Goroutines 的值,但必须小心:如果您打算从多个 Goroutines 读取/修改这些值(或者您想从多个 Goroutines 发回数据),则应该使用显式同步(例如锁、通道) 。

请注意,看起来如果您的处理程序 Goroutine 和新的 Goroutine 都只是读取/检查http.Request,这仍然可能有问题。是的,多个 goroutine 可以读取同一个变量而无需同步(如果没有人修改它)。但调用某些方法http.Request还修改http.Request,如果没有同步,就无法保证其他 goroutine 会从这个变化中看到什么。例如Request.FormValue()返回与给定键关联的表单值。但这个方法调用ParseMultiPartForm() and ParseForm()如有必要,修改http.Request(例如,他们设置了Request.PostForm and Request.Form结构字段)。

所以除非你同步你的 goroutine,否则你不应该通过Request and ResponseWriter到新的 goroutine,但从新的 goroutine 获取所需的数据Request在处理程序 goroutine 中,并且仅传递例如Astruct保存所需的数据。

你的第二个例子:

foo := int64(0)
bar := func() {
   // do slow things with foo
}
go bar()

这完全没问题。这是一个closure,并且它所引用的局部变量只要可访问就会一直存在。

请注意,您也可以将局部变量的值作为参数传递给匿名函数调用,如下所示:

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 可见 - 但这无论如何都需要同步,这将被通道解决方案取代)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Webhook 进程在另一个 goroutine 上运行 的相关文章

随机推荐

  • 如何在不移动其他元素的情况下放大div

    我怎样才能停止这个 div 将所有元素移动到您选择特定价格的位置下方 要了解我在说什么 请查看此链接 查看价格表样式3在其下方 您可以看到 当您选择某个价格表时 下面的所有元素都会因弹出而移动 我希望能够使用此功能 但当然不能移动下面的所有
  • 多个单通道矩阵转换为单个多通道矩阵

    我正在使用带有矩阵的 opencv c api 我有 4 个单通道 Mat 我想将其合并为一个 4 通道矩阵 它基本上是我在 4 个矩阵中拥有的 rgba 通道 并且想要组合成一个 rgba 图像 矩阵 谁知道该怎么做 您可以使用简历 合并
  • DQL 选择具有一列 MAX 值的每一行

    使用 Symfony 2 和 Doctrine 我正在寻找一种方法来选择特定列中具有最大值的每一行 现在 我正在两个查询中执行此操作 一种获取表中列的最大值 然后我选择具有该值的行 我确信这可以通过一个查询来完成 搜索中 我发现了这个答案
  • 如何在 C# 中更改组合框的外观

    我尝试在 xaml 中将 ComboBox 背景 前景 borderbrush 设置为蓝色只是为了测试 但它仍然保持丑陋的灰色 我也尝试过使用资源字典 但它不想改变 这是我使用组合框的 XAML
  • Haskell - 在模式匹配中使用常量

    假设我有以下代码 文本在 lt gt 是简写 实际上不是代码的一部分 data A
  • matlab导入多张图像

    我有一组连续命名的 100 张 jpg 图像 我想将它们相加以获得单个图像 我已经看到答案了here 但它不跟我一起运行 发生了什么事 这是代码 im imread C Documents and Settings 1026175117 1
  • 如何从文件中读取位?

    我知道如何读取字节 x read number of bytes 但是如何读取 Python 中的位呢 我必须从二进制文件中仅读取 5 位 而不是 8 位 1 字节 有什么想法或方法吗 Python 一次只能读取一个字节 您需要读取一个完整
  • 无需按 Control 键即可选择多行

    我有一个网格视图 可以通过按控制键选择多行 是否可以在不按控制键的情况下实现相同的目的 由于 net 默认操作也会更新slectedrows你的datagridview你需要有一个数组来保留旧的选择 DataGridViewRow old
  • Fragment 和 FragmentActivity 有什么区别?

    我的问题是除了明显的继承差异之外 两者之间的主要区别是什么Fragment and FragmentActivity 每个类别最适合什么场景 我试图了解为什么这两个类别存在 A Fragment是一个的一部分Activity 其中有 它自己
  • 按图像路径在数据库中的 RDLC 报告上显示图像

    图像路径存储在SQL Server 2008数据库中 在我的 RDLC 报告上 我有一个图像字段 我已设置此字段以从数据库中的数据库列获取图像路径 我还在报告查看器中将 EnableExternalImages 属性设置为 true 我不知
  • UIScrollView 滚动时取消 UIPageViewController 手势

    我有一个UIPageViewController它负责翻我的 书 的页面 然而 每一本书的页面都是一个ViewController with a UIScrollView as a subview The UIScrollView只能垂直滚
  • 使用 PHP 克隆 + 重命名文件

    如何使用 php ini 克隆并重命名文件 我需要采取 拇指 123 jpg Copy it 将其重命名为thumb 456 jpg 我可以很好地进行重命名rename 这是我没有得到的复制 copy thumb 123 jpg thumb
  • JQuery Slider,如何更改“步长”大小

    是否可以使用 JQuery 滑块 范围滑块 双滑块 来获得非线性 不一致的 步长 大小 值 我想要水平滑块看起来像 0 500 750 1000 1250 1500 2000 2500 75000 100000 例如 我想要以下 JQuer
  • Flink 应用程序的检查点大小持续增长

    我有这样的管道 env addSource kafkaConsumer name source keyBy value gt value f0 window EventTimeSessionWindows withGap Time seco
  • 如何将 git 存储库的副本(存档,而不是克隆)连接到其远程?

    我想知道如何将 git 存储库的副本 存档 而不是克隆 与其远程存储库连接并同步 背景 我有一个本地和远程存储库 我使用 git archive 压缩本地存储库 然后将其复制到服务器 git archive format tar HEAD
  • 使用 python 请求下载 *.gz 压缩文件会损坏它

    我使用此代码 它只是一部分 来下载 gz 存档 with requests session as s s post login to site URL payload load s get scene stream True with op
  • Rails 如何将参数从控制器传递到模型内的 after_save

    我有一个 Rfq 控制器 我正在创建新的或更新现有的 Rfq 当我创建或更新保存对象时 我想要的是因为我有引号参数的数量 所以我想使用 params quotes 中的引号更新 line items 表 保存询价后在 quote price
  • LoadViewState 未在我的用户控件上触发

    我有一个嵌套在中继器中的用户控件 在我的用户控件中 我有另一个中继器 其中有一个面板 我试图重写用户控件的 LoadViewState 事件并将控件动态添加到面板 我想在 LoadViewState 中执行此操作 以便在加载视图状态之前添加
  • Wso2IS 跳过authenticationendpoint/login.do

    使用 java 客户端 我生成了 SAMLRequest 字符串有没有办法发布整个数据 并跳过 IdentityServer 登录页面 我传递的数据必须满足SSO的身份验证 然后生成Oauth2 Token 您可以使用请求路径认证并在同一请
  • Webhook 进程在另一个 goroutine 上运行

    我想在另一个 goroutine 中运行一些缓慢的例程 这样做安全吗 func someHandler w http ResponseWriter r http Request go someReallySlowFunction sendi