kura_pool_minato (kura_postgres v1.0.2)
View Sourcekura_pool implementation over minato.
minato hands a connection to the process that borrows it: the socket belongs to
that process, and a query returns the connection to carry on from rather than
mutating one in place. kura_pool is the other shape - an opaque handle that
several processes may use and that outlives the call that made it, which is what
kura_sandbox needs when it checks a connection out in one process and runs the
test in another.
A checkout therefore spawns a holder: a process that borrows the connection,
owns the socket for as long as the checkout lasts, and answers run/4. The
handle is that process. Nothing on the ordinary query path goes through it -
kura_driver_minato:query/5 borrows and returns a connection inside one call -
so the holder is only paid for by callers who asked for a connection to keep.
The holder watches whoever owns the checkout and gives the connection back if
that process dies, so a test that crashes returns its connection instead of
taking it out of the pool. give_away/3 moves the watch rather than the socket,
because the socket never left the holder.
Summary
Functions
What this backend supports. Read by kura_capabilities.
Give a borrowed connection back.
Borrow a connection and keep it until checkin/2.
Hand the checkout to another process.
Note that this process is inside a transaction on Pool, held by Holder.
Run a statement on a held connection. Used by kura_driver_minato.
Start a pool.
Stop a pool. A pool that is not running is not an error.
The holder of the transaction this process is inside, or undefined.
Functions
-spec capabilities() -> kura_capabilities:capability_set().
What this backend supports. Read by kura_capabilities.
-spec checkin(kura_pool:name(), kura_pool:token()) -> ok.
Give a borrowed connection back.
-spec checkout(kura_pool:name(), kura_pool:checkout_opts()) -> {ok, kura_pool:conn(), kura_pool:token()} | {error, term()}.
Borrow a connection and keep it until checkin/2.
The handle is the holder process, and the token is what gives it back.
-spec give_away(kura_pool:token(), pid(), term()) -> ok | {error, term()}.
Hand the checkout to another process.
Only the watch moves: the socket belongs to the holder and stays there, so
nothing about the connection changes. The new owner is now the one whose death
returns the connection, and it is the one that should call checkin/2.
-spec in_transaction(kura_pool:name(), pid() | undefined) -> ok.
Note that this process is inside a transaction on Pool, held by Holder.
undefined clears it. Kept in the process dictionary because that is what makes
a query written inside the transaction function find the transaction's
connection without being handed one.
Run a statement on a held connection. Used by kura_driver_minato.
-spec start_pool(kura_pool:name(), kura_pool:opts()) -> {ok, pid()} | {error, term()}.
Start a pool.
The minato application is started if it is not already, because a repo starting its pool has not necessarily been told that it has to start something else first, and a pool that cannot start for that reason is a confusing way to find out.
kura's options are translated to minato's: pool_size becomes size, and the
connection settings are gathered under connection. host, user, password
and database are accepted as strings or binaries, because kura configuration
in the wild is written both ways.
-spec stop_pool(kura_pool:name()) -> ok.
Stop a pool. A pool that is not running is not an error.
-spec transaction_conn(kura_pool:name()) -> pid() | undefined.
The holder of the transaction this process is inside, or undefined.