Closed andrew-stripe closed 7 years ago
r? @evan-stripe I ran tests locally and they passed, didn't want to wait for Travis to assign for review since getting OS X workers on Travis can take an eternity.
cc @doy-stripe @asf-stripe @dougbarth-stripe since y'all provided suggestions for tracking this down.
There's some precedent for making this change
Note that this is also what the example in the Ruby docs suggests doing: (at http://ruby-doc.org/core-2.3.0/IO.html#method-c-select):
while 0 < string.bytesize
begin
written = io_like.write_nonblock(string)
rescue IO::WaitReadable
IO.select([io_like])
retry
rescue IO::WaitWritable
IO.select(nil, [io_like])
retry
end
string = string.byteslice(written..-1)
end
(They also rescue WaitReadable
to in case of SSL renegotiation, which we don't need to worry about here.)
I think I'm sufficiently convinced that the test failures over the weekend was either spurious or some sort of test runner issue, so LGTM
Yea, I've found the builds on this repo to be somewhat flaky :-/
Add a version bump to this PR as well.
We've had several reports of people running OS X getting an
EAGAINWaitWritable
error from Subprocess writing to stdin. Rebooting the machine seems to fix the issue. On a non-rebooted machine, I was able to verify that after writing 512 bytes to a new pipe, subsequent writes would throw an error even immediately afterselect
indicated that the fd is writable:I was also able to confirm that this diff fixes the observed issue and the Subprocess completes cleanly.
There's some precedent for making this change:
write
to return an error even ifselect
indicates writability:If the OS misbehaves and the process blocks forever, the invoking process will spinloop indefinitely. I think this is acceptable since it's already good practice to implement a timeout if you don't trust the child process not to block indefinitely.