-
Notifications
You must be signed in to change notification settings - Fork 419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Any plans to support Ruby 3 ractor as a back-end for most common constructs in the gem? #899
Comments
In principle I believe that many of these abstractions still have value in the Ruby 3 world. For the same reasons we have multiple data structures like map, array, stack, queue, etc. Abstractions solve problems. Ractor should be a much better foundation than threads, as I believe you are suggesting with your question. As far as concrete plans, I haven't worked in Ruby or on this gem in several years so this isn't something I plan to work on. Im 100% in favor of others giving that a try and I'd be happy to support those efforts in any way that I can. @pitr-ch is the maintainer now so any merges to this particular repo will need his input. I haven't spoken to him in a while so I have no idea what his plans are. |
Hi, I'll be grateful for any information you share back from your experiments. I am planning to look at it in more detail in the summer. |
This would be really useful, particularly with thread pools. Unfortunately, the current design of thread pools allows you to pass a new |
Upon further investigation, it seems that wrapping
Essentially |
Thanks a lot for the investigation. This is a pity, it was originally planned to have additional syntax to create isolated blocks as needed, exactly for these use cases. It appears it did not get in. If you raise this issue with Ruby please send me a link to the issue. |
Calling Example:
This also works without modification on Ruby 3.0.1 release, so it is not reliant on any ruby-head specific feature:
You might also be able to use |
@justinlynn Thanks very much for the additional information! That looks promising and it was part of the original design, the previous discussion made me worried that it was dropped. I'll be looking into this more over the summer or a prototype PR would be always welcomed! |
Awesome investigation! I don't believe I tried to |
Thanks very much for the kind words, @pitr-ch and @stouset. I'll see what I can come up with but I've been quite busy with work recently so I can't promise. Cheers :) Are there any implementations/constructs in particular we should focus on porting? Should we create a new backend in the same way that ruby and java backends are separated? |
Should this be marked as |
I think few abstractions of concurrent-ruby are actually compatible with Ractors (the programming model, which never allows one mutable object to be used by multiple Ractors), except thread pools and actors-like abstractions (if they have copy semantics) could probably run on top of Ractor with some limitations. Using abstractions using Ractors would always needs to be opt-in (cannot just replace the backend of existing abstractions) because it seems impossible to have fully-compatible behavior built on Ractor given the restrictions Ractors enforce (e.g., deep copy of the Proc and its captured locals, no way to e.g. copy an IO instance in, can't even access STDOUT/STDERR although $stdout/$stderr are fine, etc). Back to my first point, I think Concurrent::{Map,Array,Set,AtomicReference} all cannot reasonably work on Ractor, implementing them on Ractor would mean an extra Ractor per instance (heavy on footprint it's an extra OS thread, not so fast for communication due to copying) and would serialize all accesses to that data structure since everything would happen a single Ractor, and so they would no longer work concurrently/in parallel (on any Ruby implementation). Also the copying would mean having mutable objects in the data structure wouldn't work as before, as external updates wouldn't be reflected. |
Another challenge is a block/Proc captures r = Ractor.new { p Ractor.receive.call }
r << Ractor.make_shareable(-> { 2*3 }) gives:
r << Ractor.make_shareable(nil.instance_exec { -> { 2*3 } }) works but that I feel building abstractions on top of Ractor is very difficult because there are so many restrictions. It may be useful to develop new Ractor-specific abstractions (e.g. a Ractor pool or so). And if those are generic enough it may be useful to add them to this gem. Or maybe they better belong in another gem. In any case that's a different issue. |
Also Ractor is still experimental and if you want true parallelism in Ruby which works with existing gems/code, then Threads on TruffleRuby or JRuby is the way to go. |
I'm really curios if this is actually feasible and what are the plans if any regarding this direction.
Thank you for all the great work on this gem (and yes, I'll try to answer the question myself by forking and playing a bit with the repo).
The text was updated successfully, but these errors were encountered: