Timeout shards?

Can anyone please suggest a nice and flexible timeout shard?

While there are some listed here CrystalShards.org but they seem to be missing or broken.

For Channel based timeout I do see select when <> … when timeout(seconds) … end construct explained here Crystal 0.33.0 released! - The Crystal Programming Language but I think I cannot use it for ncurses shard that I installed (GitHub - SamualLB/ncurses: Ncurses bindings for Crystal).

While there is a timeout & no_delay method in the above said ncurses shard, I am not sure it is working for me when I used it.

My code sample is something like this,

spawn do
  loop do
    puts "Fiber 1 should print forever sleeping a millisecond in between work"
    sleep 1.milliseconds
  end
end

spawn do
  puts "Fiber 2 should see if there is input every 100 milliseconds, if not then should yield to Fiber 1"
  loop do
    NCurses::Window.new(10,10,0,0).get_char do |x| #=> getting blocked here till user enters input
    sleep 100.milliseconds
  end
end

sleep

If ncurses uses a C call for that, in single thread mode it will block the entire program. No shard you use will help you with that. The only option is to use multithreading, but that’s not finished yet.

@asterite Thanks for clarifying. Do you know when we would get the multi-threading support?
I see this post but not sure where should I check for this feature timeline.

No idea. You can use it right now but things might not work well.

Something separate we could do is to somehow say that a C call has to be done in a separate thread, regardless of multithreading support. That would allow these scenarios to work even in single-thread mode.

It would have to be a feature request.

@asterite Yes this would be nice stop gap solution and may find its own usefulness in some other scenarios as well. Thanks again for clarifying.
Because in some cases like mine I would need to access the same ncurses window object from 2 different spawns in crystal, I cannot separate it to different crystal programs. So, only other option for my usecase is to find why the underlying ncurses shard is not non-blocking when I set nodelay & timeout options provided in the shard (that would be a separate issue & out of this discussion). Having said that, if you know how these kind of issues is handled by on going projects using crystal then that may be of help to me and others who may face similar situations.

PS:
Just adding these for others who may see this discussion.

This can be useful if we are dealing with fiber channels but not for my use case where we are expecting from a C call.
Edited Typo

I think you could just try with preview_mt. In case you don’t use any fibers yet and you only add fibers for the C calls, this should be completely fine. If you use fibers, you have to make sure there’s no unguarded parallel access to any data structure. spawn(same_thread: true) is also an option for fibers that should run concurrently, but don’t need to be scheduled among different threads.

1 Like

Thanks @straight-shoota
After seeing your message, I searched for MT and found the following that I need to go through fully to understand. If there is any other detailed documentation on the usage/expectations with MT, do share please.
https://crystal-lang.org/2019/09/06/parallelism-in-crystal.html
https://forum.crystal-lang.org/t/mt-and-mutex/1297
https://forum.crystal-lang.org/t/multithreaded-crystal-initial-thoughts/1089
https://forum.crystal-lang.org/t/crystal-parallelism-and-kemal/1790

I cannot separate it to different crystal programs. So, only other option for my usecase is to find why the underlying ncurses shard is not non-blocking when I set nodelay & timeout options provided in the shard (that would be a separate issue & out of this discussion).