gpt4 book ai didi

http - 传入请求的上下文

转载 作者:IT老高 更新时间:2023-10-28 13:08:16 25 4
gpt4 key购买 nike

我时常会遇到“上下文” 概念,该概念通常是为所有传入请求创建的。最近看了Go blog article描述使用 golang.org/x/net/context 包。然而,在玩过代码并尝试复现文章的逻辑之后,我仍然很难理解如何将它用于每个传入的请求,甚至不明白它为什么有用。

我应该如何组织我的代码以使用 golang.org/x/net/context 包为每个传入请求创建上下文(以及它通常应该包含什么)?谁能举个小例子,解释一下什么是有用的以及为什么如此频繁使用?

最佳答案

上下文传递最常见的需求之一是将传出请求与传入请求相关联。我已经将它用于各种目的,例如:

  • 我希望我的数据库组件的错误日志包含来自它的结果的 http 请求的完整 url。
  • 传入的 http 请求包含一组 header ,我需要保留这些 header 并将其传递给我在下游调用的其他 http 服务(可能出于跟踪原因)。
  • 我想在其他组件中检查传入的 http 请求,以进行访问控制或用户身份验证等。这可能在 http 处理程序层,或者我的应用程序的其他部分。

许多语言和平台都有方便/神奇的方式来获取当前的 Http 请求。 C# 有 HttpRequest.Current 对任何想知道当前 http 请求上下文的人来说都是全局可用的(通过线程本地存储)。您可以在其上设置任意数据以传达各种上下文数据。其他平台也有类似的设施。

由于 go 没有 goroutine 本地存储的设施,因此无法在当前 http 请求的上下文中存储全局变量。相反,在系统边界初始化上下文(传入请求)并将其作为参数传递给需要访问该信息的任何下游组件是惯用的。

一种 super 简单的方法是使用当前的 http 请求创建一个上下文对象并传递它:

func someHandler(w http.ResponseWriter, r * http.Request){
ctx := context.WithValue(context.Background(),"request",r)
myDatabase.doSomething(ctx,....)
}

您当然可以将其限制为您需要传递的更有针对性的数据集,而不是整个请求。

上下文包可以帮助的另一件事(我认为该博客在指出方面做得很好)是超时或截止日期的通用框架。

请注意,上下文包不会为您强制超时。由接收上下文对象的组件来观看 Done channel 并自行取消它们自己的 http 请求或数据库调用或计算或其他任何事情。

编辑 - 超时

能够从组件外部管理超时非常有用。如果我有一个数据库模块,我不需要硬编码超时值,只需能够处理从外部触发的超时。

我做到这一点的一种方法是在每个传入请求中进行多个数据库/服务调用的服务中。如果总时间超过 1 秒,我想中止所有出站操作并返回部分或错误结果。在顶层使用超时初始化上下文并将其传递给所有依赖项是一种非常简单的管理方法。

依赖项收听 Done channel 并中止它的工作并不总是很好,但正如博客所示,这也不是很痛苦。

关于http - 传入请求的上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28486324/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com