[#100284] [Ruby master Bug#17211] Test failures in ruby2.7.2 and ruby3.0~preview1 — utkarsh@...

Issue #17211 has been reported by utkarsh (Utkarsh Gupta).

10 messages 2020/10/02

[#100301] [Ruby master Feature#17215] Backport for arm64 optimizations that exist for power/x86 — jaruga@...

Issue #17215 has been reported by jaruga (Jun Aruga).

10 messages 2020/10/05

[#100329] [Ruby master Bug#17220] Rails Active Job integration test fails with Ruby 3.0.0 since 2038cc6cab6ceeffef3ec3a765c70ae684f829ed — yasuo.honda@...

Issue #17220 has been reported by yahonda (Yasuo Honda).

28 messages 2020/10/07

[#100332] [Ruby master Bug#17221] Relax the Fiber#transfer's limitation — ko1@...

Issue #17221 has been reported by ko1 (Koichi Sasada).

15 messages 2020/10/07

[#100348] [Ruby master Bug#17257] Integer#pow(0, 1) returns 1, which is incorrect — universato@...

Issue #17257 has been reported by universato (Yoshimine Sato).

13 messages 2020/10/09

[#100371] [Ruby master Feature#17260] Promote pattern matching to official feature — kazuki@...

Issue #17260 has been reported by ktsj (Kazuki Tsujimoto).

10 messages 2020/10/11

[#100383] [Ruby master Feature#17261] Software transactional memory (STM) for Threads and Ractors — ko1@...

Issue #17261 has been reported by ko1 (Koichi Sasada).

14 messages 2020/10/12

[#100401] [Ruby master Bug#17263] Fiber context switch degrades with number of fibers, limit on number of fibers — ciconia@...

Issue #17263 has been reported by ciconia (Sharon Rosner).

14 messages 2020/10/15

[#100422] [CommonRuby Feature#17265] Add `Bool` module — marcandre-ruby-core@...

Issue #17265 has been reported by marcandre (Marc-Andre Lafortune).

11 messages 2020/10/19

[#100466] [Ruby master Feature#17273] shareable_constant_value pragma — ko1@...

Issue #17273 has been reported by ko1 (Koichi Sasada).

14 messages 2020/10/21

[#100471] [Ruby master Feature#17277] Make Enumerator#with_index yield row and col indices for Matrix — grzegorz.jakubiak@...

Issue #17277 has been reported by greggzst (Grzegorz Jakubiak).

8 messages 2020/10/21

[#100479] [Ruby master Feature#17278] On-demand sharing of constants for Ractor — daniel@...42.com

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

13 messages 2020/10/21

[#100534] [Ruby master Feature#17284] Shareable Proc — ko1@...

Issue #17284 has been reported by ko1 (Koichi Sasada).

16 messages 2020/10/25

[#100597] [Ruby master Feature#17288] Optimize __send__ call with a literal method name — muraken@...

Issue #17288 has been reported by mrkn (Kenta Murata).

13 messages 2020/10/27

[#100669] [Ruby master Feature#17295] Feature: Create a directory and file with Pathname#touch — get.codetriage@...

Issue #17295 has been reported by schneems (Richard Schneeman).

9 messages 2020/10/30

[#100673] [Ruby master Feature#17298] Ractor's basket communication APIs — ko1@...

Issue #17298 has been reported by ko1 (Koichi Sasada).

15 messages 2020/10/30

[#100675] [Ruby master Misc#17299] DevelopersMeeting20201120Japan — mame@...

Issue #17299 has been reported by mame (Yusuke Endoh).

11 messages 2020/10/31

[ruby-core:100678] [Ruby master Feature#17298] Ractor's basket communication APIs

From: eregontp@...
Date: 2020-10-31 11:00:52 UTC
List: ruby-core #100678
Issue #17298 has been updated by Eregon (Benoit Daloze).


From the benchmark above, USE_BASKET=false takes for me `5.636s`.
Adding `Ractor.make_shareable(ary)`, it takes `0.192s`.
So that's ~10x faster than with `w/ basket API` on this benchmark, and does not require new APIs and concepts.

So I don't see the need for this API, better to freeze or to move, and both are more efficient.
Copying is confusing anyway if mutated.

Maybe all messages should be made `Ractor.make_shareable` by `Ractor#send`/`Ractor.yield`, unless `move: true` is used?
Then there would be no confusion about mutations, and there would be no hidden cost to sending a message (copying a big data structure can take a long time as we see here).
Moving still has a cost proportional to the #objects in the object graph, which seems unavoidable, but at least it does not need to copy e.g. the array storage.

Do other languages have something similar to the basket API?

----------------------------------------
Feature #17298: Ractor's basket communication APIs
https://bugs.ruby-lang.org/issues/17298#change-88320

* Author: ko1 (Koichi Sasada)
* Status: Open
* Priority: Normal
----------------------------------------
This ticket proposes send_basket/send_receive, yield_basket/take_basket APIs to make effective and flexible bridge ractors.

## Background

When we want to send an object as a message, usually we need to copy it.
Copying is achieved by marshal protocol, and receiver load it immediately.

If we want to make a bridge ractor which receive a message and send it to another ractor, the immediate loading is not effective.

```ruby
bridge = Ractor.new do
  Ractor.yield Ractor.receive
end

consumer = Ractor.new bridge do |from|
  obj = from.take
  do_task(obj)
end

msg = [1, 2, 3]
bridge.send msg
```

In this case, the array (`[1, 2, 3]`) is

* (1) dumped at the first `bridge.send msg`
* (2) loaded at `Ractor.receive`
* (3) dumped again at `Ractor.yield`
* (4) laoded at `from.take`

Essentially we only need one dump/load pair, but now it needs 2 pairs.

Mixing "moving" is more complex.
Now there is no way to pass the "moving" status to the bridge ractors, we can not make a moving bridge.

## Proposal

To make more effective and flexible bridge ractors, we propose new basket APIs

* `Ractor.receive_basket`
* `Ractor#send_basket`
* `Ractor.take_basket`
* `Ractor.yield_basket`

They receive a message, but remaining dumped state and send it without dumping again.
We can rewrite the above example with these APIs.

```ruby
bridge = Ractor.new do
  Ractor.yield_basket Ractor.receive_basket
end

consumer = Ractor.new bridge do |from|
  obj = from.take
  do_task(obj)
end

msg = [1, 2, 3]
bridge.send msg
```

In this case,

* (1) dumped at the first `bridge.send msg`
* (2) laoded at `from.take`

we only need one dump/load pair.


## Implementation

https://github.com/ruby/ruby/pull/3725

## Evaluation

The following program makes 4 type of bridges and pass an array as a message through them.

```ruby
USE_BASKET = false

receive2yield = Ractor.new do
  loop do
    if USE_BASKET
      Ractor.yield_basket Ractor.receive_basket
    else
      Ractor.yield Ractor.receive
    end
  end
end

receive2send = Ractor.new receive2yield do |r|
  loop do
    if USE_BASKET
      r.send_basket Ractor.receive_basket
    else
      r.send Ractor.receive
    end
  end
end

take2yield = Ractor.new receive2yield do |from|
  loop do
    if USE_BASKET
      Ractor.yield_basket from.take_basket
    else
      Ractor.yield from.take
    end
  end
end

take2send = Ractor.new take2yield, Ractor.current do |from, to|
  loop do
    if USE_BASKET
      to.send_basket from.take_basket
    else
      to.send from.take
    end
  end
end

AN = 1_000
LN = 10_000

ary = Array.new(AN) # 1000
LN.times{
  receive2send << ary
  Ractor.receive
}

# This program passes the message as:
#   main ->
#   receive2send ->
#   receive2yield ->
#   take2yield ->
#   take2send ->
#   main
```

The result is:

```
w/ basket API   0m2.056s
w/o basket API  0m5.974s
```

on my machine (=~ x3 faster).

(BTW, if we have a TVar, we can change the value `USE_BASKET` dynamically)

## Discussion

### naming

Of course, naming is an issue. Now, I named "_basket" because source code using this terminology.
There are other candidates:

* container metaphor
  * package
  * parcel
  * box
  * envelope
  * packet (maybe bad idea because of confusion of networking)
  * bundle (maybe bad idea because of confusion of bin/bundle)
* "don't touch the content" metaphor
  * raw
  * sealed
  * unopened

I like "basket" because I like picnic.

### feature

Now, basket is represented by "Ractor::Basket" and there is no methods.
We can add the following feature:

* `Ractor::Basket#sender` return the sending ractor.
* `Ractor::Basket#sender = a_ractor` change the sending ractor.
* `Ractor::Basket#value` returns the content.

There was another proposal `Ractor.recvfrom`, but we only need these APIs.




-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

In This Thread