From: "ko1 (Koichi Sasada) via ruby-core" Date: 2024-07-11T03:14:02+00:00 Subject: [ruby-core:118542] [Ruby master Bug#20627] `require` on Ractor should run on the main Ractor Issue #20627 has been reported by ko1 (Koichi Sasada). ---------------------------------------- Bug #20627: `require` on Ractor should run on the main Ractor https://bugs.ruby-lang.org/issues/20627 * Author: ko1 (Koichi Sasada) * Status: Open * Assignee: ko1 (Koichi Sasada) * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- Now `require` on main Ractor is not allowed (raising error) but it is hard, especially for `autoload`. So let's allow `require` by running it on the main Ractor. ## Background On many libraries it is needed to run loading on the main Ractors because: 1. Setup constants with unshareable objects (such as `C = []`) are not allowed on non main Ractors. 2. Setup global variables and class variables are not allowed. `$LOADED_FEATURES` is also untouchable. 3. (maybe more reasons) So the `require` on non main Ractors is not allowed. However it is hard to program especially on `autoload`. Also dynamic `require` (`require` in methods) are not allowed too (`pp` method, for example). ## Proposal Allow `require` on non main Ractors by running `require` process on the main Ractor. ![](clipboard-202407111201-kaiem.png) (quoted on my talk at RubyKaigi 2024) ### `rb_ractor_interrupt_exec(target_ractor, func)` C-API Make a thread on `target_ractor` and run `func` (C function) on it. I think it is safe to expose on Ruby API because running `func` on a *newly created* thread (do not disturb running target threads). But now it is proposed as only (hidden) C-API. ### New Ractor methods - `Rcator.main?` returns Ractors - `Ractor.require(feature)` do `require` on the main Ractor These new methods are useful for users who override `require` method like [RubyGems](https://github.com/ruby/ruby/blob/master/lib/rubygems/core_ext/kernel_require.rb#L36). ```ruby alias orig_require require def require feature return Rator.require(feature) unless Ractor.main? # overriding require code end ``` Or we can prepend a module like: ``` Module.new do def require(feature) return Rator.require(feature) unless Ractor.main? super(feature) end Kernel.prepend self end ``` will support ractors for all overgrinding methods. But not sure it is acceptable to add additional one modules in ancestors by `prepend`. Also this technique doesn't support require overriding by prepending. ## Implementation https://github.com/ruby/ruby/pull/11142 (not matured yet) ---Files-------------------------------- clipboard-202407111201-kaiem.png (70.8 KB) -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/