<p>I recently refactored my Go project with net/context package,
and the code got so much easier to manage and more efficient.
So I would like to share with you all.</p>
<p>First, to understand how to use net/context, here are two articles:
<a href="https://blog.golang.org/context">https://blog.golang.org/context</a> / <a href="https://joeshaw.org/net-context-and-http-handler">https://joeshaw.org/net-context-and-http-handler</a></p>
<p>Second, nicolai86 has a great example project that I referred to:
<a href="https://github.com/nicolai86/dash-annotations">https://github.com/nicolai86/dash-annotations</a></p>
<p>And here's my code:
<a href="https://github.com/gyuho/learn/tree/master/doc/go_web_application#netcontext">https://github.com/gyuho/learn/tree/master/doc/go_web_application#netcontext</a>
/ <a href="https://github.com/gyuho/learn/tree/master/doc/go_web_application/app">https://github.com/gyuho/learn/tree/master/doc/go_web_application/app</a></p>
<p>Please give me some feedback if you have any.</p>
<p>Thanks all!</p>
<hr/>**评论:**<br/><br/>jlinkels: <pre><p>I don't understand how people transmit contexts across API boundaries. For example, if server A gets a request and decides the deadline should be one second, and the request depends on results from server B, how do you pass the constraint on to server B? Do you attempt to transmit cancellations across different servers?</p>
<p>It seems like context is only usable for request scoped stuff, ie on one server, but it would be most useful across network boundaries.</p></pre>gyuho: <pre><p>You are right. The documentation says context is for request-scoped values across API boundaries, but seems limited within the same process. I think it's a hard problem, once being tried with something netchan, or etcd.</p>
<p>If you need to communicate across servers, I would just use protobuf or gob packages.</p></pre>sdhillon: <pre><p>I'd actually look at GRPC. Although it's still in Beta right now. It has management of the context, and cancellation across multiple servers: <a href="http://www.grpc.io/docs/guides/concepts.html#rpc-termination">http://www.grpc.io/docs/guides/concepts.html#rpc-termination</a></p></pre>ItsNotMineISwear: <pre><p>Given that it uses a channel, I don't think it is possible. But you could have both the client and server take a Context and then do the plumbing yourself so that closing the Client's Done chan propogates to the server. Not easy though.</p></pre>barsonme: <pre><p>Cross-server communication with net/context doesn't seem terribly difficult provided each server has access to the required schemas.</p>
<p>It's kind of like JSON requests except the data is serialized down to a small stream of bytes instead of the (relatively) more bloated JSON.</p>
<blockquote>
<p>For example, if server A gets a request and decides the deadline should be one second...</p>
</blockquote>
<p>AFAICT, if A receives a request it doesn't set the deadline. The deadline is defined by the sender and receiver only has to act within the deadline.</p>
<p><a href="https://godoc.org/golang.org/x/net/context#WithDeadline" rel="nofollow">WithDeadline</a> states that</p>
<blockquote>
<p>If the parent's deadline is already earlier than d, WithDeadline(parent, d) is semantically equivalent to parent.</p>
</blockquote>
<p>meaning if server 1 sets a deadline of 5 minutes and sends the context to server 2 which then sets a deadline of 10 minutes and sends the context to server 3, the deadline is still 5 minutes and the only control server 3 has over the deadline is to shorten the rope.</p>
<blockquote>
<p>and the request depends on results from server B, how do you pass the constraint on to server B? Do you attempt to transmit cancellations across different servers?</p>
</blockquote>
<p>Since server A only receives the context, theoretically you'd alert server B of the constraints as well. That is, if server C kicks off a job to server A that requires server B to send it some results, you'd send the constraints to both servers so that B would know to bail if it exceeds the deadline (+/- a margin of error).</p></pre>jlinkels: <pre><p>I understand how the constraints work, I'm asking about a popular way to transmit the constraints and information contained in the context. It seems awkward to attach an encoding/gob onto your transports, but maybe that's the best way to do it.</p></pre>eikenberry: <pre><p>The deadline only matters to the A process. The B process gets called normally with no deadline passed. It either finishes with A's deadline or not and A handles that and B handles the cancelled request.</p>
<p>Trying to pass deadlines would lead to overly tight coupling and would make the app more complicated and fragile.</p>
<p>[edit: grammer]</p></pre>comrade_donkey: <pre><p>You don't need self-executing functions for scoping in Go as in, say, Javascript. Just use a block <code>{ ... }</code>.</p></pre>danhardman: <pre><p>This is actually really useful and I was thinking about how I would need to use context in my API project. This saves me having to use a 3rd party library.</p>
<p>I can't think of any obvious issues with getting this working with gorilla mux, can anyone else?</p></pre>daveddev: <pre><p>For net/context handler chaining with additional features, please consider <a href="https://github.com/codemodus/chain" rel="nofollow">https://github.com/codemodus/chain</a>. Features include appending of handlers to a chain, chain merging, chain context swapping, and standard http handler adapting. This is useful for following and combining the prescribed practices for handler nesting (middleware) and process/request context as found here <a href="https://blog.golang.org/context" rel="nofollow">https://blog.golang.org/context</a>.</p>
<p>Beyond the docs and tests, more complete example usage is shown in this ongoing project - <a href="https://github.com/codemodus/formlark" rel="nofollow">https://github.com/codemodus/formlark</a>.</p>
<p>Using nearly the same API as "chain"; If net/context is not needed, please consider - <a href="https://github.com/codemodus/catena" rel="nofollow">https://github.com/codemodus/catena</a></p></pre>IntellectualReserve: <pre><p>If you want people to use your repos, it would be more effective to provide a detailed TL:DR list of what use cases warrant it. "More features" and "" are not detailed enough to make me interested.</p></pre>daveddev: <pre><p>Thanks for the criticism. I've updated my post.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传