<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/test/-ext-/thread/test_instrumentation_api.rb, branch v4.0.3</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>`Ractor::Port`</title>
<updated>2025-05-30T19:01:33+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2025-05-26T18:58:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ef2bb61018cd9ccb5b61a3d91911e04a773da4a7'/>
<id>ef2bb61018cd9ccb5b61a3d91911e04a773da4a7</id>
<content type='text'>
* 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 &lt;&lt; "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
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* 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 &lt;&lt; "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
</pre>
</div>
</content>
</entry>
<entry>
<title>Skip TestThreadInstrumentation#test_sleeping_inside_ractor on ModGC workflow (#12996)</title>
<updated>2025-03-27T12:22:38+00:00</updated>
<author>
<name>Naoto Ono</name>
<email>onoto1998@gmail.com</email>
</author>
<published>2025-03-27T12:22:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=5adb2591dacc9b9c40db373616b6bc0b5c5dadb7'/>
<id>5adb2591dacc9b9c40db373616b6bc0b5c5dadb7</id>
<content type='text'>
TestThreadInstrumentation#test_sleeping_inside_ractor is a flaky and failing intermittently. Additionally, Launchable reported this test as a top flaky test. (Link: https://app.launchableinc.com/organizations/ruby/workspaces/ruby/insights/unhealthy-tests)

It failed only failed intermittently on ModGC workflow, so I'm gonna skip this test on ModGC workflow.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
TestThreadInstrumentation#test_sleeping_inside_ractor is a flaky and failing intermittently. Additionally, Launchable reported this test as a top flaky test. (Link: https://app.launchableinc.com/organizations/ruby/workspaces/ruby/insights/unhealthy-tests)

It failed only failed intermittently on ModGC workflow, so I'm gonna skip this test on ModGC workflow.</pre>
</div>
</content>
</entry>
<entry>
<title>Fix incorrect assertion in TestThreadInstrumentation</title>
<updated>2024-05-20T05:59:59+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2024-05-20T02:42:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=0b38403328f02f2b103e15103b2ace69d123c9f3'/>
<id>0b38403328f02f2b103e15103b2ace69d123c9f3</id>
<content type='text'>
The test meant to assert the thread is suspended at least once,
but was actually asserting to it to be suspected at least twice.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The test meant to assert the thread is suspended at least once,
but was actually asserting to it to be suspected at least twice.
</pre>
</div>
</content>
</entry>
<entry>
<title>Remove unused statement</title>
<updated>2023-12-12T01:31:37+00:00</updated>
<author>
<name>Yusuke Endoh</name>
<email>mame@ruby-lang.org</email>
</author>
<published>2023-12-12T01:26:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=535eb4de1109f5b8a8bde063dacc4c6fabf2322c'/>
<id>535eb4de1109f5b8a8bde063dacc4c6fabf2322c</id>
<content type='text'>
... to disable a warning: assigned but unused variable - expected
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
... to disable a warning: assigned but unused variable - expected
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix test of GVL instrumentation on Ractor sleeping</title>
<updated>2023-12-09T20:01:29+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2023-12-09T19:33:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=9e09e5aa3af03a42cf6ef59da2779b0a5d5a6505'/>
<id>9e09e5aa3af03a42cf6ef59da2779b0a5d5a6505</id>
<content type='text'>
It seems that the Ractor sleep GVL event arrives very slightly after the
value becomes available and other threads wake (which makes sense) so we
need a little additional time to ensure we end up in a consisteny state.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
It seems that the Ractor sleep GVL event arrives very slightly after the
value becomes available and other threads wake (which makes sense) so we
need a little additional time to ensure we end up in a consisteny state.
</pre>
</div>
</content>
</entry>
<entry>
<title>Add missing GVL hooks for M:N threads and ractors</title>
<updated>2023-12-09T17:31:41+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2023-12-09T05:16:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=b2ad4fec1a369e1cbd0c65d52062946a4fbfb84b'/>
<id>b2ad4fec1a369e1cbd0c65d52062946a4fbfb84b</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "Add missing GVL hooks for M:N threads and ractors"</title>
<updated>2023-12-04T02:37:06+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2023-12-04T02:13:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=85bc80a51be0ceedcc57e7b6b779e6f8f885859e'/>
<id>85bc80a51be0ceedcc57e7b6b779e6f8f885859e</id>
<content type='text'>
This reverts commit ad54fbf281ca1935e79f4df1460b0106ba76761e.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit ad54fbf281ca1935e79f4df1460b0106ba76761e.
</pre>
</div>
</content>
</entry>
<entry>
<title>Add missing GVL hooks for M:N threads and ractors</title>
<updated>2023-12-02T18:06:07+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2023-11-29T23:54:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ad54fbf281ca1935e79f4df1460b0106ba76761e'/>
<id>ad54fbf281ca1935e79f4df1460b0106ba76761e</id>
<content type='text'>
[Bug #20019]

This fixes GVL instrumentation in three locations it was missing:
- Suspending when blocking on a Ractor
- Suspending when doing a coroutine transfer from an M:N thread
- Resuming after an M:N thread starts

Co-authored-by: Matthew Draper &lt;matthew@trebex.net&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Bug #20019]

This fixes GVL instrumentation in three locations it was missing:
- Suspending when blocking on a Ractor
- Suspending when doing a coroutine transfer from an M:N thread
- Resuming after an M:N thread starts

Co-authored-by: Matthew Draper &lt;matthew@trebex.net&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Further fix the GVL instrumentation API</title>
<updated>2023-11-28T19:06:55+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>byroot@ruby-lang.org</email>
</author>
<published>2023-11-28T10:03:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=982641939cf709d22dbc060df57cbed31acd3b97'/>
<id>982641939cf709d22dbc060df57cbed31acd3b97</id>
<content type='text'>
Followup: https://github.com/ruby/ruby/pull/9029

[Bug #20019]

Some events still weren't triggered from the right place.

The test suite was also improved a bit more.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Followup: https://github.com/ruby/ruby/pull/9029

[Bug #20019]

Some events still weren't triggered from the right place.

The test suite was also improved a bit more.
</pre>
</div>
</content>
</entry>
<entry>
<title>Refactor and fix the GVL instrumentation API</title>
<updated>2023-11-27T16:37:57+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>byroot@ruby-lang.org</email>
</author>
<published>2023-11-24T12:18:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=23a7714343b372234972ef0dacf774d07fe65ced'/>
<id>23a7714343b372234972ef0dacf774d07fe65ced</id>
<content type='text'>
This entirely changes how it is tested. Rather than to use counters
we now record the timeline of events with associated threads which
makes it much easier to assert that certains events are only preceded
by a specific event, and makes it much easier to debug unexpected
timelines.

Co-Authored-By: Étienne Barrié &lt;etienne.barrie@gmail.com&gt;
Co-Authored-By: JP Camara &lt;jp@jpcamara.com&gt;
Co-Authored-By: John Hawthorn &lt;john@hawthorn.email&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This entirely changes how it is tested. Rather than to use counters
we now record the timeline of events with associated threads which
makes it much easier to assert that certains events are only preceded
by a specific event, and makes it much easier to debug unexpected
timelines.

Co-Authored-By: Étienne Barrié &lt;etienne.barrie@gmail.com&gt;
Co-Authored-By: JP Camara &lt;jp@jpcamara.com&gt;
Co-Authored-By: John Hawthorn &lt;john@hawthorn.email&gt;
</pre>
</div>
</content>
</entry>
</feed>
