diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml new file mode 100644 index 0000000..ea11ed2 --- /dev/null +++ b/.github/workflows/development.yml @@ -0,0 +1,51 @@ +name: Development + +on: [push, pull_request] + +jobs: + test: + runs-on: ${{matrix.os}}-latest + continue-on-error: ${{matrix.experimental}} + + strategy: + matrix: + os: + - ubuntu + - macos + + ruby: + - 2.5 + - 2.6 + - 2.7 + + experimental: [false] + env: [""] + + include: + - os: ubuntu + ruby: truffleruby + experimental: true + env: JRUBY_OPTS="--debug -X+O" + - os: ubuntu + ruby: jruby + experimental: true + - os: ubuntu + ruby: head + experimental: true + - os: ubuntu + ruby: 2.6 + experimental: false + env: COVERAGE=PartialSummary,Coveralls + + steps: + - uses: actions/checkout@v1 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{matrix.ruby}} + + - name: Install dependencies + run: ${{matrix.env}} bundle install + + - name: Run tests + timeout-minutes: 5 + run: ${{matrix.env}} bundle exec rspec diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ed343cd..0000000 --- a/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -language: ruby -dist: xenial -cache: bundler - -matrix: - include: - - rvm: 2.3 - - rvm: 2.4 - - rvm: 2.5 - - rvm: 2.6 - - rvm: 2.6 - env: COVERAGE=BriefSummary,Coveralls - - rvm: ruby-head - - rvm: truffleruby - - rvm: jruby-head - env: JRUBY_OPTS="--debug -X+O" - allow_failures: - - rvm: ruby-head - - rvm: truffleruby - - rvm: jruby-head diff --git a/Gemfile b/Gemfile index fa75df1..e8a2d78 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,5 @@ source 'https://rubygems.org' gemspec + +# gem "async", path: "../async" diff --git a/README.md b/README.md index ae6aae1..b13de8d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Provides support for connection pooling both singleplex and multiplex resources. -[![Build Status](https://travis-ci.com/socketry/async-pool.svg)](https://travis-ci.com/socketry/async-pool) +[![Actions Status](https://github.com/socketry/async-pool/workflows/Development/badge.svg)](https://github.com/socketry/async-pool/actions?workflow=Development) ## Installation diff --git a/Rakefile b/Rakefile deleted file mode 100644 index a1d8b92..0000000 --- a/Rakefile +++ /dev/null @@ -1,6 +0,0 @@ -require "bundler/gem_tasks" -require "rspec/core/rake_task" - -RSpec::Core::RakeTask.new - -task :default => :spec diff --git a/async-pool.gemspec b/async-pool.gemspec index 07e934a..7cd79f6 100644 --- a/async-pool.gemspec +++ b/async-pool.gemspec @@ -17,12 +17,12 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - spec.add_dependency("async", "~> 1.8") + spec.add_dependency("async", "~> 1.25") spec.add_development_dependency "async-rspec", "~> 1.1" spec.add_development_dependency "covered" spec.add_development_dependency "bundler" spec.add_development_dependency "rspec", "~> 3.6" - spec.add_development_dependency "rake" + spec.add_development_dependency "bake-bundler" end diff --git a/lib/async/pool/controller.rb b/lib/async/pool/controller.rb index 40fc03e..aaf9d6e 100644 --- a/lib/async/pool/controller.rb +++ b/lib/async/pool/controller.rb @@ -40,6 +40,8 @@ def initialize(constructor, limit: nil) @constructor = constructor @guard = Async::Semaphore.new(1) + + @gardener = nil end # @attr [Hash] all allocated resources, and their associated usage. @@ -97,6 +99,8 @@ def release(resource) def close @resources.each_key(&:close) @resources.clear + + @gardener&.stop end def to_s @@ -142,6 +146,19 @@ def retire(resource) protected + def start_gardener + return if @gardener + + Async(transient: true) do |task| + @gardener = task + + Task.yield + ensure + @gardener = nil + self.close + end + end + def usage_string "#{@resources.size}/#{@limit || '∞'}" end @@ -177,6 +194,8 @@ def wait_for_resource end def create_resource + self.start_gardener + # This might return nil, which means creating the resource failed. if resource = @constructor.call @resources[resource] = 1 diff --git a/lib/async/pool/version.rb b/lib/async/pool/version.rb index dcc64c9..0afb285 100644 --- a/lib/async/pool/version.rb +++ b/lib/async/pool/version.rb @@ -20,6 +20,6 @@ module Async module Pool - VERSION = "0.2.0" + VERSION = "0.3.0" end end diff --git a/spec/async/pool/controller_spec.rb b/spec/async/pool/controller_spec.rb index 84c4a95..7657e26 100644 --- a/spec/async/pool/controller_spec.rb +++ b/spec/async/pool/controller_spec.rb @@ -131,3 +131,22 @@ end end end + +RSpec.describe Async::Pool::Controller, timeout: 1 do + subject {described_class.new(Async::Pool::Resource)} + + describe '#close' do + it "closes all resources when going out of scope" do + Async do + object = subject.acquire + expect(object).to_not be_nil + subject.release(object) + + # There is some resource which is still open: + expect(subject.resources).to_not be_empty + end + + expect(subject.resources).to be_empty + end + end +end