https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112021-03-09T00:42:31ZRuby Issue Tracking SystemRuby master - Feature #17679: Ractor incoming channel can consume unlimited resourceshttps://redmine.ruby-lang.org/issues/17679?journal_id=908022021-03-09T00:42:31Zhsbt (Hiroshi SHIBATA)hsbt@ruby-lang.org
<ul><li><strong>Tags</strong> set to <i>ractor</i></li><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>ko1 (Koichi Sasada)</i></li></ul> Ruby master - Feature #17679: Ractor incoming channel can consume unlimited resourceshttps://redmine.ruby-lang.org/issues/17679?journal_id=908062021-03-09T01:36:43Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul></ul><p>It's not clear to me that this should be implemented at the Ractor level.</p>
<p>Both suggested approaches can be handled in Ruby, for example using an intermediary Ractor...</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">DONE</span> <span class="o">=</span> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">freeze</span>
<span class="no">MIDDLEMAN</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">on_queue</span> <span class="o">=</span> <span class="mi">0</span>
<span class="kp">loop</span> <span class="k">do</span>
<span class="n">message</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">receive</span>
<span class="k">if</span> <span class="n">message</span> <span class="o">==</span> <span class="no">DONE</span>
<span class="n">on_queue</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="k">else</span>
<span class="k">if</span> <span class="p">(</span><span class="n">on_queue</span> <span class="o">></span> <span class="mi">32_000</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"Too many requests, skipping </span><span class="si">#{</span><span class="n">message</span><span class="si">}</span><span class="s2">"</span>
<span class="k">next</span>
<span class="k">end</span>
<span class="n">on_queue</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="no">DOER</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">DOER</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="kp">loop</span> <span class="k">do</span>
<span class="n">message</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">receive</span>
<span class="nb">sleep</span> <span class="mf">0.01</span>
<span class="nb">puts</span> <span class="s2">"Processed </span><span class="si">#{</span><span class="n">message</span><span class="si">}</span><span class="s2">"</span>
<span class="no">MIDDLEMAN</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="no">DONE</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">counter</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="kp">true</span>
<span class="n">counter</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="no">MIDDLEMAN</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="n">counter</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
<p>If/when a non-blocking <code>receive</code> will be available, the receiving ractor could also handle it's waiting queue internally</p> Ruby master - Feature #17679: Ractor incoming channel can consume unlimited resourceshttps://redmine.ruby-lang.org/issues/17679?journal_id=910992021-03-26T09:16:59Zivoanjo (Ivo Anjo)ivo.anjo@datadoghq.com
<ul></ul><p>That's a reasonable point, <a class="user active user-mention" href="https://redmine.ruby-lang.org/users/182">@marcandre (Marc-Andre Lafortune)</a>. I also did tried something similar at <a href="https://ivoanjo.me/blog/2021/02/14/ractor-experiments-safe-async/" class="external">https://ivoanjo.me/blog/2021/02/14/ractor-experiments-safe-async/</a> .</p>
<p>Our concern at Datadog (I'm a colleague of <a class="user active user-mention" href="https://redmine.ruby-lang.org/users/50839">@marcotc (Marco Costa)</a>) is that adding these middle layer threads/queues/ractors is error-prone, and this seems like something that every Ractor user may need, so it can probably be solved much cleaner by Ruby itself.</p>
<p>For instance, it really looks like during enqueing of messages in <a href="https://github.com/ruby/ruby/blob/9143d21b1bf2f16b1e847d569a588510726d8860/ractor.c#L408" class="external">https://github.com/ruby/ruby/blob/9143d21b1bf2f16b1e847d569a588510726d8860/ractor.c#L408</a> the sender already checks the size of the queue anyway, so having the option to back out of the queue was at a given size seems to be a couple of lines way.</p> Ruby master - Feature #17679: Ractor incoming channel can consume unlimited resourceshttps://redmine.ruby-lang.org/issues/17679?journal_id=982462022-06-30T10:44:18Zphigrofi (Philipp Großelfinger)philipp@pollunit.com
<ul></ul><p>I created a different issue, which would help to query to incoming queue size from outside of a ractor: <a href="https://bugs.ruby-lang.org/issues/18814" class="external">https://bugs.ruby-lang.org/issues/18814</a></p>
<p>Maybe this could help you.</p> Ruby master - Feature #17679: Ractor incoming channel can consume unlimited resourceshttps://redmine.ruby-lang.org/issues/17679?journal_id=982472022-06-30T10:49:20Zivoanjo (Ivo Anjo)ivo.anjo@datadoghq.com
<ul></ul><p>Thanks <a class="user active user-mention" href="https://redmine.ruby-lang.org/users/52350">@phigrofi (Philipp Großelfinger)</a> for the hint! Definitely looks like an interesting way out of this.</p> Ruby master - Feature #17679: Ractor incoming channel can consume unlimited resourceshttps://redmine.ruby-lang.org/issues/17679?journal_id=1043052023-08-24T21:13:50Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul><li><strong>Related to</strong> <i><a class="issue tracker-2 status-1 priority-4 priority-default" href="/issues/18814">Feature #18814</a>: Ractor: add method to query incoming message queue size </i> added</li></ul> Ruby master - Feature #17679: Ractor incoming channel can consume unlimited resourceshttps://redmine.ruby-lang.org/issues/17679?journal_id=1043072023-08-24T21:14:55Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul><li><strong>Tracker</strong> changed from <i>Bug</i> to <i>Feature</i></li><li><strong>ruby -v</strong> deleted (<del><i>ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux]</i></del>)</li><li><strong>Backport</strong> deleted (<del><i>2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN</i></del>)</li></ul>