Closed morgoth closed 1 year ago
Hanging on swallowed error
Well, the error is not really "swallowed" or suppressed.
Inside an Async
block sleep
is handled by an Async::Scheduler#kernel_sleep
fiber scheduler method. The implementation for kernel_sleep
method looks like this:
Note it does not error if nil
is passed. Instead, it effectively waits indefinitely.
hmm, I thought I'm using sleep from Ruby standard lib, so this is unexpected. Also why having a different behaviour than in standard lib? What are other methods that are overwritten? Shouldn't this be documented somewhere?
I could be wrong, but I think this is not considered a bug. I'm sure you could find more "minor gotchas" like this with other blocking methods that delegate to fiber scheduler.
Fiber scheduler allows you to change the way how some ruby built-in methods work. Commonly, a user explicitly opts-in to use a fiber scheduler, so small differences from built-in methods are fine - user explicitly opted into that.
In the case of async
that's maybe less obvious, but you still ARE using a fiber scheduler, so it kinda is a user's choice.
Here are the docs: https://docs.ruby-lang.org/en/3.1/Fiber/SchedulerInterface.html
Thanks @bruno- this is an interesting compatibility issue.
Since sleep(nil)
is invalid in Ruby, maybe we could consider introducing this behaviour to make it consistent. Handling zero argument case rather than default argument = nil is less efficient in Pure Ruby than in C.
I think sleep()
and sleep(nil)
should be considered the same, but in CRuby it currently isn't. I don't have a solution. If you write this:
def sleep(time = nil)
if time
sleep_for_time(time)
else
sleep_forever
end
end
It's impossible to know if the time was nil because it was the default or the user provided nil. It's hard to replicate the CRuby interface.
It was accepted by Matz, so this will be fixed in Ruby 3.3: https://github.com/ruby/ruby/pull/7484
This simple code hangs:
so when I raise TypeError by hand it properly interrupts and report an error, but hangs on the
sleep nil
which standalone raises TypeError