class PG::Pool
Connections shared by many tasks, on any worker. An idle connection is
kept as a PG::Lease (its socket and its session's state, Shareable);
a task that needs one takes a lease and makes a PG::Connection of it
in its own task, and gives it back when done.
PG::Pool.open("postgres://app@localhost/shop", size: 8) do |pool|
Task.scope do |s|
8.times { |i| s.spawn { pool.query("SELECT $1::int", [i]) } }
end
pool.transaction { |c| c.exec("UPDATE stock SET n = n - 1") }
end
The rules:
- Connections are opened when needed, up to
size. A call waits for a free one at mostcheckout_timeoutwhen it is given (then it raisesPG::PoolTimeout); the work itself is not bounded by it. - The work runs in the caller's task, and its exceptions are the caller's. When it returns, the connection goes back to the pool if it is idle (a transaction the work left open is rolled back first); otherwise (broken, or a call cut short by cancellation or a timeout) it is closed, and the pool opens another when one is needed.
- A connection given back stops listening (
UNLISTEN *, whenPG::Connection#listening?), and the notifications it received are dropped: a listener uses a connection of its own (PG.connect). #close, or the end of.open's block, closes the idle connections and those given back later; calls waiting for one raisePG::ConnectionError("pool closed").
Class methods
def self.new(url: String, size: Int = …, checkout_timeout: Duration? = …) -> PG::Pool
A pool of up to size connections to the server url names (see
PG.connect); close it with #close. .open closes it for you.
def self.new(config: PG::Config, size: Int = …, checkout_timeout: Duration? = …) -> PG::Pool
As .new(url), with a PG::Config.
def self.open[R](url: String, size: Int = …, checkout_timeout: Duration? = …, &: (PG::Pool) -> R) -> R
Runs the block with a new pool (see .new), and closes the pool when
the block ends. Returns the block's value.
Methods
def with[R](&: (PG::Connection) -> R) -> R
Runs the block with a connection of the pool, in the calling task, and
returns its value (see the class's rules). The connection is the
pool's: a block that calls its PG::Connection#release takes it out
of the pool.
def exec(sql: String) -> PG::Result
PG::Connection#exec on a connection of the pool.
def query(sql: String, params: Array[Object?] = …) -> PG::Result
PG::Connection#query on a connection of the pool.
def transaction[R](&: (PG::Connection) -> R) -> R
PG::Connection#transaction on a connection of the pool.
def size -> Int
How many connections are open, idle or in use.
def closed? -> Bool
Whether #close was called.
def close -> Void
Closes the idle connections now, and the others when they are given
back; later calls raise PG::ConnectionError. Closing again does
nothing.