douhu8851 2015-02-12 19:39
浏览 130
已采纳

传入请求的上下文

From time to time I am faced with the "Context" concept which, as a rule is created for all incoming requests. Recently I've read the Go blog article that describes using the golang.org/x/net/context package. However, after playing with the code and trying to reproduce the logic of the article, I still hardly understand how to use it for every incoming request and even why it is useful for this.

How should I organize my code to create context (and what should it contain, generally) for every incoming request using the golang.org/x/net/context package? Could anybody give a little example and explain what is so useful and why so frequently used?

  • 写回答

2条回答 默认 最新

  • douchiwan1503 2015-02-13 18:38
    关注

    One of the most common needs for context passing is correlating outgoing requests to incoming requests. I have used this for a variety of purposes, for example:

    • I want error logs for my database component to include the full url from the http request it is a result of.
    • Incoming http requests contain a set of headers that I need to preserve and pass on to other http services I call downstream (maybe for tracking reasons).
    • I want to examine the incoming http request in some other component to do access control or user authentication or whatever. This could be at the http handler layer, or some other part of my application.

    Many languages and platforms have convenient/magical ways to get the current Http request. C# has HttpRequest.Current which is globally available (via thread local storage) to anyone who wants to know the context of the current http request. You can set arbitrary data on it to communicate various context data. Other platforms have similar facilities.

    Since go has no facilities for goroutine local storage, there is no way to store a global variable in the context of the current http request. Instead, it is idiomatic to initialize the context at the boundary of your system (an incoming request), and pass it as an argument to any downstream components that need access to that information.

    One super simple way to do this would be to make a context object with the current http request and pass that around:

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

    You can of course limit it to a more targeted set of data you need to pass around rather than the entire request.

    The other thing that the context package helps with (and I think that blog does an ok job of pointing out), is a common framework for timeouts or deadlines.

    Note that the context package does not enforce timeouts for you. It is up to the components receiving a context object to watch the Done channel and self-cancel their own http request or database call or calculation or whatever.

    edit - on timeouts

    It is extremely useful to be able to manage timeouts from the outside of a component. If I have a database module, I don't need to hardcode timeout values, just be able to handle a timeout triggered from the outside.

    One way I have done this is in a service that makes multiple db / service calls per incoming request. If the total time exceeds 1 second, I want to abort all outbound operations and return a partial or error result. Initializing the context with a timeout at the top level and passing it to all dependencies is a really easy way to manage this.

    It is not always pretty for the dependency to listen to the Done channel and abort it's work, but as the blog shows, it is not terribly painful either.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 使用C#,asp.net读取Excel文件并保存到Oracle数据库
  • ¥15 C# datagridview 单元格显示进度及值
  • ¥15 thinkphp6配合social login单点登录问题
  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配