diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 21a705e3..1916b020 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0-alpha.48" + ".": "0.1.0-alpha.49" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 62c5ffe9..968ead49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.1.0-alpha.49 (2025-09-30) + +Full Changelog: [v0.1.0-alpha.48...v0.1.0-alpha.49](https://github.com/lithic-com/lithic-ruby/compare/v0.1.0-alpha.48...v0.1.0-alpha.49) + +### Bug Fixes + +* coroutine leaks from connection pool ([fa96625](https://github.com/lithic-com/lithic-ruby/commit/fa96625074db9b9d8f6ef6dc5a14c45b6faa42a3)) + ## 0.1.0-alpha.48 (2025-09-30) Full Changelog: [v0.1.0-alpha.47...v0.1.0-alpha.48](https://github.com/lithic-com/lithic-ruby/compare/v0.1.0-alpha.47...v0.1.0-alpha.48) diff --git a/Gemfile.lock b/Gemfile.lock index 142a5a91..92ff86a5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ GIT PATH remote: . specs: - lithic (0.1.0.pre.alpha.48) + lithic (0.1.0.pre.alpha.49) connection_pool GEM diff --git a/README.md b/README.md index c8848823..f7144a7c 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ To use this gem, install via Bundler by adding the following to your application ```ruby -gem "lithic", "~> 0.1.0.pre.alpha.48" +gem "lithic", "~> 0.1.0.pre.alpha.49" ``` diff --git a/lib/lithic/internal/transport/pooled_net_requester.rb b/lib/lithic/internal/transport/pooled_net_requester.rb index 9b2eda53..40f39231 100644 --- a/lib/lithic/internal/transport/pooled_net_requester.rb +++ b/lib/lithic/internal/transport/pooled_net_requester.rb @@ -134,9 +134,9 @@ def execute(request) # rubocop:disable Metrics/BlockLength enum = Enumerator.new do |y| - with_pool(url, deadline: deadline) do |conn| - next if finished + next if finished + with_pool(url, deadline: deadline) do |conn| req, closing = self.class.build_request(request) do self.class.calibrate_socket_timeout(conn, deadline) end @@ -149,7 +149,7 @@ def execute(request) self.class.calibrate_socket_timeout(conn, deadline) conn.request(req) do |rsp| - y << [conn, req, rsp] + y << [req, rsp] break if finished rsp.read_body do |bytes| @@ -160,6 +160,8 @@ def execute(request) end eof = true end + ensure + conn.finish if !eof && conn&.started? end rescue Timeout::Error raise Lithic::Errors::APITimeoutError.new(url: url, request: req) @@ -168,16 +170,11 @@ def execute(request) end # rubocop:enable Metrics/BlockLength - conn, _, response = enum.next + _, response = enum.next body = Lithic::Internal::Util.fused_enum(enum, external: true) do finished = true - tap do - enum.next - rescue StopIteration - nil - end + loop { enum.next } ensure - conn.finish if !eof && conn&.started? closing&.call end [Integer(response.code), response, body] diff --git a/lib/lithic/version.rb b/lib/lithic/version.rb index 32a19c3a..dd94a35d 100644 --- a/lib/lithic/version.rb +++ b/lib/lithic/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Lithic - VERSION = "0.1.0.pre.alpha.48" + VERSION = "0.1.0.pre.alpha.49" end diff --git a/test/lithic/internal/util_test.rb b/test/lithic/internal/util_test.rb index 82e590ce..4d449f7e 100644 --- a/test/lithic/internal/util_test.rb +++ b/test/lithic/internal/util_test.rb @@ -310,6 +310,31 @@ def test_copy_write end class Lithic::Test::UtilFusedEnumTest < Minitest::Test + def test_rewind_closing + touched = false + once = 0 + steps = 0 + enum = Enumerator.new do |y| + next if touched + + 10.times do + steps = _1 + y << _1 + end + ensure + once = once.succ + end + + fused = Lithic::Internal::Util.fused_enum(enum, external: true) do + touched = true + loop { enum.next } + end + Lithic::Internal::Util.close_fused!(fused) + + assert_equal(1, once) + assert_equal(0, steps) + end + def test_closing arr = [1, 2, 3] once = 0