【问题标题】:How to copy Context object without deriving如何在不派生的情况下复制上下文对象
【发布时间】:2019-12-15 22:42:42
【问题描述】:

我想复制一个上下文对象——确切地说是一个请求上下文,然后在单独的 go 例程中使用它。

问题是,如果我使用context.WithCancel(reqCtx) 派生请求上下文,一旦此请求的 HTTP 处理程序完成,不仅原始请求上下文会被取消,而且请求上下文的副本也会被取消。

我希望能够复制原始请求上下文,并且在 HTTP 处理程序完成执行后不会被原始上下文取消。

【问题讨论】:

  • 那为什么不创建一个新的上下文呢?只需复制价值或您自己需要的任何东西。您可以使用 context.Background() 获得新的上下文
  • 我如何知道要从上下文中获取哪些值?这些值会因场景而异。我正在寻找不会让我手动将值从一个上下文复制到另一个上下文的东西。
  • 也许你可以给出场景?在我看来,您试图在上下文中传递太多数据,而不是仅仅构建结构并传递它们。也许这也有帮助stackoverflow.com/questions/40379960/…
  • 如果请求的上下文达到了它的截止日期而你的上下文没有,会发生什么?你不应该创建新的上下文,使用请求上下文副本并将你的值存储在那里
  • 要回答为什么有人会合理地想要这样做,想象一下对于某些请求,您不希望处理程序所做的任何事情都被客户端挂断,但是您也有请求- 特定数据,例如用户 ID,可能已被身份验证过滤器插入到上下文中。您不想丢失用户 ID,也不想将请求上下文的子项传递给不间断操作。您可以将 ID 从一个上下文复制到另一个上下文,但这意味着您的处理程序需要了解很多关于过滤器对上下文所做的事情。

标签: http go copy cancellation


【解决方案1】:

以下是如何创建一个使用来自其他上下文的值但不使用取消的上下文:

type valueOnlyContext struct{ context.Context }
func (valueOnlyContext) Deadline() (deadline time.Time, ok bool) { return }
func (valueOnlyContext) Done() <-chan struct{} { return nil }
func (valueOnlyContext) Err() error { return nil }

像这样使用它:

 ctx := valueOnlyContext{reqCtx}

使用不取消的值可能超出了上下文包的设计意图。如果包的设计者认为这是一件好事,我会期望他们将上述内容捆绑在一个上下文包函数中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 2018-08-22
    • 2023-04-08
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多