diff options
author | Thibaut Girka <thib@sitedethib.com> | 2019-07-04 16:21:39 +0200 |
---|---|---|
committer | Thibaut Girka <thib@sitedethib.com> | 2019-07-04 16:21:39 +0200 |
commit | 6ab84c12a7ebc68fb8ce9a6b8228b28ec06a2c0f (patch) | |
tree | 0f023e22bcb1ae01ce3fb4e43b771609493e4e65 /app/lib/connection_pool/shared_connection_pool.rb | |
parent | c94966891af1ff456c6382595c07c2d68c57ec49 (diff) | |
parent | 99924f282f53593e670c70a38450a1c0e2d24c20 (diff) |
Merge branch 'master' into glitch-soc/merge-upstream
Diffstat (limited to 'app/lib/connection_pool/shared_connection_pool.rb')
-rw-r--r-- | app/lib/connection_pool/shared_connection_pool.rb | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/app/lib/connection_pool/shared_connection_pool.rb b/app/lib/connection_pool/shared_connection_pool.rb new file mode 100644 index 000000000..2865a4108 --- /dev/null +++ b/app/lib/connection_pool/shared_connection_pool.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'connection_pool' +require_relative './shared_timed_stack' + +class ConnectionPool::SharedConnectionPool < ConnectionPool + def initialize(options = {}, &block) + super(options, &block) + + @available = ConnectionPool::SharedTimedStack.new(@size, &block) + end + + delegate :size, :flush, to: :@available + + def with(preferred_tag, options = {}) + Thread.handle_interrupt(Exception => :never) do + conn = checkout(preferred_tag, options) + + begin + Thread.handle_interrupt(Exception => :immediate) do + yield conn + end + ensure + checkin(preferred_tag) + end + end + end + + def checkout(preferred_tag, options = {}) + if ::Thread.current[key(preferred_tag)] + ::Thread.current[key_count(preferred_tag)] += 1 + ::Thread.current[key(preferred_tag)] + else + ::Thread.current[key_count(preferred_tag)] = 1 + ::Thread.current[key(preferred_tag)] = @available.pop(preferred_tag, options[:timeout] || @timeout) + end + end + + def checkin(preferred_tag) + if ::Thread.current[key(preferred_tag)] + if ::Thread.current[key_count(preferred_tag)] == 1 + @available.push(::Thread.current[key(preferred_tag)]) + ::Thread.current[key(preferred_tag)] = nil + else + ::Thread.current[key_count(preferred_tag)] -= 1 + end + else + raise ConnectionPool::Error, 'no connections are checked out' + end + + nil + end + + private + + def key(tag) + :"#{@key}-#{tag}" + end + + def key_count(tag) + :"#{@key_count}-#{tag}" + end +end |