Concurrency problem with IRC client

blov · · 579 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hi, I&#39;m writing a small IRC client, which consists roughly of two parts: IRC code (connecting to server, reacting to various commands, ...) and UI code (input and widgets like a prompt, a text window with scrolling, ...). There are at least two goroutines running, namely the main thread, which listens to user input and forwards it to the UI, and one for the server connection/IRC code. These are not independent of each other, for example if you join a channel, a new widget should be created. This is what I&#39;ve come up with to let them communicate:</p> <ul> <li><p>Every widget has its own goroutine and methods are invoked by sending events over a channel (like Rob Pike&#39;s libcontrol, if I understood it correctly). For instance, when a new message from the server arrives, the IRC code sends it over a (go) channel to the widget, which then draws it. I&#39;m using termbox for the UI, which is not threadsafe, hence all termbox operations need to be locked with mutexes. Moreover termbox uses an expensive Flush function, which flushes changes to the screen, thus I want to batch draw calls before calling Flush. I&#39;ve tried this and it became excessively complicated.</p></li> <li><p>Let the IRC code run in the main thread. By that I mean instead of handling the messages coming from the server in the goroutine, just notify the main thread via a channel and select that work could be done. This is what I&#39;m doing at the moment.</p></li> <li><p>Use one UI mutex and one IRC mutex. Locks would be limited to the main loop when user input happens and whenever one part accesses or modifies the other. This could be wrapped in publish/update functions (observer pattern).</p></li> </ul> <p>Ideally a solution should scale to several IRC connections and keep IRC and UI code reasonably separate from each other.</p> <p>Have you run into a similar situation. What did/would you do? Thanks!</p> <hr/>**评论:**<br/><br/>Fwippy: <pre><p>I haven&#39;t done much UI work, but my gut says you should try a goroutine that just manages the UI. Widgets, user input, IRC comms, would all send updates over a channel to the UI layer. This would then be responsible for batching the draw calls, and no mutexes would be required. So your widgets responsibility would be &#34;process incoming messages; figure out draw updates, then put those in the queue.&#34;</p> <p>For batching, have you looked into a select statement with <code>time.After</code>?</p></pre>qcoh: <pre><p>This sounds alright, but updates go both ways. For example hitting enter should send the message to the server.</p> <p>I think what you describe is a more clean version of what I&#39;m doing now, with the same drawback of having lots of logic in the goroutine main loops. I&#39;ll give it a try.</p> <blockquote> <p>For batching, have you looked into a select statement with time.After?</p> </blockquote> <p>Excellent idea, thank you!</p></pre>ivosaurus: <pre><ul> <li>main thread <ul> <li>UI thread</li> <li>IRC Connection</li> <li>IRC Connection</li> </ul></li> </ul></pre>qcoh: <pre><p>I&#39;m not sure if I follow you. The IRC connections have lots of program logic which I want to keep separate from the rest to avoid spaghetti code.</p></pre>ivosaurus: <pre><blockquote> <p>The IRC connections have lots of program logic </p> </blockquote> <p>Yeah, separate that out. Make them just good at parsing and handling IRC messages, possibly IRC state.</p></pre>zxy_xyz: <pre><p>What lib for UI? if any.</p></pre>qcoh: <pre><p>My own wrapper for termbox. Specifically for this IRC client, thus incomplete, not very general, some intricate behaviour, etc. You can find it <a href="https://github.com/qcoh/mondrian" rel="nofollow">here</a>. Since it&#39;s not very good I suggest you look at <a href="https://github.com/gizak/termui" rel="nofollow">https://github.com/gizak/termui</a> or <a href="https://github.com/jroimartin/gocui" rel="nofollow">https://github.com/jroimartin/gocui</a>.</p></pre>

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

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