66 Commits

Author SHA1 Message Date
Steve Savio
bff7c6d9e9 [DOC] Fix minor typo on shareable procs section 2026-01-06 18:30:33 +09:00
Luke Gruber
481f16f3f1
[DOC] Improve ractor class docs (grammar, code examples) (#15686) 2025-12-22 13:22:01 -05:00
John Hawthorn
0c4fcdff32 Update ArgumentError message for Ractor.select 2025-12-18 16:47:35 -08:00
John Hawthorn
535233c68c [DOC] Update ractor.rb docs 2025-12-18 15:59:49 -08:00
Luke Gruber
a7eb1879ad
[DOC] small improvements to ractor class docs (#15584)
* Ractor.yield no longer exists
* Ractor.shareable_proc returns a copy of the given proc
* Improve wording for monitoring/unmonitoring ports
2025-12-18 15:08:36 -05:00
John Hawthorn
5828872ec4 Update Ractor warning message
Although the Ractor API is still experimental and may change, and there
may be some implementation issues, we should no longer say that there
are many.

Hopefully we can remove this warning entirely for Ruby 4.1
2025-12-10 16:01:27 -08:00
Koichi Sasada
2aaea665bb fix typo s/sharable/shareable/ 2025-12-05 03:10:50 +09:00
Koichi Sasada
f8231dacd5 Ractor.store_if_absent should not warn
```ruby
$VERBOSE = true

Ractor.store_if_absent :key do
end #=> warning: the block passed to 'Ractor.store_if_absent' defined at <internal:ractor>:474 may be ignored
```
2025-12-04 17:15:42 +09:00
Koichi Sasada
55b1ba3bf2 Ractor.shareable_proc
call-seq:
  Ractor.sharable_proc(self: nil){} -> sharable proc

It returns shareable Proc object. The Proc object is
shareable and the self in a block will be replaced with
the value passed via `self:` keyword.

In a shareable Proc, the outer variables should
* (1) refer shareable objects
* (2) be not be overwritten

```ruby
  a = 42
  Ractor.shareable_proc{ p a }
  #=> OK

  b = 43
  Ractor.shareable_proc{ p b; b = 44 }
  #=> Ractor::IsolationError because 'b' is reassigned in the block.

  c = 44
  Ractor.shareable_proc{ p c }
  #=> Ractor::IsolationError because 'c' will be reassigned outside of the block.
  c = 45

  d = 45
  d = 46 if cond
  Ractor.shareable_proc{ p d }
  #=> Ractor::IsolationError because 'd' was reassigned outside of the block.
```

The last `d`'s case can be relaxed in a future version.

The above check will be done in a static analysis at compile time,
so the reflection feature such as `Binding#local_varaible_set`
can not be detected.

```ruby
  e = 42
  shpr = Ractor.shareable_proc{ p e } #=> OK
  binding.local_variable_set(:e, 43)
  shpr.call #=> 42 (returns captured timing value)
```

Ractor.sharaeble_lambda is also introduced.
[Feature #21550]
[Feature #21557]
2025-09-24 03:59:03 +09:00
Koichi Sasada
f9bffff3d4 remove Ractor#take
[Feature #21262]
2025-09-01 17:34:41 +09:00
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 0bdb38ba6be208064a514c12a9b80328645689f8
(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