https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112022-03-30T12:11:32ZRuby Issue Tracking SystemRuby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=970872022-03-30T12:11:32ZEregon (Benoit Daloze)
<ul><li><strong>Related to</strong> <i><a class="issue tracker-2 status-5 priority-4 priority-default closed" href="/issues/18566">Feature #18566</a>: Merge `io-wait` and `io-nonblock` gems into core IO</i> added</li></ul> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=971032022-03-31T01:10:26Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul></ul><p>I don't think this gem deserves a room into core. Are there any practical usages of it? Note that <code>IO#read_nonblock</code> is an unrelated method (works with or without of this).</p>
<p>Also, are we going to add tons of trivial methods into core just because they are small? I guess we need good reasons for each of them to exist.</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=971092022-03-31T09:47:08ZEregon (Benoit Daloze)
<ul></ul><blockquote>
<p>Are there any practical usages of it?</p>
</blockquote>
<p>I already mentioned them:</p>
<blockquote>
<p>This is needed when using a Fiber scheduler but also other cases such as <a href="https://bugs.ruby-lang.org/issues/18630#note-9" class="external">https://bugs.ruby-lang.org/issues/18630#note-9</a>.</p>
</blockquote>
<p>I believe one of the main use cases is to check whether an IO is in nonblocking mode (IO#nonblock?), and to set or ensure a specific IO instance is in nonblocking mode (IO#nonblock=, IO#nonblock {}).<br>
This is <em>essential</em> for the Fiber scheduler and <a href="https://bugs.ruby-lang.org/issues/18630" class="external">https://bugs.ruby-lang.org/issues/18630</a>, they mostly don't work on IOs for which nonblock?=false.<br>
However, such checking might be temporary or helpful for debugging but not necessarily kept in the code.<br>
For instance <a href="https://github.com/ruby/ruby/blob/master/test/fiber/scheduler.rb" class="external">https://github.com/ruby/ruby/blob/master/test/fiber/scheduler.rb</a> requires it but does not seem to use the <code>IO#nonblock*</code> methods, but most likely they were used for debugging and finding out if everything is as expected.</p>
<p>Having <code>*_nonblock</code> methods but no way to observe whether it's in nonblocking mode in core feels like a missing piece.<br>
We have <code>IO#autoclose?</code>, <code>IO#binmode?</code>, <code>IO#close_on_exec?</code> yet without <code>require 'io/nonblock'</code> we have no way to check if an IO is in nonblocking mode, even though we have an indirect way to set it (IO#*_nonblock).</p>
<p>You can also see it's used in several places with <a href="https://github.com/search?q=require+io%2Fnonblock&type=Code" class="external">https://github.com/search?q=require+io%2Fnonblock&type=Code</a> : 40000+ results</p>
<blockquote>
<p>Also, are we going to add tons of trivial methods into core just because they are small? I guess we need good reasons for each of them to exist.</p>
</blockquote>
<p>These methods already "exist", whether they are in core or not.<br>
I don't understand why it makes such a big difference whether it's behind <code>require 'io/nonblock'</code> or not, these methods have always (or since so many years) been shipped with Ruby.</p>
<p>But if core devs feel strongly about it, I would also be fine for these methods to be in stdlib (as before the gem), and no longer a gem.<br>
What is the advantage of having this in a gem, separate repository? I see none.</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=971112022-03-31T10:44:26Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul></ul><p>Eregon (Benoit Daloze) wrote in <a href="#note-3">#note-3</a>:</p>
<blockquote>
<blockquote>
<p>Are there any practical usages of it?</p>
</blockquote>
<p>I already mentioned them:</p>
<blockquote>
<p>This is needed when using a Fiber scheduler but also other cases such as <a href="https://bugs.ruby-lang.org/issues/18630#note-9" class="external">https://bugs.ruby-lang.org/issues/18630#note-9</a>.</p>
</blockquote>
</blockquote>
<p>And I see no use of the methods in question in the URL above. Maybe I’m missing something.</p>
<blockquote>
<p>I believe one of the main use cases is to check whether an IO is in nonblocking mode (IO#nonblock?), and to set or ensure a specific IO instance is in nonblocking mode (IO#nonblock=, IO#nonblock {}).<br>
This is <em>essential</em> for the Fiber scheduler and <a href="https://bugs.ruby-lang.org/issues/18630" class="external">https://bugs.ruby-lang.org/issues/18630</a>, they mostly don't work on IOs for which nonblock?=false.<br>
However, such checking might be temporary or helpful for debugging but not necessarily kept in the code.<br>
For instance <a href="https://github.com/ruby/ruby/blob/master/test/fiber/scheduler.rb" class="external">https://github.com/ruby/ruby/blob/master/test/fiber/scheduler.rb</a> requires it but does not seem to use the <code>IO#nonblock*</code> methods, but most likely they were used for debugging and finding out if everything is as expected.</p>
</blockquote>
<p>OK I can understand it’s handy for debugging purposes. That, however, sounds more like it’s not the feature needed for everyone.</p>
<blockquote>
<p>Having <code>*_nonblock</code> methods but no way to observe whether it's in nonblocking mode in core feels like a missing piece.<br>
We have <code>IO#autoclose?</code>, <code>IO#binmode?</code>, <code>IO#close_on_exec?</code> yet without <code>require 'io/nonblock'</code> we have no way to check if an IO is in nonblocking mode, even though we have an indirect way to set it (IO#*_nonblock).</p>
<p>You can also see it's used in several places with <a href="https://github.com/search?q=require+io%2Fnonblock&type=Code" class="external">https://github.com/search?q=require+io%2Fnonblock&type=Code</a>: 40000+ results</p>
</blockquote>
<p>Maybe I’m not doing the right thing but I have hard time finding out the actual use of the aforementioned feature in the URL, except testing codes. Do you want this for tests?</p>
<blockquote>
<blockquote>
<p>Also, are we going to add tons of trivial methods into core just because they are small? I guess we need good reasons for each of them to exist.</p>
</blockquote>
<p>These methods already "exist", whether they are in core or not.<br>
I don't understand why it makes such a big difference whether it's behind <code>require 'io/nonblock'</code> or not, these methods have always (or since so many years) been shipped with Ruby.</p>
</blockquote>
<p>We want smaller core because of vulnerabilities. A separate gem can have a separate CVE, separate release, and administrators can avoid replacing everything only because a tiny fraction of our code has some issue. This is better than having security releases every time.</p>
<blockquote>
<p>But if core devs feel strongly about it, I would also be fine for these methods to be in stdlib (as before the gem), and no longer a gem.<br>
What is the advantage of having this in a gem, separate repository? I see none.</p>
</blockquote>
<p>I see a big one.</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=971132022-03-31T11:22:36ZEregon (Benoit Daloze)
<ul></ul><p>Sorry, it seems Redmine/I messed up the link by including the <code>:</code> in it.<br>
This should work: <a href="https://github.com/search?q=require+io%2Fnonblock&type=Code" class="external">https://github.com/search?q=require+io%2Fnonblock&type=Code</a><br>
So that's ~40000 usages of `require io/nonblock' as far as I can see.<br>
GitHub search isn't great though, so there is likely a lot of duplicate results (due vendored code, etc), and no easy way to search for method calls specifically.</p>
<p>This (or variants) might be more helpful, it uses the new GitHub search: <a href="https://cs.github.com/?scopeName=All+repos&scope=&q=.nonblock%3F+language%3ARuby" class="external">https://cs.github.com/?scopeName=All+repos&scope=&q=.nonblock%3F+language%3ARuby</a></p>
<blockquote>
<p>OK I can understand it’s handy for debugging purposes. That, however, sounds more like it’s not the feature needed for everyone.</p>
</blockquote>
<p>I agree it's not needed by everyone. OTOH that can be said for so many methods in core.</p>
<p>IMHO, these 3 methods belong to IO core, implementation-wise and API-wise (ways to set it but not query it, annoying for debugging).<br>
They might not be used a lot, but I don't think this is so important for core, there are plenty of methods in core not used much (e.g., most of <code>Process</code> methods).<br>
I think stability and good naming are more important for core, and those methods are good at that.</p>
<blockquote>
<p>We want smaller core because of vulnerabilities. A separate gem can have a separate CVE, separate release, and administrators can avoid replacing everything only because a tiny fraction of our code has some issue. This is better than having security releases every time.</p>
</blockquote>
<p>Yes, but these 3 methods are clearly insignificant for vulnerabilities. Is that not obvious?<br>
<a href="https://github.com/ruby/io-nonblock/blob/e20578b24405d225e6383d6c5ebfb7ffefac646b/ext/io/nonblock/nonblock.c" class="external">https://github.com/ruby/io-nonblock/blob/e20578b24405d225e6383d6c5ebfb7ffefac646b/ext/io/nonblock/nonblock.c</a> is 97 SLOC of C code, if it was written in Ruby it'd probably be just 10 lines (e.g., using <code>IO#fcntl</code>).<br>
It's tiny, it's extremely unlikely to have vulnerabilities, and it's never had a vulnerability in 10+ years AFAIK.<br>
In fact, the vast majority of code in that repo (1257 SLOC according to <code>cloc .</code>) is all boilerplate that wouldn't be there if this was in core.</p>
<p>And if those methods were written in Ruby (e.g., using <code>IO#fcntl</code>), it'd probably be impossible to have a vulnerability in these 3 methods, so maybe that's a good reason to rewrite them using Ruby code.</p>
<p>So I understand the separate security release argument, but it seems clear there is a limit at which it's not worth the overhead, and io-nonblock seems way below that limit (in term of size and likeliness of vulnerabilities).<br>
(joke: otherwise let's make a gem for every core method?)</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=971162022-03-31T12:00:09Zioquatix (Samuel Williams)samuel@oriontransfer.net
<ul></ul><p>I support this change. In fact 90% of the code already exists in CRuby, it's just a matter of exposing it.</p>
<ul>
<li>I don't see any practical security advantage of this being a gem.</li>
<li>I see an advantage of reducing code duplication by moving this into core.</li>
<li>There are several methods like <code>read</code> and <code>write</code> which behave differently with <code>nonblock=true</code>. It doesn't make sense for a core semantic trait to be in a gem.</li>
</ul> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973052022-04-19T04:26:25Zko1 (Koichi Sasada)
<ul></ul><p>-1 because I think the name <code>IO#nonblock =</code> makes me <code>IO#read</code> (or other methods) becomes nonblocking.</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973092022-04-19T07:07:07Zko1 (Koichi Sasada)
<ul></ul><blockquote>
<p>There are several methods like read and write which behave differently with nonblock=true. It doesn't make sense for a core semantic trait to be in a gem.</p>
</blockquote>
<p>Could you list the difference?</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973102022-04-19T08:15:17Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul></ul><p>Can you explain what you expect <code>IO#nonblock=</code> to do?</p>
<p><code>IO#nonblock=</code> is a low-level API to set <code>O_NONBLOCK</code> to the internal file descriptor of an IO. As far as I know, this was introduced in the Ruby 1.8 era to make IO operations (like <code>IO#read</code>) non-blocking.</p>
<pre><code># Ruby 1.8
$stdin.nonblock = true
$stdin.read #=> Errno::EAGAIN
</code></pre>
<p>Note that <code>IO#read</code> was a (relatively) simple wrapper for read(2) system call in the era. (More precisely, a wrapper for fread(3).)</p>
<p>However, since Ruby 1.9, <code>IO#read</code> is not a simple wrapper. It uses select(2) system call to wait until it is ready to read, and then call read(2) syscall. Therefore, <code>O_NONBLOCK</code> flag does not change the behavior of <code>IO#read</code>, AFAIK (let me know if I am wrong). It always works as a blocking operation, even if <code>IO#nonblock=</code> is set as true.</p>
<pre><code># Ruby 1.9
$stdin.nonblock = true
$stdin.read #=> wait and read
</code></pre>
<p>So, I think that <code>IO#nonblock=</code> does not work as you expect. If you want a non-blocking read, you have no choice but to use <code>IO#read_nonblock</code>.</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973142022-04-19T11:13:21ZEregon (Benoit Daloze)
<ul></ul><p><code>IO#read</code> behaves <em>externally</em>/for the caller the same, i.e., it always "reads N bytes and block until it gets them (or EOF/error)".<br>
But internally <code>O_NONBLOCK</code> does affect <code>IO#read</code>, and this is observable for instance with a Fiber scheduler.<br>
If <code>io.nonblock = true</code>, then <code>io.read</code> will call the Fiber scheduler if the read(2) syscall returns EAGAIN.<br>
The Fiber scheduler is then able to schedule another Fiber, instead of waiting/blocking, which improves CPU utilization and IO concurrency.</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973222022-04-20T01:27:46Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul></ul><p>Eregon (Benoit Daloze) wrote in <a href="#note-10">#note-10</a>:</p>
<blockquote>
<p>this is observable for instance with a Fiber scheduler.</p>
</blockquote>
<p>Okay, can you show a self-contained program that demonstrates it? Is there another situation than a Fiber scheduler where <code>IO#nonblock=</code> is important?</p>
<p>A Fiber scheduler requires <code>nonblock = true</code> but not <code>nonblock = false</code>, right? If so, I think we may set O_NONBLOCK to all file descriptors by default. There is circumstantial evidence that this flag is not important to the interpreter itself (except a Fiber scheduler): when<code>IO#read_nonblock</code> is called, O_NONBLOCK is implicitly set, and never reset.</p>
<pre><code>require "io/nonblock"
p $stdin.nonblock? #=> false
begin
p $stdin.read_nonblock(1)
rescue IO::WaitReadable
end
p $stdin.nonblock? #=> true
</code></pre> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973372022-04-20T10:48:23ZEregon (Benoit Daloze)
<ul></ul><p>mame (Yusuke Endoh) wrote in <a href="#note-11">#note-11</a>:</p>
<blockquote>
<p>Okay, can you show a self-contained program that demonstrates it?</p>
</blockquote>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'io/nonblock'</span>
<span class="k">class</span> <span class="nc">Scheduler</span>
<span class="k">def</span> <span class="nf">block</span>
<span class="k">raise</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">unblock</span>
<span class="k">raise</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">kernel_sleep</span>
<span class="k">raise</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">io_wait</span><span class="p">(</span><span class="o">*</span><span class="p">)</span>
<span class="k">raise</span> <span class="s2">"io_wait called (expected)"</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">fiber</span><span class="p">(</span><span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="no">Fiber</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="o">&</span><span class="n">block</span><span class="p">).</span><span class="nf">resume</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Fiber</span><span class="p">.</span><span class="nf">set_scheduler</span> <span class="no">Scheduler</span><span class="p">.</span><span class="nf">new</span>
<span class="vg">$stdin</span><span class="p">.</span><span class="nf">nonblock</span> <span class="o">=</span> <span class="kp">true</span> <span class="c1"># needed to use scheduler for this IO</span>
<span class="no">Fiber</span><span class="p">.</span><span class="nf">schedule</span> <span class="k">do</span>
<span class="nb">print</span> <span class="s2">"> "</span>
<span class="nb">p</span> <span class="vg">$stdin</span><span class="p">.</span><span class="nf">gets</span>
<span class="k">end</span>
</code></pre>
<blockquote>
<p>Is there another situation than a Fiber scheduler where IO#nonblock= is important?</p>
</blockquote>
<p>Maybe not for <code>IO#nonblock=</code>. I think <code>IO#nonblock?</code> is useful for several cases, and notably to find out if a fd is nonblocking, which e.g., matters when it's passed to a C extension.<br>
So it's an helpful method for debugging.</p>
<blockquote>
<p>I think we may set O_NONBLOCK to all file descriptors by default.</p>
</blockquote>
<p>IIRC there were issues with that, notably when <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/724">@normalperson (Eric Wong)</a> tried it a while ago. <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/3344">@ioquatix (Samuel Williams)</a> might know more.<br>
stdstreams/File seem nonblock?=false currently, and socket/pipe seem nonblock?=true currently.</p>
<p>Also, maybe O_NONBLOCK by default is actually slower for IO (without a Fiber scheduler)? It will typically cause more syscalls, isn't it?</p>
<blockquote>
<p>There is circumstantial evidence that this flag is not important to the interpreter itself (except a Fiber scheduler): when<code>IO#read_nonblock</code> is called, O_NONBLOCK is implicitly set, and never reset.</p>
</blockquote>
<p>Yes, it does not matter for most methods, hence I don't see why it's a "problem" to include it into core.<br>
AFAIK Ruby developers see stdlib/default gems as "code shipped with Ruby and should work well", and so have no reason to think that because <code>IO#nonblock*</code> is behind <code>require 'io/nonblock'</code> it should not be used.<br>
My opinion is there is no problem if people use <code>IO#nonblock*</code>.<br>
And there is also no problem if it is not used often (the case for many other core methods).</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973402022-04-20T19:12:58Znormalperson (Eric Wong)normalperson@yhbt.net
<ul></ul><p>"shyouhei (Shyouhei Urabe)" <a href="mailto:noreply@ruby-lang.org" class="email">noreply@ruby-lang.org</a> wrote:</p>
<blockquote>
<p>I don't think this gem deserves a room into core. Are there any practical usages of it?</p>
</blockquote>
<p>The functionality is already there; and it should be useful to check<br>
if writing code that needs to be compatible between old/new Ruby<br>
versions with different nonblock defaults.</p>
<blockquote>
<p>Also, are we going to add tons of trivial methods into core just because they are small? I guess we need good reasons for each of them to exist.</p>
</blockquote>
<p>Having many trivial .so is a waste of memory if they're loaded anyways in<br>
common programs. See <a href="/issues/18566">[ruby-core:107493]</a> and<br>
<a href="https://udrepper.livejournal.com/8790.html" class="external">https://udrepper.livejournal.com/8790.html</a></p>
<p>(I also use <code>etc' and </code>socket' ext in all my scripts, anyways)</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973412022-04-20T19:22:22Znormalperson (Eric Wong)normalperson@yhbt.net
<ul></ul><p>"Eregon (Benoit Daloze)" <a href="mailto:noreply@ruby-lang.org" class="email">noreply@ruby-lang.org</a> wrote:</p>
<blockquote>
<p>Issue <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Merge `io-nonblock` gems into core (Open)" href="https://bugs.ruby-lang.org/issues/18668">#18668</a> has been updated by Eregon (Benoit Daloze).</p>
<p>mame (Yusuke Endoh) wrote in <a href="#note-11">#note-11</a>:</p>
<blockquote>
<p>I think we may set O_NONBLOCK to all file descriptors by default.</p>
</blockquote>
</blockquote>
<blockquote>
<p>IIRC there were issues with that, notably when <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/724">@normalperson (Eric Wong)</a><br>
tried it a while ago. <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/3344">@ioquatix (Samuel Williams)</a> might know more.<br>
stdstreams/File seem nonblock?=false currently, and<br>
socket/pipe seem nonblock?=true currently.</p>
</blockquote>
<p>nonblock=true as default is still risky to me. I tried it years<br>
ago but the compatibility problems w.r.t. FD sharing (send_io,<br>
exec) to non-Ruby programs put me off. AFAIK there were also<br>
problems on the Windows side and I don't touch proprietary.</p>
<blockquote>
<p>Also, maybe O_NONBLOCK by default is actually slower for IO<br>
(without a Fiber scheduler)? It will typically cause more<br>
syscalls, isn't it?</p>
</blockquote>
<p>Yes, nonblock is slightly slower in terms of raw throughput for<br>
a single endpoint (which the rare case). Nonblock makes sense<br>
for the common case of multiple connections or the normal<br>
Internet case when you have latency and bandwidth limitations.</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973462022-04-21T05:24:23Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p>As <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/18">@mame (Yusuke Endoh)</a> described in <a href="#note-9">#note-9</a>, the design of io-nonblock is misleading. I'd rather like to make the gem deprecate.</p>
<p>Matz.</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973622022-04-21T09:17:18ZEregon (Benoit Daloze)
<ul></ul><p>I don't think the current design of io/nonblock is misleading. I would think the majority of people knowing about its existence know what it does. There is probably some bias here from people who knew about its 1.8 behavior, and that behavior was clearly broken as it would change the high-level semantics incorrectly of many other methods. So now we have the correct sensible semantics for those methods, IMHO no reason to deprecate.</p>
<p>Also we cannot deprecate it since the Fiber scheduler needs it, as I showed above.<br>
And as <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/724">@normalperson (Eric Wong)</a> said, if one wants to use the Fiber scheduler and doesn't know the exact Ruby version, they need IO#nonblock= + IO#nonblock? to ensure the fd is O_NONBLOCK and so the Fiber scheduler is used.<br>
Or simply if they don't know the exact kind of fd or don't want to rely on the changing defaults for IO instances.</p>
<p><a href="https://bugs.ruby-lang.org/issues/18630" class="external">https://bugs.ruby-lang.org/issues/18630</a> also needs io/nonblock, because that only applies to IO#nonblock? = true IO instances. And it has no effect on IO#nonblock? = false IO instances.</p>
<p>It seems clear core devs don't want it in core.<br>
How about stdlib then?<br>
A gem is clear overkill for this, and adding non-trivial overhead for every Ruby implementation.</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973642022-04-21T09:23:57Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>TIL, <code>IO#nonblock?</code> doesn't work on Windows.<br>
So I'm positive for the deprecation now.</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973662022-04-21T09:43:58ZEregon (Benoit Daloze)
<ul></ul><p>nobu (Nobuyoshi Nakada) wrote in <a href="#note-17">#note-17</a>:</p>
<blockquote>
<p>TIL, <code>IO#nonblock?</code> doesn't work on Windows.<br>
So I'm positive for the deprecation now.</p>
</blockquote>
<p>So let's also deprecate half the methods of <code>Process</code> which don't work on Windows either?<br>
I don't understand the argument.</p>
<p>My understanding is Windows doesn't support non-blocking for some file descriptors, hence of course IO#nonblock= should raise and <code>IO#nonblock?</code> should be false for those fds which can't be non-blocking on Windows.<br>
Or is there an unexpected error there?</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973682022-04-21T09:52:04ZEregon (Benoit Daloze)
<ul></ul><p><a class="user active user-mention" href="https://bugs.ruby-lang.org/users/17">@ko1 (Koichi Sasada)</a> showed us the output on Windows:</p>
<pre><code>require 'io/nonblock'
require 'socket'
# p STDOUT.nonblock?
p s = Socket.tcp('atdot.net', 80)
p s.nonblock = true
p s.nonblock? #=> `nonblock?': nonblock?() function is unimplemented on this machine (NotImplementedError)
</code></pre>
<p>We should fix IO#nonblock? to just be false on Windows.<br>
And IO#nonblock= should raise on Windows, either always or when passed true.</p>
<p>BTW, several CRuby tests check if nonblock?, and they do it via <code>IO.method_defined?("nonblock=")</code> most likely to workaround that bug.</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=973692022-04-21T10:02:28ZEregon (Benoit Daloze)
<ul></ul><p>Also I don't see why we need so much investigation into the details of io/nonblock and io/wait.<br>
Those were always stdlib, and they became default gems (with no discussion AFAIK).<br>
Now I'd like both of them to be back to stdlib, as they always were, and no longer gems.<br>
Because those 2 gems here are significant overhead for all Ruby implementations (e.g. have to support each Ruby implementation in the gem, while this code just makes more sense in each Ruby implementation's repo).</p>
<p>I give up on trying to make them core, because core devs seem to feel strongly against it despite many arguments. And I personally don't care too much between core or stdlib. An extra <code>require</code> is no big deal, an extra gem is IMHO.</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=984432022-07-23T02:19:02Zianks (Ian Ker-Seymer)
<ul></ul><p>IMO, we really do need to support this use case. Even if it were just fir testing purposes, it would <em>still</em> be worthwhile if it makes developing non-blocking gems easier.</p>
<p>Ruby should move towards better async support, not away from it. So it makes sense to remove extra friction where possible.</p> Ruby master - Feature #18668: Merge `io-nonblock` gems into corehttps://bugs.ruby-lang.org/issues/18668?journal_id=984482022-07-25T00:53:26Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul></ul><p>ianks (Ian Ker-Seymer) wrote in <a href="#note-21">#note-21</a>:</p>
<blockquote>
<p>IMO, we really do need to support this use case. Even if it were just fir testing purposes, it would <em>still</em> be worthwhile if it makes developing non-blocking gems easier.</p>
</blockquote>
<p>What precisely is "this use case" you mean? <code>io.nonblock = true</code> doesn't prevent things from blocking.</p>