Ractor: a proposal for new concurrent abstraction without thread-safety issues#3365
Merged
Conversation
d02410a to
847d281
Compare
benoittgt
reviewed
Aug 1, 2020
d04762d to
602f56e
Compare
Contributor
Author
|
@benoittgt I'll squash most of commit, is it okay? (your commit doesn't appear in ruby repo). |
Contributor
|
@ko1 No problem! ;) |
2d946c8 to
7194182
Compare
This commit introduces Ractor mechanism to run Ruby program in parallel. See doc/ractor.md for more details about Ractor. See ticket [Feature ruby#17100] to see the implementation details and discussions. [Feature ruby#17100] This commit does not complete the implementation. You can find many bugs on using Ractor. Also the specification will be changed so that this feature is experimental. You will see a warning when you make the first Ractor with `Ractor.new`. I hope this feature can help programmers from thread-safety issues.
This implementation has memory corruption errors so and it causes BUG on rare occasions. This commit skips suspect tests on Github actions Compiler tests.
okeeblow
added a commit
to okeeblow/ox
that referenced
this pull request
Jul 26, 2021
…ax` example. For ohler55#277 I've been experimenting with `Ractor`s since upgrading to Ruby 3.0 for ohler55#275 but quickly ran into `Ractor::UnsafeError` when trying to call `Ox::sax_parse` in anything except the main `Ractor`. Per Ruby's `Ractor` C extension documentation (link below): "By default, all C extensions are recognized as `Ractor`-unsafe. If C extension becomes `Ractor`-safe, the extension should call `rb_ext_ractor_safe(true)` at the `Init_` function and all defined method marked as `Ractor`-safe. `Ractor`-unsafe C-methods only been called from main-ractor. If non-main ractor calls it, then `Ractor::UnsafeError` is raised." I don't like to open seemingly-large feature requests like this without making some attempt at it myself first, and luckily it seems like `Ox::sax_parse` Just Works™ since I marked it `Ractor`-safe, even with the `class_cache`. Confirming this safety, making any remaining changes to `Ox::Sax`, and expanding this to the non-`Sax` parts of `Ox` are all unfortunately out of my depth as a n00b C coder, so I would appreciate if you could take this over if it interests you. I am happy with just `Sax` support since I have no current need for marshalling, but I imagine other `Ox` users wouldn't be satisfied if stratified. In this commit: - Enable `rb_ext_ractor_safe` preprocessor macro via `have_func` in `extconf.rb`. - Mark `Init_Ox` and `ox_sax_parse` as `Ractor` -safe. - Add a new `Ractor`-based `Ox::Sax` example exercising both parallel and serial `Ox::Sax` handler `Ractor`s to parse data from `shared-mime-info` XML files many users likely already have on their systems. Official `Ractor` info: - "Ractor: a proposal for a new concurrent abstraction without thread-safety issues": https://bugs.ruby-lang.org/issues/17100 (ruby/ruby#3365) - Ruby's official `Ractor` documentation: https://docs.ruby-lang.org/en/master/doc/ractor_md.html - "A way to mark C extensions as thread-safe, Ractor-safe, or unsafe": https://bugs.ruby-lang.org/issues/17307 (ruby/ruby#3824) - Ruby's C Extension `Ractor` documention covering `rb_ext_ractor_safe`: https://docs.ruby-lang.org/en/master/doc/extension_rdoc.html#label-Appendix+F.+Ractor+support - A `Ractor` C Extension from the creator of `Ractor` that might serve as a useful example: https://github.com/ko1/ractor-tvar Blogs: - "Ractors: Multi-Core Parallel Processing Comes to Ruby 3": https://www.ruby3.dev/ruby-3-fundamentals/2021/01/27/ractors-multi-core-parallel-processing-in-ruby-3/ - "Ruby Ractor Experiments: Safe async communication" :https://ivoanjo.me/blog/2021/02/14/ractor-experiments-safe-async/ - "Playing with Ruby Ractors": https://billy-ruffian.co.uk/playing-with-ruby-ractors/ - "How Fast are Ractors?": https://www.fastruby.io/blog/ruby/performance/how-fast-are-ractors.html (https://github.com/noahgibbs/ractor_basic_benchmarks/tree/main/benchmarks) Before this change: ``` [okeeblow@emi#CHECKING-YOU-OUT] time ./bin/checking-you-out ~/224031-dot-jpg Received /home/okeeblow/.local/share/mime/packages/user-extension-rsrc.xml /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival/mr_mime.rb:375:in `sax_parse': ractor unsafe method called from not main ractor (Ractor::UnsafeError) from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival/mr_mime.rb:375:in `block in open' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival/mr_mime.rb:331:in `open' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival/mr_mime.rb:331:in `open' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:24:in `block (2 levels) in remember_me' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:19:in `loop' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:19:in `block in remember_me' <internal:ractor>:583:in `send': The incoming-port is already closed (Ractor::ClosedError) from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:86:in `block in extended' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:63:in `each' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:63:in `each_with_object' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:63:in `extended' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/inner_spirit.rb:216:in `extend' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/inner_spirit.rb:216:in `<top (required)>' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out.rb:10:in `require_relative' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out.rb:10:in `<top (required)>' from ./bin/checking-you-out:3:in `require_relative' from ./bin/checking-you-out:3:in `<main>' ./bin/checking-you-out ~/224031-dot-jpg 0.12s user 0.05s system 100% cpu 0.168 total ``` My new `Ox::Sax` Ractor example script's usage: ``` [okeeblow@emi#ox] ./examples/sax_ractor.rb Please provide the path to a `shared-mime-info` XML package and some media-type query arguments (e.g. 'image/jpeg') ``` ``` [okeeblow@emi#ox] ./examples/sax_ractor.rb /usr/share/mime/packages/freedesktop.org.xml Please provide some media-type query arguments (e.g. 'image/jpeg') ``` Finding all-extant types: ``` [okeeblow@emi#ox] ./examples/sax_ractor.rb /usr/share/mime/packages/freedesktop.org.xml image/jpeg font/ttf application/xhtml+xml image/x-pict Parallel Ractors ["Worker 0 gave us JPEG 影像 (image/jpeg) [.jpeg,.jpg,.jpe]", "Worker 1 gave us TrueType 字型 (font/ttf) [.ttf]", "Worker 2 gave us XHTML 網頁 (application/xhtml+xml) [.xhtml,.xht]", "Worker 3 gave us Macintosh Quickdraw/PICT 繪圖 (image/x-pict) [.pct,.pict,.pict1,.pict2]"] Serial Ractor "ONLY ONE OX gave us [#<CYO JPEG 影像 (image/jpeg) [.jpeg,.jpg,.jpe]>, #<CYO TrueType 字型 (font/ttf) [.ttf]>, #<CYO XHTML 網頁 (application/xhtml+xml) [.xhtml,.xht]>, #<CYO Macintosh Quickdraw/PICT 繪圖 (image/x-pict) [.pct,.pict,.pict1,.pict2]>]" ``` …and not finding invalid ones: ``` [okeeblow@emi#ox] ./examples/sax_ractor.rb /usr/share/mime/packages/freedesktop.org.xml lol/rofl fart/butt image/jpeg Parallel Ractors ["Worker 0 gave us nothing", "Worker 1 gave us nothing", "Worker 2 gave us JPEG 影像 (image/jpeg) [.jpeg,.jpg,.jpe]"] Serial Ractor "ONLY ONE OX gave us [nil, nil, #<CYO JPEG 影像 (image/jpeg) [.jpeg,.jpg,.jpe]>]" ``` Unit tests pass.
ohler55
pushed a commit
to ohler55/ox
that referenced
this pull request
Jul 27, 2021
…ax` example. (#278) For #277 I've been experimenting with `Ractor`s since upgrading to Ruby 3.0 for #275 but quickly ran into `Ractor::UnsafeError` when trying to call `Ox::sax_parse` in anything except the main `Ractor`. Per Ruby's `Ractor` C extension documentation (link below): "By default, all C extensions are recognized as `Ractor`-unsafe. If C extension becomes `Ractor`-safe, the extension should call `rb_ext_ractor_safe(true)` at the `Init_` function and all defined method marked as `Ractor`-safe. `Ractor`-unsafe C-methods only been called from main-ractor. If non-main ractor calls it, then `Ractor::UnsafeError` is raised." I don't like to open seemingly-large feature requests like this without making some attempt at it myself first, and luckily it seems like `Ox::sax_parse` Just Works™ since I marked it `Ractor`-safe, even with the `class_cache`. Confirming this safety, making any remaining changes to `Ox::Sax`, and expanding this to the non-`Sax` parts of `Ox` are all unfortunately out of my depth as a n00b C coder, so I would appreciate if you could take this over if it interests you. I am happy with just `Sax` support since I have no current need for marshalling, but I imagine other `Ox` users wouldn't be satisfied if stratified. In this commit: - Enable `rb_ext_ractor_safe` preprocessor macro via `have_func` in `extconf.rb`. - Mark `Init_Ox` and `ox_sax_parse` as `Ractor` -safe. - Add a new `Ractor`-based `Ox::Sax` example exercising both parallel and serial `Ox::Sax` handler `Ractor`s to parse data from `shared-mime-info` XML files many users likely already have on their systems. Official `Ractor` info: - "Ractor: a proposal for a new concurrent abstraction without thread-safety issues": https://bugs.ruby-lang.org/issues/17100 (ruby/ruby#3365) - Ruby's official `Ractor` documentation: https://docs.ruby-lang.org/en/master/doc/ractor_md.html - "A way to mark C extensions as thread-safe, Ractor-safe, or unsafe": https://bugs.ruby-lang.org/issues/17307 (ruby/ruby#3824) - Ruby's C Extension `Ractor` documention covering `rb_ext_ractor_safe`: https://docs.ruby-lang.org/en/master/doc/extension_rdoc.html#label-Appendix+F.+Ractor+support - A `Ractor` C Extension from the creator of `Ractor` that might serve as a useful example: https://github.com/ko1/ractor-tvar Blogs: - "Ractors: Multi-Core Parallel Processing Comes to Ruby 3": https://www.ruby3.dev/ruby-3-fundamentals/2021/01/27/ractors-multi-core-parallel-processing-in-ruby-3/ - "Ruby Ractor Experiments: Safe async communication" :https://ivoanjo.me/blog/2021/02/14/ractor-experiments-safe-async/ - "Playing with Ruby Ractors": https://billy-ruffian.co.uk/playing-with-ruby-ractors/ - "How Fast are Ractors?": https://www.fastruby.io/blog/ruby/performance/how-fast-are-ractors.html (https://github.com/noahgibbs/ractor_basic_benchmarks/tree/main/benchmarks) Before this change: ``` [okeeblow@emi#CHECKING-YOU-OUT] time ./bin/checking-you-out ~/224031-dot-jpg Received /home/okeeblow/.local/share/mime/packages/user-extension-rsrc.xml /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival/mr_mime.rb:375:in `sax_parse': ractor unsafe method called from not main ractor (Ractor::UnsafeError) from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival/mr_mime.rb:375:in `block in open' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival/mr_mime.rb:331:in `open' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival/mr_mime.rb:331:in `open' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:24:in `block (2 levels) in remember_me' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:19:in `loop' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:19:in `block in remember_me' <internal:ractor>:583:in `send': The incoming-port is already closed (Ractor::ClosedError) from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:86:in `block in extended' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:63:in `each' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:63:in `each_with_object' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/ghost_revival.rb:63:in `extended' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/inner_spirit.rb:216:in `extend' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out/inner_spirit.rb:216:in `<top (required)>' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out.rb:10:in `require_relative' from /home/okeeblow/Works/DistorteD/CHECKING-YOU-OUT/lib/checking-you-out.rb:10:in `<top (required)>' from ./bin/checking-you-out:3:in `require_relative' from ./bin/checking-you-out:3:in `<main>' ./bin/checking-you-out ~/224031-dot-jpg 0.12s user 0.05s system 100% cpu 0.168 total ``` My new `Ox::Sax` Ractor example script's usage: ``` [okeeblow@emi#ox] ./examples/sax_ractor.rb Please provide the path to a `shared-mime-info` XML package and some media-type query arguments (e.g. 'image/jpeg') ``` ``` [okeeblow@emi#ox] ./examples/sax_ractor.rb /usr/share/mime/packages/freedesktop.org.xml Please provide some media-type query arguments (e.g. 'image/jpeg') ``` Finding all-extant types: ``` [okeeblow@emi#ox] ./examples/sax_ractor.rb /usr/share/mime/packages/freedesktop.org.xml image/jpeg font/ttf application/xhtml+xml image/x-pict Parallel Ractors ["Worker 0 gave us JPEG 影像 (image/jpeg) [.jpeg,.jpg,.jpe]", "Worker 1 gave us TrueType 字型 (font/ttf) [.ttf]", "Worker 2 gave us XHTML 網頁 (application/xhtml+xml) [.xhtml,.xht]", "Worker 3 gave us Macintosh Quickdraw/PICT 繪圖 (image/x-pict) [.pct,.pict,.pict1,.pict2]"] Serial Ractor "ONLY ONE OX gave us [#<CYO JPEG 影像 (image/jpeg) [.jpeg,.jpg,.jpe]>, #<CYO TrueType 字型 (font/ttf) [.ttf]>, #<CYO XHTML 網頁 (application/xhtml+xml) [.xhtml,.xht]>, #<CYO Macintosh Quickdraw/PICT 繪圖 (image/x-pict) [.pct,.pict,.pict1,.pict2]>]" ``` …and not finding invalid ones: ``` [okeeblow@emi#ox] ./examples/sax_ractor.rb /usr/share/mime/packages/freedesktop.org.xml lol/rofl fart/butt image/jpeg Parallel Ractors ["Worker 0 gave us nothing", "Worker 1 gave us nothing", "Worker 2 gave us JPEG 影像 (image/jpeg) [.jpeg,.jpg,.jpe]"] Serial Ractor "ONLY ONE OX gave us [nil, nil, #<CYO JPEG 影像 (image/jpeg) [.jpeg,.jpg,.jpe]>]" ``` Unit tests pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Quoted from https://bugs.ruby-lang.org/issues/17100
This ticket proposes a new concurrent abstraction named "Ractor", Ruby's
Actor-like feature (not an exact Actor-model).
Ractor achieves the following goals:
I'm working on this proposal in a few years, and the project name was
"Guild". I renamed it from Guild to Ractor because of Matz's preference.
Resources:
Current implementation is not complete (many bugs are remaining) but it passes current CI.
I propose to merge it soon and try the APIs, continue to develop the implementation on a master branch.