From 9ef556d452b7987a96d78ec0947d04bc33498c2e Mon Sep 17 00:00:00 2001 From: Florian Dejonckheere Date: Mon, 25 Mar 2024 08:41:38 +0200 Subject: [PATCH 1/8] Target Ruby 3.3 --- .github/workflows/test.yml | 2 +- .github/workflows/test_io_uring.yml | 2 +- .rubocop.yml | 4 ++-- README.md | 2 +- docs/advanced-io.md | 4 ++-- docs/readme.md | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bf48e4b9..09c0b5e3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] - ruby: ['3.1', '3.2', 'head'] + ruby: ['3.1', '3.2', '3.3', 'head'] name: >- ${{matrix.os}}, ${{matrix.ruby}} diff --git a/.github/workflows/test_io_uring.yml b/.github/workflows/test_io_uring.yml index b7d3afcf..ec3fdc94 100644 --- a/.github/workflows/test_io_uring.yml +++ b/.github/workflows/test_io_uring.yml @@ -8,7 +8,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - ruby: ['3.1', '3.2', 'head'] + ruby: ['3.1', '3.2', '3.3', 'head'] name: >- ${{matrix.os}}, ${{matrix.ruby}} diff --git a/.rubocop.yml b/.rubocop.yml index c27956f9..13c77979 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,5 @@ AllCops: - TargetRubyVersion: 3.2 + TargetRubyVersion: 3.3 RubyInterpreters: - ruby Exclude: @@ -202,4 +202,4 @@ Style/SlicingWithRange: Style/RaiseArgs: Exclude: - - lib/polyphony/extensions/fiber.rb \ No newline at end of file + - lib/polyphony/extensions/fiber.rb diff --git a/README.md b/README.md index 4a6af0e9..cc3b68de 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ ## What is Polyphony? Polyphony is a library for building concurrent applications in Ruby. Polyphony -harnesses the power of [Ruby fibers](https://rubyapi.org/3.2/o/fiber) to provide +harnesses the power of [Ruby fibers](https://rubyapi.org/3.3/o/fiber) to provide a cooperative, sequential coroutine-based concurrency model. Under the hood, Polyphony uses [io_uring](https://unixism.net/loti/what_is_io_uring.html) or [libev](https://github.com/enki/libev) to maximize I/O performance. diff --git a/docs/advanced-io.md b/docs/advanced-io.md index 7de4d4d0..22919645 100644 --- a/docs/advanced-io.md +++ b/docs/advanced-io.md @@ -119,7 +119,7 @@ minimizing memory use and GC pressure. ## Compressing and decompressing in-flight data You might be familiar with Ruby's [zlib](https://github.com/ruby/zlib) gem (docs -[here](https://rubyapi.org/3.2/o/zlib)), which can be used to compress and +[here](https://rubyapi.org/3.3/o/zlib)), which can be used to compress and uncompress data using the popular gzip format. Imagine we want to implement an HTTP server that can serve files compressed using gzip: @@ -318,4 +318,4 @@ provided by Polyphony, which lets us write less code, have it run faster, have it run concurrently, and minimize memory allocations and pressure on the Ruby GC. Feel free to browse the [IO examples](https://github.com/digital-fabric/polyphony/tree/master/examples/io) -included in Polyphony. \ No newline at end of file +included in Polyphony. diff --git a/docs/readme.md b/docs/readme.md index ac8b8afb..47a6feb8 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -25,7 +25,7 @@ ## What is Polyphony? Polyphony is a library for building concurrent applications in Ruby. Polyphony -harnesses the power of [Ruby fibers](https://rubyapi.org/3.2/o/fiber) to provide +harnesses the power of [Ruby fibers](https://rubyapi.org/3.3/o/fiber) to provide a cooperative, sequential coroutine-based concurrency model. Under the hood, Polyphony uses [io_uring](https://unixism.net/loti/what_is_io_uring.html) or [libev](https://github.com/enki/libev) to maximize I/O performance. From e148d7b5b2a4f336c25b25f454fda447f16a7dc3 Mon Sep 17 00:00:00 2001 From: Florian Dejonckheere Date: Mon, 25 Mar 2024 08:52:42 +0200 Subject: [PATCH 2/8] Update development dependencies --- .rubocop.yml | 1 + polyphony.gemspec | 14 +++++++------- test/helper.rb | 1 + 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 13c77979..cfcc79f5 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -9,6 +9,7 @@ AllCops: - 'Gemfile*' - 'ext/**/*.rb' - lib/polyphony/adapters/irb.rb + NewCops: enable Style/LambdaCall: Enabled: false diff --git a/polyphony.gemspec b/polyphony.gemspec index 2a27afce..69b5ddc4 100644 --- a/polyphony.gemspec +++ b/polyphony.gemspec @@ -20,15 +20,15 @@ Gem::Specification.new do |s| s.require_paths = ["lib"] s.required_ruby_version = '>= 3.1' - s.add_development_dependency 'rake-compiler', '1.2.1' - s.add_development_dependency 'minitest', '5.17.0' + s.add_development_dependency 'rake-compiler', '1.2.7' + s.add_development_dependency 'minitest', '5.22.3' s.add_development_dependency 'simplecov', '0.22.0' - s.add_development_dependency 'rubocop', '1.45.1' + s.add_development_dependency 'rubocop', '1.62.1' s.add_development_dependency 'pry', '0.14.2' - s.add_development_dependency 'msgpack', '1.6.0' + s.add_development_dependency 'msgpack', '1.7.2' s.add_development_dependency 'httparty', '0.21.0' - s.add_development_dependency 'localhost', '1.1.10' - s.add_development_dependency 'debug', '1.8.0' - s.add_development_dependency 'benchmark-ips', '2.10.0' + s.add_development_dependency 'localhost', '1.2.0' + s.add_development_dependency 'debug', '1.9.1' + s.add_development_dependency 'benchmark-ips', '2.13.0' end diff --git a/test/helper.rb b/test/helper.rb index 6d6ae3a8..b1f7780e 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -11,6 +11,7 @@ require_relative './eg' require 'minitest/autorun' +require 'minitest/unit' ::Exception.__disable_sanitized_backtrace__ = true From 50885414661d3aefd45762a0da2b0aa237756827 Mon Sep 17 00:00:00 2001 From: Florian Dejonckheere Date: Mon, 25 Mar 2024 09:01:03 +0200 Subject: [PATCH 3/8] Update Github actions --- .github/workflows/test.yml | 2 +- .github/workflows/test_io_uring.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 09c0b5e3..7713db34 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Setup machine - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Ruby uses: ruby/setup-ruby@v1 with: diff --git a/.github/workflows/test_io_uring.yml b/.github/workflows/test_io_uring.yml index ec3fdc94..5b111cc2 100644 --- a/.github/workflows/test_io_uring.yml +++ b/.github/workflows/test_io_uring.yml @@ -16,7 +16,7 @@ jobs: runs-on: ${{matrix.os}} steps: - name: Checkout repository and submodules - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive - name: Setup Ruby From 29df9b2e6f0b01eae10ab3b833517483a76e9736 Mon Sep 17 00:00:00 2001 From: Florian Dejonckheere Date: Mon, 25 Mar 2024 08:38:42 +0200 Subject: [PATCH 4/8] Temporarily add bundled gems --- polyphony.gemspec | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/polyphony.gemspec b/polyphony.gemspec index 69b5ddc4..2c851b4b 100644 --- a/polyphony.gemspec +++ b/polyphony.gemspec @@ -31,4 +31,10 @@ Gem::Specification.new do |s| s.add_development_dependency 'localhost', '1.2.0' s.add_development_dependency 'debug', '1.9.1' s.add_development_dependency 'benchmark-ips', '2.13.0' + + # FIXME: remove gems when all other dependencies have bundled them (not part of stdlib since Ruby 3.4) + s.add_development_dependency 'base64', '0.2.0' + s.add_development_dependency 'bigdecimal', '3.1.7' + s.add_development_dependency 'csv', '3.3.0' + s.add_development_dependency 'mutex_m', '0.2.0' end From 43e177a75c6800ac78243dacf3b9af8efcd022ad Mon Sep 17 00:00:00 2001 From: Florian Dejonckheere Date: Mon, 16 Sep 2024 09:14:02 +0200 Subject: [PATCH 5/8] Forward keyword arguments in Polyphony::ResourcePool --- lib/polyphony/core/resource_pool.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/polyphony/core/resource_pool.rb b/lib/polyphony/core/resource_pool.rb index 4613f8bd..a1f997de 100644 --- a/lib/polyphony/core/resource_pool.rb +++ b/lib/polyphony/core/resource_pool.rb @@ -56,9 +56,10 @@ def acquire(&block) # # @param sym [Symbol] method name # @param args [Array] method arguments + # @param kwargs [Hash] keyword arguments # @return [any] result of method call - def method_missing(sym, *args, &block) - acquire { |r| r.send(sym, *args, &block) } + def method_missing(sym, *args, **kwargs, &block) + acquire { |r| r.send(sym, *args, **kwargs, &block) } end # @!visibility private From bf693fd2c93064308da05cf0485b5152b8b16b79 Mon Sep 17 00:00:00 2001 From: Florian Dejonckheere Date: Mon, 16 Sep 2024 10:33:16 +0200 Subject: [PATCH 6/8] Cancel Github Actions workflow in progress --- .github/workflows/test.yml | 4 ++++ .github/workflows/test_io_uring.yml | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7713db34..8c975c17 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,6 +13,10 @@ jobs: name: >- ${{matrix.os}}, ${{matrix.ruby}} + concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{matrix.os}}-${{matrix.ruby}}-libev + cancel-in-progress: true + runs-on: ${{matrix.os}} env: diff --git a/.github/workflows/test_io_uring.yml b/.github/workflows/test_io_uring.yml index 5b111cc2..7b945d22 100644 --- a/.github/workflows/test_io_uring.yml +++ b/.github/workflows/test_io_uring.yml @@ -13,7 +13,12 @@ jobs: name: >- ${{matrix.os}}, ${{matrix.ruby}} + concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{matrix.os}}-${{matrix.ruby}}-io_uring + cancel-in-progress: true + runs-on: ${{matrix.os}} + steps: - name: Checkout repository and submodules uses: actions/checkout@v4 From 507a9654573b699fc021cc547139027e5d9b0007 Mon Sep 17 00:00:00 2001 From: Florian Dejonckheere Date: Mon, 16 Sep 2024 11:15:49 +0200 Subject: [PATCH 7/8] Fix inspect format for Ruby >= 3.4.0 --- test/helper.rb | 8 ++++++++ test/test_fiber.rb | 5 +++-- test/test_thread.rb | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/test/helper.rb b/test/helper.rb index b1f7780e..008b9f67 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -45,6 +45,14 @@ def format_trace(args) def monotonic_clock ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) end + + def inspect_method_name_for(klass_name, method_name) + if RUBY_VERSION < '3.4.0' + "`#{method_name}'" + else + "'#{klass_name}##{method_name}'" + end + end end class MiniTest::Test diff --git a/test/test_fiber.rb b/test/test_fiber.rb index 3657ea4d..e4c85479 100644 --- a/test/test_fiber.rb +++ b/test/test_fiber.rb @@ -619,7 +619,7 @@ def test_inspect f = spin(:baz) { :foo } expected = format( - '#', + "#", f.object_id, __FILE__, spin_line_no @@ -627,8 +627,9 @@ def test_inspect assert_equal expected, f.inspect f.await + expected = format( - '#', + "#", f.object_id, __FILE__, spin_line_no diff --git a/test/test_thread.rb b/test/test_thread.rb index 21b434c1..72d9649f 100644 --- a/test/test_thread.rb +++ b/test/test_thread.rb @@ -133,7 +133,7 @@ def test_that_suspend_returns_immediately_if_no_watchers Thread.backend.trace_proc = proc {|*r| records << r } suspend assert_equal [ - [:block, Fiber.current, ["#{__FILE__}:#{__LINE__ - 2}:in `test_that_suspend_returns_immediately_if_no_watchers'"] + caller] + [:block, Fiber.current, ["#{__FILE__}:#{__LINE__ - 2}:in #{inspect_method_name_for(self.class.name, __method__.to_s)}"] + caller] ], records ensure Thread.backend.trace_proc = nil From c8535192e9592842bfad50ea97c57722d77e0fbe Mon Sep 17 00:00:00 2001 From: Florian Dejonckheere Date: Mon, 2 Dec 2024 15:13:27 -0300 Subject: [PATCH 8/8] Use kwargs instead of empty hash argument --- lib/polyphony/extensions/io.rb | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/polyphony/extensions/io.rb b/lib/polyphony/extensions/io.rb index dbf315fb..ab2b0570 100644 --- a/lib/polyphony/extensions/io.rb +++ b/lib/polyphony/extensions/io.rb @@ -27,20 +27,17 @@ def binwrite(name, string, offset = nil) end end - # @!visibility private - EMPTY_HASH = {}.freeze - # @!visibility private alias_method :orig_foreach, :foreach # @!visibility private - def foreach(name, sep = $/, limit = nil, getline_args = EMPTY_HASH, &block) + def foreach(name, sep = $/, limit = nil, **kwargs, &block) if sep.is_a?(Integer) sep = $/ limit = sep end File.open(name, 'r') do |f| - f.each_line(sep, limit, chomp: getline_args[:chomp], &block) + f.each_line(sep, limit, chomp: kwargs[:chomp], &block) end end @@ -48,21 +45,21 @@ def foreach(name, sep = $/, limit = nil, getline_args = EMPTY_HASH, &block) alias_method :orig_read, :read # @!visibility private - def read(name, length = nil, offset = nil, opt = EMPTY_HASH) + def read(name, length = nil, offset = nil, **kwargs) if length.is_a?(Hash) - opt = length + kwargs = length length = nil end - File.open(name, opt[:mode] || 'r') do |f| + File.open(name, kwargs[:mode] || 'r') do |f| f.seek(offset) if offset length ? f.read(length) : f.read end end alias_method :orig_readlines, :readlines - def readlines(name, sep = $/, limit = nil, getline_args = EMPTY_HASH) + def readlines(name, sep = $/, limit = nil, **kwargs) File.open(name, 'r') do |f| - f.readlines(sep, **getline_args) + f.readlines(sep, **kwargs) end end @@ -70,8 +67,8 @@ def readlines(name, sep = $/, limit = nil, getline_args = EMPTY_HASH) alias_method :orig_write, :write # @!visibility private - def write(name, string, offset = nil, opt = EMPTY_HASH) - File.open(name, opt[:mode] || 'w') do |f| + def write(name, string, offset = nil, **kwargs) + File.open(name, kwargs[:mode] || 'w') do |f| f.seek(offset) if offset f.write(string) end