ml.ruby-lang.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

ruby-core

Thread Start a new thread
Download
Threads by month
  • ----- 2025 -----
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
ruby-core@ml.ruby-lang.org

September 2024

  • 5 participants
  • 189 discussions
[ruby-core:115981] [Ruby master Bug#20105] Introduce `IO::Stream` or something similar.
by ioquatix (Samuel Williams) 07 Jun '25

07 Jun '25
Issue #20105 has been reported by ioquatix (Samuel Williams). ---------------------------------------- Bug #20105: Introduce `IO::Stream` or something similar. https://bugs.ruby-lang.org/issues/20105 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal * Assignee: ioquatix (Samuel Williams) * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- Ruby's IO class has a general model for streaming IO, including some hidden classes like `IO::generic_readable` and `IO::generic_writable`. As Ruby's core IO classes evolve, gems like `openssl` (see `OpenSSL::Buffering`) need to be updated to support changes to the interface. As it stands, there are changes in `IO` which are not copied to `OpenSSL::Buffering`. I'd like to propose we introduce some shared interface for streams that is used by `IO`, `Socket`, and `OpenSSL` to start with. The general interface would be similar to `IO` and allow code like `OpenSSL` to avoid re-implementing the `IO` interface. -- https://bugs.ruby-lang.org/
2 2
0 0
[ruby-core:117216] [Ruby master Bug#20346] FiberScheduler.unblock not called by Thread#join when Thread body contains Ractor.take
by forthoney (Seong-Heon Jung) 05 Jun '25

05 Jun '25
Issue #20346 has been reported by forthoney (Seong-Heon Jung). ---------------------------------------- Bug #20346: FiberScheduler.unblock not called by Thread#join when Thread body contains Ractor.take https://bugs.ruby-lang.org/issues/20346 * Author: forthoney (Seong-Heon Jung) * Status: Open * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- When using a `Ractor.take` inside a different thread, `Thread#join` on the thread running `Ractor.take` fails to call `FiberScheduler.unblock`. The below code can replicate this behavior ```ruby require "async" class RactorWrapper def initialize @ractor = Ractor.new do Ractor.recv # Ractor doesn't start until explicitly told to # Do some calculations fib = ->(x) { x < 2 ? 1 : fib.call(x - 1) + fib.call(x - 2) } fib.call(20) end end def take_async @ractor.send(nil) Thread.new { @ractor.take }.join.value end end Async do |task| 10000.times do |i| task.async do RactorWrapper.new.take_async puts i end end end ``` The above code deadlocks, and when we leave a debugging print statement inside of `Async`'s scheduler's `block` and `unblock` method, we can confirm that we only call `Scheduler.block`, and never `Scheduler.unblock` -- https://bugs.ruby-lang.org/
3 2
0 0
[ruby-core:118191] [Ruby master Bug#20560] make install - skipped bundled gems - minor issue
by MSP-Greg (Greg L) 04 Jun '25

04 Jun '25
Issue #20560 has been reported by MSP-Greg (Greg L). ---------------------------------------- Bug #20560: make install - skipped bundled gems - minor issue https://bugs.ruby-lang.org/issues/20560 * Author: MSP-Greg (Greg L) * Status: Open * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- See most recent job: https://github.com/ruby/ruby/actions/runs/9389674968/job/25857719333#step:9… Which is logging the following during `make install`: ``` skipped bundled gems: power_assert-2.0.4dev.gem not found in bundled_gems syslog-0.1.2.gem not found in bundled_gems ``` Not sure what the correct versioning should be. Or, should bundled gems use 'dev' versions, etc... -- https://bugs.ruby-lang.org/
2 3
0 0
[ruby-core:115995] [Ruby master Bug#20112] Ractors not working properly in ruby 3.3.0
by ariasdiniz (Aria Diniz) 19 May '25

19 May '25
Issue #20112 has been reported by ariasdiniz (Aria Diniz). ---------------------------------------- Bug #20112: Ractors not working properly in ruby 3.3.0 https://bugs.ruby-lang.org/issues/20112 * Author: ariasdiniz (Aria Diniz) * Status: Open * Priority: Normal * ruby -v: 3.3.0 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- I recently installed Ruby 3.3.0, and noticed that some of my scripts that use Ractors started to struggle with performance. After doing some benchmarks, I noticed that, while Ractors seem to be working well on Ruby 3.2.2, they're not working properly on 3.3.0. I'm using Ubuntu 22.04.3 LTS Here is the benchmark code: ``` ruby # frozen_string_literal: true require 'benchmark' Ractor.new { :warmup } if defined?(Ractor) Benchmark.bmbm do |x| x.report("Thread: ") do threads = [] 8.times do |i| threads << Thread.new do 20000000.times do |j| ((i * 20000000) + j)**2 end end end threads.each(&:join) end x.report("Ractor: ") do ractors = [] 0..8.times do |i| ractors << Ractor.new(i) do |k| 20000000.times do |j| ((k * 20000000) + j)**2 end end end ractors.map(&:take) end end ``` Here is the results for Ruby 3.2.2: Rehearsal -------------------------------------------- Thread: 7.666909 0.001091 7.668000 ( 7.675266) Ractor: 19.318528 0.012017 19.330545 ( 2.505888) ---------------------------------- total: 26.998545sec user system total real Thread: 7.918141 0.004011 7.922152 ( 7.928772) Ractor: 19.366414 0.003954 19.370368 ( 2.517993) Here is the results for Ruby 3.3.0: Rehearsal -------------------------------------------- Thread: 8.634152 0.010895 8.645047 ( 8.645104) Ractor: 100.172179 0.035985 100.208164 ( 15.213245) --------------------------------- total: 108.853211sec user system total real Thread: 9.451236 0.004002 9.455238 ( 9.460132) Ractor: 118.463294 0.119942 118.583236 ( 18.462157) -- https://bugs.ruby-lang.org/
5 4
0 0
[ruby-core:119137] [Ruby master Bug#20726] Issue with hash without braces when assigned to constant with ractor literals
by luke-gru (Luke Gruber) 14 May '25

14 May '25
Issue #20726 has been reported by luke-gru (Luke Gruber). ---------------------------------------- Bug #20726: Issue with hash without braces when assigned to constant with ractor literals https://bugs.ruby-lang.org/issues/20726 * Author: luke-gru (Luke Gruber) * Status: Open * ruby -v: 3.4.0dev * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- ```ruby a = 'hi' A = ['hello' => a] p A ``` gives: ``` ./ruby -I../ruby/lib -I. -I.ext/x86_64-linux -I.ext/common -r./x86_64-linux-fake ../ruby/test.rb -- raw disasm-------- trace: 1 0000 putchilledstring "hi" ( 3) 0002 setlocal_WC_0 3 ( 3) trace: 1 0004 newarray 1 ( 4) 0006 putspecialobject 3 ( 4) * 0008 setconstant :A ( 4) trace: 1 0010 putself ( 5) 0011 opt_getconstant_path [:A] ( 5) 0013 opt_send_without_block <calldata:p, 1> ( 5) 0015 leave ( 5) --------------------- ../ruby/test.rb:4: argument stack underflow (-1) ../ruby/test.rb: compile error (SyntaxError) ``` This is due to a line in `compile.c`, function `compile_shareable_literal_constant`: ```c if (!RNODE_HASH(node)->nd_brace) { } ``` I'm not sure why this condition is there so I'm not confident in making a fix. Also, my git-fu isn't the best so I can't track down the right commit where it was added. -- https://bugs.ruby-lang.org/
4 3
0 0
[ruby-core:111809] [Ruby master Bug#19338] Ruby hangs when defining new constant in ractor
by luke-gru (Luke Gruber) 13 May '25

13 May '25
Issue #19338 has been reported by luke-gru (Luke Gruber). ---------------------------------------- Bug #19338: Ruby hangs when defining new constant in ractor https://bugs.ruby-lang.org/issues/19338 * Author: luke-gru (Luke Gruber) * Status: Open * Priority: Normal * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- This code causes Ruby to hang: ``` ruby rs = [] 2.times do rs << Ractor.new do MYCONSTANT = 2 end end rs.each(&:take) ``` There is a problem when the warning is being outputted with multiple ractors. A thread is calling RB_VM_LOCK() while holding the VM lock in ractor.c (ractor_check_blocking()) If the code is changed to RB_VM_LOCK_ENTER() and RB_VM_LOCK_LEAVE() then it fixes it, but I don't know if there's a better way. Thanks! -- https://bugs.ruby-lang.org/
3 3
0 0
[ruby-core:118467] [Ruby master Feature#20610] Float::INFINITY as IO.select timeout argument
by akr (Akira Tanaka) 13 May '25

13 May '25
Issue #20610 has been reported by akr (Akira Tanaka). ---------------------------------------- Feature #20610: Float::INFINITY as IO.select timeout argument https://bugs.ruby-lang.org/issues/20610 * Author: akr (Akira Tanaka) * Status: Open ---------------------------------------- I propose IO.select accepts Float::INFINITY as a timeout argument. It behaves the same as nil which means IO.select will block indefinitely. Motivation: Currently, the Ruby convention to indicate no timeout is using nil. This practice often forces us to treat the nil case separately. Conceptually, no timeout can be thought of as an infinite timeout. So I propose to accept Float::INFINITY as a timeout. It makes us less conditionals when we need to calculate or compare timeouts. Assume `now` method as follows to read the following examples. ``` def now = Process.clock_gettime(Process::CLOCK_MONOTONIC) ``` Example 1: absolute timeout Sometimes we maintain timeout as an absolute clock. The following method takes a relative timeout as an argument. It invokes IO.select several times and raises if the timeout is reached. Assuming a user must specify a finite timeout, the following definition is possible. ``` # user_timeout is the required argument def method(..., user_timeout) abs_timeout = now + user_timeout loop { IO.select(rs, ws, es, (abs_timeout - now).clamp(0..)) raise "timeout" if abs_timeout < now ... } end ``` Consider we need to make user_timeout optional. If user_timeout is not given, no timeout occurs. The implementation is as follows. I think the following implementation is typical. It needs 3 more conditionals than the above. ``` # user_timeout is an optional argument. nil means no timeout. def method(..., user_timeout=nil) abs_timeout = user_timeout ? now + user_timeout : nil loop { IO.select(rs, ws, es, user_timeout ? (abs_timeout - now).clamp(0..) : nil) raise "timeout" if abs_timeout && (abs_timeout < now) ... } end ``` It is possible to reduce a conditional if we use Float::INFINITY. (`abs_timeout && (abs_timeout < now)` is changed to `abs_timeout < now`) ``` # user_timeout is an optional argument. nil means no timeout. def method(..., user_timeout=nil) abs_timeout = user_timeout ? now + user_timeout : Float::INFINITY loop { IO.select(rs, ws, es, abs_timeout != Float::INFINITY ? (abs_timeout - now).clamp(0..) : nil) raise "timeout" if abs_timeout < now ... } end ``` If IO.select accepts Float::INFINITY as a timeout argument (this proposal), we can reduce one more conditional as follows. ``` # user_timeout is an optional argument. nil means no timeout. def method(..., user_timeout=nil) abs_timeout = user_timeout ? now + user_timeout : Float::INFINITY loop { IO.select(rs, ws, es, (abs_timeout - now).clamp(0..)) raise "timeout" if abs_timeout < now ... } end ``` Example 2: minimum of timeouts Sometimes we need to choose the minimum of several timeouts. I think many event-driven programs use this strategy to determine the timeout for select function. If "no timeout" is represented as nil, `[t1, t2, t3, ...].compact.min` is the minimum. If "no timeout" is represented as Float::INFINITY, we can remove `compact`: `[t1, t2, t3, ...].min` However, Float::INFINITY must be converted to nil for IO.select. This proposal removes this conversion. Example 3: maximum of timeouts Sometimes we need to choose the maximum of several timeouts. We encountered this situation with a Happy Eyeballs implementation. There are two timeouts for getaddrinfo and connect. We need to wait the longer timeout because a timeout for one doesn't stop another. Also, we don't ignore results after a timeout as long as the algorithm waits for something. If "no timeout" is represented as nil, `ts = [t1, t2, t3, ...]; ts.include?(nil) ? nil : ts.max` is the maximum. If "no timeout" is represented as Float::INFINITY, we can compute the maximum more easily: `[t1, t2, t3, ...].max` It makes code simpler. However, Float::INFINITY must be converted to nil for IO.select. This proposal removes this conversion. Several Consideration: Consideration 1: Methods other than IO.select. Several methods take a timeout. An incomplete list of methods is as follows. (I searched rb_time_interval.) - IO.select(rs, ws, es, timeout) - sleep(secs) - TCPSocket.new(connect_timeout:) - io.wait_readable(timeout) - io.wait_writable(timeout) - io.wait_priority(timeout) - mutex.sleep(timeout) Do we want to modify them consistently to accept Float::INFINITY? Consideration 2: C-level API If we want to change the timeout of many methods, we would wish to new C-level API similar to rb_time_interval but can return NULL. Unfortunately, rb_time_interval cannot return NULL because the return type is struct timeval. Note that ext/io/wait/wait.c contains get_timeout function. It seems a good first step for such API. Consideration 3: IEEE 754 dependency. Minor platforms (such as VAX) use non-IEEE 754 floating point numbers without infinity. Note that NetBSD/vax still works. (And there is an emulator, simh). Consideration 4: It seems no major languages accept infinity as select's timeout. I found Perl, Python, and OCaml take a floating point number as a timeout of select function. But they don't accept infinity. -- https://bugs.ruby-lang.org/
3 7
0 0
[ruby-core:116085] [Ruby master Bug#20165] Ractors moving a Struct breaks beyond the first 3 fields
by codekitchen (Brian Palmer) 09 May '25

09 May '25
Issue #20165 has been reported by codekitchen (Brian Palmer). ---------------------------------------- Bug #20165: Ractors moving a Struct breaks beyond the first 3 fields https://bugs.ruby-lang.org/issues/20165 * Author: codekitchen (Brian Palmer) * Status: Open * Priority: Normal * ruby -v: ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- Experimenting with Ractors on ruby 3.3.0, and I'm seeing a bug where if you move a struct between ractors, all but the first 3 fields are set to nil. ``` ruby Foo = Struct.new(:a,:b,:c,:d,:e,:f) r = Ractor.new { foo = Foo[0,0,0,0,0,0] p foo Ractor.yield(foo, move: true) } p r.take ``` ``` ❯ ruby -v ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] ❯ ruby rbug.rb rbug.rb:3: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. #<struct Foo a=0, b=0, c=0, d=0, e=0, f=0> #<struct Foo a=0, b=0, c=0, d=nil, e=nil, f=nil> ``` This seems specific to moving, if I set `move: false` the struct makes it across OK. -- https://bugs.ruby-lang.org/
3 2
0 0
[ruby-core:112091] [Ruby master Bug#19387] Issue with ObjectSpace.each_objects not returning IO objects after starting a ractor
by luke-gru (Luke Gruber) 09 May '25

09 May '25
Issue #19387 has been reported by luke-gru (Luke Gruber). ---------------------------------------- Bug #19387: Issue with ObjectSpace.each_objects not returning IO objects after starting a ractor https://bugs.ruby-lang.org/issues/19387 * Author: luke-gru (Luke Gruber) * Status: Open * Priority: Normal * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- ```ruby r = Ractor.new do receive # block, the problem is not the termination of the ractor but the starting end ObjectSpace.each_object(IO) { |io| p io # we get no objects } ``` -- https://bugs.ruby-lang.org/
6 8
0 0
[ruby-core:112207] [Ruby master Bug#19408] Object no longer frozen after moved from a ractor
by luke-gru (Luke Gruber) 09 May '25

09 May '25
Issue #19408 has been reported by luke-gru (Luke Gruber). ---------------------------------------- Bug #19408: Object no longer frozen after moved from a ractor https://bugs.ruby-lang.org/issues/19408 * Author: luke-gru (Luke Gruber) * Status: Open * Priority: Normal * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- I think frozen objects should still be frozen after a move. ```ruby r = Ractor.new do obj = receive p obj.frozen? # should be true but is false p obj end obj = [Object.new].freeze r.send(obj, move: true) r.take ``` -- https://bugs.ruby-lang.org/
3 3
0 0
  • ← Newer
  • 1
  • 2
  • 3
  • 4
  • 5
  • ...
  • 19
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.