Class: ConnectionPool::TimedStack
- Inherits:
-
Object
- Object
- ConnectionPool::TimedStack
- Defined in:
- lib/connection_pool/timed_stack.rb
Overview
The TimedStack manages a pool of homogeneous connections (or any resource you wish to manage). Connections are created lazily up to a given maximum number.
Examples:
ts = TimedStack.new(size: 1) { MyConnection.new }
# fetch a connection
conn = ts.pop
# return a connection
ts.push conn
conn = ts.pop
ts.pop timeout: 5
#=> raises ConnectionPool::TimeoutError after 5 seconds
Instance Attribute Summary collapse
-
#max ⇒ Object
readonly
Returns the value of attribute max.
Instance Method Summary collapse
-
#decrement_created ⇒ Object
Reduce the created count.
-
#empty? ⇒ Boolean
Returns
trueif there are no available connections. -
#idle ⇒ Object
The number of connections created and available on the stack.
-
#initialize(size: 0, &block) ⇒ TimedStack
constructor
Creates a new pool with
sizeconnections that are created from the givenblock. -
#length ⇒ Object
The number of connections available on the stack.
-
#pop(timeout: 0.5, exception: ConnectionPool::TimeoutError) ⇒ Object
Retrieves a connection from the stack.
-
#push(obj) ⇒ Object
(also: #<<)
Returns
objto the stack. -
#reap(idle_seconds:) ⇒ Object
Reaps connections that were checked in more than
idle_secondsago. -
#shutdown(reload: false, &block) ⇒ Object
Shuts down the TimedStack by passing each connection to
blockand then removing it from the pool.
Constructor Details
#initialize(size: 0, &block) ⇒ TimedStack
Creates a new pool with size connections that are created from the given block.
25 26 27 28 29 30 31 32 33 |
# File 'lib/connection_pool/timed_stack.rb', line 25 def initialize(size: 0, &block) @create_block = block @created = 0 @que = [] @max = size @mutex = Thread::Mutex.new @resource = Thread::ConditionVariable.new @shutdown_block = nil end |
Instance Attribute Details
#max ⇒ Object (readonly)
Returns the value of attribute max.
20 21 22 |
# File 'lib/connection_pool/timed_stack.rb', line 20 def max @max end |
Instance Method Details
#decrement_created ⇒ Object
Reduce the created count
143 144 145 |
# File 'lib/connection_pool/timed_stack.rb', line 143 def decrement_created @created -= 1 unless @created == 0 end |
#empty? ⇒ Boolean
Returns true if there are no available connections.
125 126 127 |
# File 'lib/connection_pool/timed_stack.rb', line 125 def empty? (@created - @que.length) >= @max end |
#idle ⇒ Object
The number of connections created and available on the stack.
137 138 139 |
# File 'lib/connection_pool/timed_stack.rb', line 137 def idle @que.length end |
#length ⇒ Object
The number of connections available on the stack.
131 132 133 |
# File 'lib/connection_pool/timed_stack.rb', line 131 def length @max - @created + @que.length end |
#pop(timeout: 0.5, exception: ConnectionPool::TimeoutError) ⇒ Object
Retrieves a connection from the stack. If a connection is available it is immediately returned. If no connection is available within the given timeout a ConnectionPool::TimeoutError is raised.
Other options may be used by subclasses that extend TimedStack.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/connection_pool/timed_stack.rb', line 62 def pop(timeout: 0.5, exception: ConnectionPool::TimeoutError, **) deadline = current_time + timeout @mutex.synchronize do loop do raise ConnectionPool::PoolShuttingDownError if @shutdown_block if (conn = try_fetch_connection(**)) return conn end connection = try_create(**) return connection if connection to_wait = deadline - current_time if to_wait <= 0 if exception raise exception, "Waited #{timeout} sec, #{length}/#{@max} available" else return nil end end @resource.wait(@mutex, to_wait) end end end |
#push(obj) ⇒ Object Also known as: <<
Returns obj to the stack. Additional kwargs are ignored in TimedStack but may be used by subclasses that extend TimedStack.
38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/connection_pool/timed_stack.rb', line 38 def push(obj, **) @mutex.synchronize do if @shutdown_block @created -= 1 unless @created == 0 @shutdown_block.call(obj) else store_connection obj, ** end @resource.broadcast end end |
#reap(idle_seconds:) ⇒ Object
Reaps connections that were checked in more than idle_seconds ago.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/connection_pool/timed_stack.rb', line 106 def reap(idle_seconds:) raise ArgumentError, "reap must receive a block" unless block_given? raise ArgumentError, "idle_seconds must be a number" unless idle_seconds.is_a?(Numeric) raise ConnectionPool::PoolShuttingDownError if @shutdown_block count = idle count.times do conn = @mutex.synchronize do raise ConnectionPool::PoolShuttingDownError if @shutdown_block reserve_idle_connection(idle_seconds) end break unless conn yield conn end end |
#shutdown(reload: false, &block) ⇒ Object
Shuts down the TimedStack by passing each connection to block and then removing it from the pool. Attempting to checkout a connection after shutdown will raise ConnectionPool::PoolShuttingDownError unless :reload is true.
92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/connection_pool/timed_stack.rb', line 92 def shutdown(reload: false, &block) raise ArgumentError, "shutdown must receive a block" unless block @mutex.synchronize do @shutdown_block = block @resource.broadcast shutdown_connections @shutdown_block = nil if reload end end |