Class: TriCoreDB::Pool
- Inherits:
-
Object
- Object
- TriCoreDB::Pool
- Defined in:
- lib/tricoredb/pool.rb
Overview
A thread-safe pool of connections.
A connection is lent to exactly one block at a time. Connections are
created lazily up to size.
A session transaction is bound to its connection, so a connection is never returned mid-transaction: a block that raises with one open has it rolled back, and a block that returns with one open has it rolled back and raises.
Instance Attribute Summary collapse
- #size ⇒ Integer readonly
Instance Method Summary collapse
-
#close ⇒ Object
Close idle connections and refuse further checkouts.
-
#initialize(size: 8, checkout_timeout: 10, **connect_options) ⇒ Pool
constructor
A new instance of Pool.
- #stats ⇒ Hash{Symbol => Integer}
-
#with(timeout: @checkout_timeout) {|db| ... } ⇒ Object
Borrow a connection for the duration of the block.
Constructor Details
#initialize(size: 8, checkout_timeout: 10, **connect_options) ⇒ Pool
Returns a new instance of Pool.
24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/tricoredb/pool.rb', line 24 def initialize(size: 8, checkout_timeout: 10, **) raise ArgumentError, "pool size must be >= 1" if size < 1 @size = size @checkout_timeout = checkout_timeout @connect_options = @idle = [] @created = 0 @waiting = 0 @closed = false @lock = Mutex.new @available = ConditionVariable.new end |
Instance Attribute Details
#size ⇒ Integer (readonly)
19 20 21 |
# File 'lib/tricoredb/pool.rb', line 19 def size @size end |
Instance Method Details
#close ⇒ Object
Close idle connections and refuse further checkouts. Connections in use are closed when they are returned.
80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/tricoredb/pool.rb', line 80 def close idle = @lock.synchronize do @closed = true @available.broadcast list = @idle.dup @idle.clear @created -= list.size list end idle.each(&:close) nil end |
#stats ⇒ Hash{Symbol => Integer}
72 73 74 75 76 |
# File 'lib/tricoredb/pool.rb', line 72 def stats @lock.synchronize do { size: @size, created: @created, idle: @idle.size, in_use: @created - @idle.size, waiting: @waiting } end end |
#with(timeout: @checkout_timeout) {|db| ... } ⇒ Object
Borrow a connection for the duration of the block.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/tricoredb/pool.rb', line 43 def with(timeout: @checkout_timeout) raise ArgumentError, "Pool#with needs a block" unless block_given? client = checkout(timeout) broken = false begin begin result = yield client rescue Exception => e # rubocop:disable Lint/RescueException if client.closed? || stream_broken?(e) broken = true elsif client.in_transaction? broken = !abandon_transaction(client) end raise end if client.in_transaction? broken = !abandon_transaction(client) raise Error, "the block returned with a session transaction still open on the pooled connection; it " \ "has been rolled back rather than returned to the pool. Commit or roll back inside the " \ "block, or use db.transaction { }" end result ensure checkin(client, broken) end end |