But for users come from ruby, it still not easy to porting exists code into Fiber + Channel, there is still no a detailed document for how to do this, some examples in that PR is only touch the most simple user case.
For me, a user use Crystal for half years, still don’t know how to porting following code to Crystal, showing real-life use cases is often not as easy as comments in the PR.
Basically, this is a example read non-blocked from several ios, for differnt io, we may need handle differently, with a timeout settings.
Thread.new do
timeout = 30
loop do
# try to read from io1 and io_list (io_list is a array)
io = IO.select([io1] + io_list, nil, nil, timeout)
run_common_logic
if io # if no timeout
io.first.each do |reader|
if reader == io1
# logic if select on io1
read_from_io1
next
end
# logic if select on the elements of io_list (io_list may be empty)
read_from_elements_of_io_list
end
end
end
end
For above code, there is some concerns need to mention:
the io_list will changes when running, that is why in the above code, io_list is in a loop, we have to handle it when porting.
we have to handle the timeout in IO.select(io_list, nil, nil, timeout)
pay attention to there is a if io condition and next, This may be a complicated place.
Any idea? if this code can porting to Crystal correctly, it will be a perfect example for original PR.
Crystal uses libevent for evented I/O, so it’s already non-blocking, and it can eliminate the need for select in some cases. In other cases, I would recommend spawning a reader fiber and a timeout fiber, then having a common Channel in which the fastest (reader or timeout) fiber sends a message, e.g. the timeout fiber sends a Nil, or the reader fiber sends a String.
I figure you might get more responses if you described the behaviour you’re looking to implement instead of just pasting some code that implements this in Ruby. The code example is decently complex and hard to reason about without context. You’re forcing anyone willing to help you to dig into this code and try to understand what you even want before they can start helping you with doing this in Crystal.
If you explain your problem in prose, that’s much easier. Existing code can certainly be a helpful addition, but as sole source of knowledge, it’s quite a hurdle.
Yes, probably people confusing by the context, thought the key is not regarding tightly the context, I just want to learn the way to turn above IO.select logic into Crystal, maybe following pseudo-code is better?
Thread.new do
timeout = 30
loop do
# try to read from io1 and io_list (io_list is a array)
io = IO.select([io1] + io_list, nil, nil, timeout)
run_common_logic
if io # if no timeout
io.first.each do |reader|
if reader == io1
# logic if select on io1
read_from_io1
next
end
# logic if select on the elements of io_list (io_list may be empty)
read_from_elements_of_io_list
end
end
end
end