[help] http.ListenAndServe with signal handler in select not exiting app

xuanbao · · 444 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Kind of my first proper go project where the task is to get some data over HTTP web call and produce it to Kafka.</p> <p><a href="https://gist.github.com/riteshn-niara/c8e0dd8f9b69b74b62cb67c73755005c" rel="nofollow">https://gist.github.com/riteshn-niara/c8e0dd8f9b69b74b62cb67c73755005c</a></p> <p>This was my first attempt and apart from everything else working (I am able to start the web server, listen to request, connect to Kafka), I am bit confused why my code does not exit on Ctrl+C and i have to do a hard kill.</p> <p>If i remove the select{} and just use the defer as shown in comment, the program exits.</p> <p>Any idea what I might be doing wrong?</p> <hr/>**评论:**<br/><br/>mwholt: <pre><p>You break from the <code>for</code> loop that has the <code>select</code> in it, but returning from that function only ends that goroutine. The main goroutine is still running.</p></pre>smartfinances: <pre><p>Hmm, I am still not clear. When Ctrl+C i clicke, I can see the text:</p> <p>log.Println(&#34;Producer closed&#34;)</p> <p>being logged. So this means, the ProducerLoop and the defer in it executed and returns.</p> <p>When I did an strace, I can still see the app being still blocked on the select(..) call so preseumably the ListenAndServe() is still running. Is this what you meant by the main goroutine? This means the signal is handled by the select but is then not propagated to the ListenAndServe() method?</p></pre>mwholt: <pre><blockquote> <p>Is this what you meant by the main goroutine? This means the signal is handled by the select but is then not propagated to the ListenAndServe() method?</p> </blockquote> <p>Yup. If you want the program to exit, you have to do that yourself because you captured the signal.</p></pre>smartfinances: <pre><p>Thanks. That makes sense now.</p> <p>Any idea whats the golang way to do this?</p></pre>mwholt: <pre><p>Call os.Exit to have the application exit.</p></pre>Redundancy_: <pre><p>Let&#39;s take a step back -</p> <p>Cancelling on an os Signal is an application concern that shouldn&#39;t be down at the level of your Kafka workers. You are far better off (imo) passing down a <a href="https://golang.org/pkg/context/#Context" rel="nofollow">https://golang.org/pkg/context/#Context</a> that you can cancel for whatever reason you want.</p> <p>If you use <a href="https://godoc.org/golang.org/x/sync/errgroup" rel="nofollow">https://godoc.org/golang.org/x/sync/errgroup</a>, you can easily catch errors from any one of your Kafka objects, cancel all of them, and wait on them all exiting. Similarly, you can put your http.ListenAndServe in an errgroup goroutine, but you&#39;ll need to explicitly stop it. You can handle that by having another goroutine listen for the context.Done, and to call <a href="https://golang.org/pkg/net/http/#Server.Shutdown" rel="nofollow">https://golang.org/pkg/net/http/#Server.Shutdown</a></p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

444 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传