[#120465] [Ruby master Bug#20998] rb_str_locktmp() changes flags of frozen strings and string literals — "Eregon (Benoit Daloze) via ruby-core" <ruby-core@...>

Issue #20998 has been reported by Eregon (Benoit Daloze).

17 messages 2025/01/03

[#120469] [Ruby master Feature#21000] A way to avoid loading constant required by a type check — "Dan0042 (Daniel DeLorme) via ruby-core" <ruby-core@...>

Issue #21000 has been reported by Dan0042 (Daniel DeLorme).

13 messages 2025/01/03

[#120488] [Ruby master Feature#21005] Update the source location method to include line start/stop and column start/stop details — "bkuhlmann (Brooke Kuhlmann) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxMDA1IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IGJrdWhsbWFubiAoQnJvb2tlIEt1aGxt

16 messages 2025/01/05

[#120580] [Ruby master Bug#21021] "try to mark T_NONE object" with 3.4.1 — "Benoit_Tigeot (Benoit Tigeot) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxMDIxIGhhcyBiZWVuIHJlcG9ydGVkIGJ5IEJlbm9pdF9UaWdlb3QgKEJlbm9pdCBU

28 messages 2025/01/09

[#120601] [Ruby master Bug#21024] Ruby including <cstdbool> generates compilation warning with GCC 15, header is deprecated in C++17, — "jprokop (Jarek Prokop) via ruby-core" <ruby-core@...>

Issue #21024 has been reported by jprokop (Jarek Prokop).

7 messages 2025/01/10

[#120617] [Ruby master Feature#21028] Method for finding why an object isn't Ractor shareable — "tenderlovemaking (Aaron Patterson) via ruby-core" <ruby-core@...>

Issue #21028 has been reported by tenderlovemaking (Aaron Patterson).

7 messages 2025/01/11

[#120618] [Ruby master Bug#21029] Prism behavior for `defined? (;x)` differs — "qnighy (Masaki Hara) via ruby-core" <ruby-core@...>

Issue #21029 has been reported by qnighy (Masaki Hara).

12 messages 2025/01/12

[#120619] [Ruby master Bug#21030] Bug: #step with Range<ActiveSupport::Duration> behavior broken on Ruby 3.4.1 — "johnnyshields (Johnny Shields) via ruby-core" <ruby-core@...>

Issue #21030 has been reported by johnnyshields (Johnny Shields).

11 messages 2025/01/12

[#120628] [Ruby master Bug#21031] Incompatibility with prism and parse.y when eval'ing unnamed forwarding variables — "ksss (Yuki Kurihara) via ruby-core" <ruby-core@...>

Issue #21031 has been reported by ksss (Yuki Kurihara).

8 messages 2025/01/13

[#120637] [Ruby master Bug#21032] `Module#autoload?` is slow when `$LOAD_PATH` contains a relative path — "byroot (Jean Boussier) via ruby-core" <ruby-core@...>

Issue #21032 has been reported by byroot (Jean Boussier).

9 messages 2025/01/13

[#120643] [Ruby master Feature#21033] Allow lambdas that don't access `self` to be Ractor shareable — "tenderlovemaking (Aaron Patterson) via ruby-core" <ruby-core@...>

Issue #21033 has been reported by tenderlovemaking (Aaron Patterson).

18 messages 2025/01/13

[#120650] [Ruby master Bug#21034] try to mark T_NONE object error after upgrading to 3.4.1 — "travisbell (Travis Bell) via ruby-core" <ruby-core@...>

Issue #21034 has been reported by travisbell (Travis Bell).

17 messages 2025/01/14

[#120657] [Ruby master Misc#21035] Clarify or redefine Module#autoload? and Module#const_defined? — "fxn (Xavier Noria) via ruby-core" <ruby-core@...>

Issue #21035 has been reported by fxn (Xavier Noria).

28 messages 2025/01/14

[#120694] [Ruby master Bug#21039] Ractor.make_shareable breaks block semantics (seeing updated captured variables) of existing blocks — "Eregon (Benoit Daloze) via ruby-core" <ruby-core@...>

Issue #21039 has been reported by Eregon (Benoit Daloze).

26 messages 2025/01/15

[#120738] [Ruby master Bug#21048] [Prism] rescue in modifier form with condition behaves differently — "Earlopain (Earlopain _) via ruby-core" <ruby-core@...>

Issue #21048 has been reported by Earlopain (Earlopain _).

7 messages 2025/01/19

[#120774] [Ruby master Bug#21087] "try to mark T_NONE object" error in ActiveRecord with 3.4.1 upgrade — "p8 (Petrik de Heus) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxMDg3IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IHA4IChQZXRyaWsgZGUgSGV1cykuDQoN

6 messages 2025/01/23

[#120787] [Ruby master Bug#21088] TCPSocket.new raises Socket::ResolutionError instead of Errno::ECONNREFUSED for hosts defined in /etc/hosts — "dmlary (David Lary) via ruby-core" <ruby-core@...>

Issue #21088 has been reported by dmlary (David Lary).

9 messages 2025/01/24

[#120811] [Ruby master Bug#21095] Prefer `uname -n` over `hostname` in tests. — "ioquatix (Samuel Williams) via ruby-core" <ruby-core@...>

Issue #21095 has been reported by ioquatix (Samuel Williams).

10 messages 2025/01/28

[#120819] [Ruby master Bug#21097] `x = a rescue b in c` and `def f = a rescue b in c` parsed differently between parse.y and prism — "tompng (tomoya ishida) via ruby-core" <ruby-core@...>

Issue #21097 has been reported by tompng (tomoya ishida).

12 messages 2025/01/29

[#120840] [Ruby master Misc#21100] DevMeeting before or after RubyKaigi2025 — "ko1 (Koichi Sasada) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxMTAwIGhhcyBiZWVuIHJlcG9ydGVkIGJ5IGtvMSAoS29pY2hpIFNhc2FkYSkuDQoN

9 messages 2025/01/30

[ruby-core:120668] [Ruby master Feature#21033] Allow lambdas that don't access `self` to be Ractor shareable

From: "Eregon (Benoit Daloze) via ruby-core" <ruby-core@...>
Date: 2025-01-14 19:22:04 UTC
List: ruby-core #120668
Issue #21033 has been updated by Eregon (Benoit Daloze).


tenderlovemaking (Aaron Patterson) wrote in #note-11:
> Adding syntax makes it much harder to port existing applications to use Ractors.
> I'm specifically looking at adding Ractor support to Rails at the moment, and there are blocks that are shared between threads and would need to be shared between Ractors.

I think porting any non-trivial code to use Ractors is a huge effort (I would think most gems out there do not work when used inside a Ractor, which seems a huge compatibility problem).
Ractor seems fundamentally incompatible with much of how Ruby code works, a lot of it being mutation, sharing state, configuration, etc globally and having access to everything everywhere.
It's like forcing the actor model when there are so many other concurrency models and the actor one is only good for some (small) subset of it.

So my impression is the issue of procs/lambdas being not shareable is just one of the many hurdles (but maybe I'm wrong).

> New syntax / idioms would mean we have to change all lambda creation sites.

I understand why new syntax would be very annoying.
But one could define `def isolated(&) = nil.instance_exec(&)` or so and then use `isolated { lambda { ... } }`.
Or maybe a new argument/kwarg to `#lambda` then or some new method (not sure how well that would work on older versions though).
Or a new magic comment?
I think it makes some sense to change all blocks meant to be passed to a Ractor, because changing `self` to `nil` not where the block is declared would lead to lots of confusion (NoMethodError on nil much later, looking at the code `self` can't possibly be `nil`), it breaks the intent of the person who wrote that block, and also to anyone reading that code.

It seems nice if we could reliably auto-detect blocks which don't rely on `self`, indeed, but I think that's basically impossible with things like `debug_inspector` and `Proc#binding` and `eval`.
I think it apply to a pretty small set of blocks, as I would guess most blocks rely on `self`, e.g. to call an instance method (or even just to call a Kernel instance method).
Also it doesn't seem nice if a program would behave differently by adding a `p(value)` in some block to debug (which adds a `putself`) and that would cause a Ractor::IsolationError or so.

----------------------------------------
Feature #21033: Allow lambdas that don't access `self` to be Ractor shareable
https://bugs.ruby-lang.org/issues/21033#change-111493

* Author: tenderlovemaking (Aaron Patterson)
* Status: Open
----------------------------------------
Hi,

I would like to allow lambdas that don't access `self` to be eligible for Ractor shareability regardless of the shareability status of `self`.

Consider the following code:

```ruby
class Foo
  def make_lambda
    x = 123
    lambda { x }
  end
end

Ractor.make_shareable(Foo.new.make_lambda)
```

With Ruby 3.4.X, this will raise an exception.  The reason is because `self`, which is an unfrozen instance of `Foo`, is not shareable.  However, we can see from the code that the lambda doesn't access `self`.  I would like to make lambdas such as the ones above eligible for shareability, and I've submitted a patch [here](https://github.com/ruby/ruby/pull/12567).

I think we can detect access to `self` by scanning the instructions in the lambda.  Any references to `putself`, `getinstancevariable`, or `setinstancevariable` will result in using the default behavior (checking the frozen status of `self`).

## Considerations

### What about `eval`?

I think that `eval` is not a problem because calling eval has an implicit reference to `self`:

```
$ ./miniruby --dump=insns -e 'lambda { eval("123") }'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,22)>
0000 putself                                                          (   1)[Li]
0001 send                                   <calldata!mid:lambda, argc:0, FCALL>, block in <main>
0004 leave

== disasm: #<ISeq:block in <main>@-e:1 (1,7)-(1,22)>
0000 putself                                                          (   1)[LiBc]
0001 putchilledstring                       "123"
0003 opt_send_without_block                 <calldata!mid:eval, argc:1, FCALL|ARGS_SIMPLE>
0005 leave                                  [Br]
```

If we try to call `eval` inside the lambda, there will be an implicit `putself` instruction added which means we will fall back to the old behavior.

### What about `binding`?

If you call `binding` from inside the `lambda` there will be a `putself` instruction so we fall back to the old behavior.  This is the same as the `eval` case.

### What about `binding` via a local?

If you assign `binding` to a local, shareability will fail because the `lambda` references an unshareable local:

```ruby
class Foo
  def make_lambda
    x = binding
    lambda { x }
  end
end

b = Foo.new.make_lambda
# exception because local `x` is not shareable
Ractor.make_shareable(b)
```

### What about accessing `binding` via the proc itself?

The lambda can references itself via a local and access binding, but again this will fail isolation when locals are scanned:

```ruby
class Foo
  def make_lambda
    x = lambda { x.binding.eval("self") }
  end
end

b = Foo.new.make_lambda
# exception because local `x` is not shareable
Ractor.make_shareable(b)
```

I _think_ I've covered all cases where `self` can possibly escape.  I would appreciate any feedback.

Again, [here is the patch](https://github.com/ruby/ruby/pull/12567).

Thanks.

---Files--------------------------------
0001-Allow-lambdas-that-don-t-access-self-to-be-made-shar.patch (6.51 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/


In This Thread