Open DougEverly opened 2 years ago
I think what's going on is that it's not the fact that it's empty causing it to hang, but more so there is no blocking operation that allows it to switch to another fiber. For example, in your working flow:
loop do
a part of the main fiber, send chan
a value, and sleep 1
causes execution to switch to first spawned fiberhey
sleep 1
causes execution to switch to second spawned fiberselect
, receives the sent value and prints true
, skipping chan1
since there is no value waiting
loop do
, there is no value waiting again on either channel, so the select
blocks, causing execution to switch back to the main fiberhey
again, which repeats all this ad infinitumOnce you introduce the else
block, the second iteration won't block execution, thus never allowing the main fiber to run which essentially traps the program in the infinite loop of the second spawned fiber.
In short, I'm fairly certain this is working by design.
EDIT: You can prove this by adding sleep 0
causes it to work, but something like puts "else"
does not, but does make it more clear what's going on.
In short, I'm fairly certain this is working by design.
Yes, I agree. Your else
branch short circuits the fiber in a tight loop. There is no escape 🧟
We're missing documentation on select
(https://github.com/crystal-lang/crystal-book/issues/208). There this could be mentioned as a possible trap.
The empty
else
block will hang all fibers and will not give a compile error.An empty
when
block works as expected.Example:
Works as expected:
Unexpectedly hangs all fibers, and without compiler error: