Commit graph

56 commits

Author SHA1 Message Date
Nobuyoshi Nakada
6179cc0118
[DOC] Fill undocumented documents 2025-08-04 02:23:43 +09:00
Koichi Sasada
84253ce38c fix obsolete doc with Ractor::Port 2025-07-17 12:13:33 +09:00
zzak
e8094943a4
s/sned/send 2025-06-09 16:23:08 +09:00
Koichi Sasada
8070d5d97d Ractor#take and warn
`Ractor#take` was deprecated but some libraries can use it as
an alias for `Ractor#value` (i.e., to wait for a Ractor's
temrination and retrieve its result).
Therefore `Ractor#take` is simply an alias for `Ractor#value`.

This method will remain available until the end of August 2025,
unless there is further discussion.
2025-06-04 19:18:16 +09:00
Koichi Sasada
ef2bb61018 Ractor::Port
* Added `Ractor::Port`
  * `Ractor::Port#receive` (support multi-threads)
  * `Rcator::Port#close`
  * `Ractor::Port#closed?`
* Added some methods
  * `Ractor#join`
  * `Ractor#value`
  * `Ractor#monitor`
  * `Ractor#unmonitor`
* Removed some methods
  * `Ractor#take`
  * `Ractor.yield`
* Change the spec
  * `Racotr.select`

You can wait for multiple sequences of messages with `Ractor::Port`.

```ruby
ports = 3.times.map{ Ractor::Port.new }
ports.map.with_index do |port, ri|
  Ractor.new port,ri do |port, ri|
    3.times{|i| port << "r#{ri}-#{i}"}
  end
end

p ports.each{|port| pp 3.times.map{port.receive}}

```

In this example, we use 3 ports, and 3 Ractors send messages to them respectively.
We can receive a series of messages from each port.

You can use `Ractor#value` to get the last value of a Ractor's block:

```ruby
result = Ractor.new do
  heavy_task()
end.value
```

You can wait for the termination of a Ractor with `Ractor#join` like this:

```ruby
Ractor.new do
  some_task()
end.join
```

`#value` and `#join` are similar to `Thread#value` and `Thread#join`.

To implement `#join`, `Ractor#monitor` (and `Ractor#unmonitor`) is introduced.

This commit changes `Ractor.select()` method.
It now only accepts ports or Ractors, and returns when a port receives a message or a Ractor terminates.

We removes `Ractor.yield` and `Ractor#take` because:
* `Ractor::Port` supports most of similar use cases in a simpler manner.
* Removing them significantly simplifies the code.

We also change the internal thread scheduler code (thread_pthread.c):
* During barrier synchronization, we keep the `ractor_sched` lock to avoid deadlocks.
  This lock is released by `rb_ractor_sched_barrier_end()`
  which is called at the end of operations that require the barrier.
* fix potential deadlock issues by checking interrupts just before setting UBF.

https://bugs.ruby-lang.org/issues/21262
2025-05-31 04:01:33 +09:00
lukeg
c941fced21 Throw RuntimeError if getting/setting ractor local storage for non-main ractor
[Bug #19367]
2025-05-13 13:18:10 +02:00
Kanstantsin Shautsou
4646ab8917 Use correct warn method 2025-04-07 16:37:39 +02:00
Lorenzo Zabot
a203603be0 Correct typo in Ractor comment 2025-03-31 09:16:18 +09:00
Nobuyoshi Nakada
e433e6515e
[DOC] Exclude 'Class' and 'Module' from RDoc's autolinking 2025-01-02 12:36:06 +09:00
Nobuyoshi Nakada
bf878b5494
[DOC] Ractor::RemoteError 2024-12-25 13:16:28 +09:00
Victor Shepelev
efe671f9d3
Properly document Ractor#require (#12389) 2024-12-21 20:05:26 +02:00
Jean Boussier
5d97c14fec FIx Ractor.main? to return true not 0
[Bug #20954]
2024-12-16 08:37:55 +01:00
Koichi Sasada
e09c23433e followup 0bdb38ba6b
(forgot to amend...)
2024-12-13 17:05:58 +09:00
Koichi Sasada
0bdb38ba6b Ractor.set_if_absent(key)
to initialize ractor local storage in thread-safety.
[Feature #20875]
2024-12-13 06:22:13 +09:00
Koichi Sasada
aa63699d10 support require in non-main Ractors
Many libraries should be loaded on the main ractor because of
setting constants with unshareable objects and so on.

This patch allows to call `requore` on non-main Ractors by
asking the main ractor to call `require` on it. The calling ractor
waits for the result of `require` from the main ractor.

If the `require` call failed with some reasons, an exception
objects will be deliverred from the main ractor to the calling ractor
if it is copy-able.

Same on `require_relative` and `require` by `autoload`.

Now `Ractor.new{pp obj}` works well (the first call of `pp` requires
`pp` library implicitly).

[Feature #20627]
2024-11-08 18:02:46 +09:00
Koichi Sasada
075a102c93 Ractor.[] and Ractor.[]=
`Ractor#[]/[]=` is only for accessors to the current ractor, so that
`Ractor.[]/[]=` is simpler.
[Feature #20715]
2024-11-08 18:02:46 +09:00
Koichi Sasada
f0d0c030c0 Ractor.main?
to return the current ractor is the main ractor.
(== `Ractor.current == Ractor.main`)
2024-11-08 18:02:46 +09:00
Koichi Sasada
c9a9b8036c remove Ractor::Selector from Ruby level
`Ractor::Selector` is not approved by Matz so remove it from
Ruby-level.

The implementation is used by `Ractor.select` so most of implementation
was remaind and calling `rb_init_ractor_selector()`, `Ractor::Selector`
will be defined. I will provide `ractor-selector` gem to try it.
2023-12-16 01:00:01 +09:00
Koichi Sasada
5875fce6ce Ractor::Selector#empty?
It returns the waiting set is empty or not.

Also add Ractor::Selector's tests.
2023-03-03 00:08:02 +09:00
Koichi Sasada
a4421bd73c Rewrite Ractor synchronization mechanism
This patch rewrites Ractor synchronization mechanism, send/receive
and take/yield.

* API
  * Ractor::Selector is introduced for lightweight waiting
    for many ractors.
* Data structure
  * remove `struct rb_ractor_waiting_list` and use
    `struct rb_ractor_queue takers_queue` to manage takers.
  * remove `rb_ractor_t::yield_atexit` and use
    `rb_ractor_t::sync::will_basket::type` to check the will.
  * add `rb_ractor_basket::p.take` to represent a taking ractor.
* Synchronization protocol
  * For the Ractor local GC, `take` can not make a copy object
    directly so ask to generate the copy from the yielding ractor.
  * The following steps shows what `r1.take` does on `r0`.
    * step1: (r0) register `r0` into `r1`'s takers.
    * step2: (r0) check `r1`'s status and wakeup r0 if `r1` is waiting
             for yielding a value.
    * step3: (r0) sleep until `r1` wakes up `r0`.
  * The following steps shows what `Ractor.yield(v)` on `r1`.
    * step1: (r1) check first takers of `r1` and if there is (`r0`),
             make a copy object of `v` and pass it to `r0` and
             wakes up `r0`.
    * step2: (r1) if there is no taker ractors, sleep until
             another ractor try to take.
2023-03-02 14:31:54 +09:00
John Bampton
2f7270c681
Fix spelling (#7389) 2023-02-27 09:56:06 -08:00
Luke Gruber
4ffef59bb1
[DOC] Make changes to docs in ractor.rb (#7180)
* Make changes to docs in ractor.rb

Mainly English changes to make things more clear, and to fix minor
non-idiomatic phrases. Also clarified difference between frozen and
shareable objects.

* More minor changes to Ractor docs.
2023-01-29 10:01:49 +09:00
Nobuyoshi Nakada
131c31a920
[Bug #19081] Show the caller location in warning for Ractor
The internal location in ractor.rb is not usefull at all.
```
$ ruby -e 'Ractor.new {}'
<internal:ractor>:267: warning: Ractor is experimental, ...
```
2022-10-26 19:43:14 +09:00
Felix Yan
1486ffe039
[DOC] Correct article of Ractor's introduction [ci skip] 2022-08-28 16:27:11 +09:00
Nobuyoshi Nakada
94c3d528e7
Fix conversion of rb_ractor_id() 2022-07-28 23:46:07 +09:00
Nobuyoshi Nakada
a27c274f04
[DOC] Fix broken links [ci skip]
* As the "doc/" prefix is specified by the `--page-dir` option,
  remove from the rdoc references.
* Refer to the original .rdoc instead of the converted .html.
2021-09-15 14:16:14 +09:00
S-H-GAMELINKS
bdd6d8746f Replace RBOOL macro 2021-09-05 23:01:27 +09:00
Ryuta Kamizono
33f2ff3bab Fix some typos by spell checker 2021-04-26 10:07:41 +09:00
Tom Chen
8187228de0
Fix ractor docs (#4048) [doc] 2021-01-10 15:39:37 -05:00
Marc-Andre Lafortune
a76082f499 Add call-seq to Ractor doc; improve wording [doc] 2020-12-24 02:19:37 -05:00
nagachika
831f785068 [DOC] Fix typo in Ractor.make_shareable documentation. 2020-12-22 08:08:27 +09:00
Koichi Sasada
c34c6a89cb fix ractor's doc. [ci skip] 2020-12-22 06:09:42 +09:00
Koichi Sasada
d0e4ccbefc add Ractor.main
It returns main Ractor, like Thread.main.
[Feature #17418]
2020-12-22 05:54:14 +09:00
Koichi Sasada
35471a9487 add Ractor#[]/#[]= for ractor local storage
This API is similar to plain old Thread#[]/Fiber#[] interface
with symbol key.
2020-12-22 05:26:32 +09:00
Marc-Andre Lafortune
8f2031a067 Ractor#to_s as #inspect 2020-12-21 13:31:00 -05:00
Koichi Sasada
02d9524cda separate rb_ractor_pub from rb_ractor_t
separate some fields from rb_ractor_t to rb_ractor_pub and put it
at the beggining of rb_ractor_t and declare it in vm_core.h so
vm_core.h can access rb_ractor_pub fields.

Now rb_ec_ractor_hooks() is a complete inline function and no
MJIT related issue.
2020-12-22 00:03:00 +09:00
Koichi Sasada
7600f69a8e rename to rb_ractor_make_shareable_copy()
from rb_ractor_make_copy_shareable().
2020-12-21 02:21:33 +09:00
Nobuyoshi Nakada
b911509a08
Adjusted indents of closing braces [ci skip] 2020-12-20 15:13:25 +09:00
Koichi Sasada
7f8108eeff fix indent 2020-12-20 04:51:00 +09:00
Victor Shepelev
1f565ac6d9
Add documentation for Ractor (#3895) 2020-12-19 13:04:40 -05:00
Nobuyoshi Nakada
5c9d6ea6b4
Strip trailing spaces [ci skip] 2020-12-19 15:34:37 +09:00
Koichi Sasada
80cb9165fa add "copy: true" option for Ractor.make_shareable
Ractor.make_shareable(obj) tries to make obj a shareable object
by changing the attribute of obj and traversable objects from obj
(mainly freeze them).

"copy: true" option is more conservative approach by make deep
copied object and make it sharable. It doesn't affect any existing
objects.
2020-12-19 05:52:18 +09:00
Marc-Andre Lafortune
d5929b39a9 Make Ractor#receive_if private 2020-12-16 10:42:17 -05:00
Koichi Sasada
a9a7f4d8b8 Ractor#receive_if to receive only matched messages
Instead of Ractor.receive, Ractor.receive_if can provide a pattern
by a block and you can choose the receiving message.

[Feature #17378]
2020-12-16 19:12:48 +09:00
Koichi Sasada
0a52161872 fix Ractor#receive by other ractors
Ractor#receive can be called by the another Ractors using send,
so making this method completely same as `Ractor.receive` even if
the ractor is specified by the receiver (OO term :p).
2020-12-16 17:18:13 +09:00
Nobuyoshi Nakada
65450e8f7d Call FrozenCore.make_shareable 2020-12-14 19:19:16 +09:00
Nobuyoshi Nakada
f43c71abe0 Implemented shareable_constant_value
It does shallow freeze only for now.
2020-12-14 19:19:16 +09:00
Marc-Andre Lafortune
53ce71b5af Ractor.select requires an argument or yield_value 2020-12-07 02:21:12 -05:00
Koichi Sasada
fa3670e6e4 remove Ractor#close
close_incoming by antoher ractor means there is no other messages
will be sent to the ractor, so Ractor.receive will block forever,
and it should raise and stop.

close_outgoing by antoher ractor means, ... I don't have good idea
to use it. It can be a private method.

Ractor#close calls both, but it does not make sense to call
different purpose methods, so I remove it.
2020-11-11 18:11:09 +09:00
Marc-Andre Lafortune
bd6cd85155 Tweak return of Ractor#close, add doc 2020-10-30 15:22:18 -04:00