Ecto.Pool behaviour

Behaviour for using a pool of connections.

Source

Summary

break(ref, timeout)

Breaks the active connection

rollback(pool_mod, pool, value)

Triggers a rollback that is handled by with_rollback/2

run(pool_mod, pool, timeout, fun)

Runs a fun using a connection from a pool

transaction(pool_mod, pool, timeout, fun)

Carries out a transaction using a connection from a pool

with_rollback(ref, fun)

Executes the given function giving it the ability to rollback

Types

ref

Opaque connection reference.

Use inside run/4 and transaction/4 to retrieve the connection module and pid or break the transaction.

t :: atom | pid

A pool process

depth :: non_neg_integer

The depth of nested transactions.

queue_time :: non_neg_integer

The time in microseconds spent waiting for a connection from the pool.

Functions

break(ref, timeout)

Specs:

  • break(ref, timeout) :: :ok

Breaks the active connection.

Any attempt to use it inside the same transaction Calling run/1 inside the same transaction or run (at any depth) will return {:error, :noconnect}.

Examples

Pool.transaction(mod, pool, timout,
  fn(:opened, ref, conn, _queue_time) ->
    :ok = Pool.break(ref, timeout)
    {:error, :noconnect} = Pool.run(mod, pool, timeout, fn _, _ -> end)
  end)
Source
rollback(pool_mod, pool, value)

Triggers a rollback that is handled by with_rollback/2.

Raises if outside a transaction.

Source
run(pool_mod, pool, timeout, fun)

Specs:

  • run(module, t, timeout, (conn, queue_time | nil -> result)) :: {:ok, result} | {:error, :noproc | :noconnect} when conn: {module, pid}, result: var

Runs a fun using a connection from a pool.

The connection will be taken from the pool unless we are inside a transaction/4 which, in this case, would already have a conn attached to it.

Returns the value returned by the function wrapped in a tuple as {:ok, value}.

Returns {:error, :noproc} if the pool is not alive or {:error, :noconnect} if no connection is available.

Examples

Pool.run(mod, pool, timeout,
  fn(_conn, queue_time) -> queue_time end)

Pool.transaction(mod, pool, timeout,
  fn(:opened, _ref, _conn, _queue_time) ->
    {:ok, :nested} =
      Pool.run(mod, pool, timeout, fn(_conn, nil) ->
        :nested
      end)
  end)
Source
transaction(pool_mod, pool, timeout, fun)

Specs:

  • transaction(module, t, timeout, fun) :: value | {:error, :noproc} | {:error, :noconnect} | no_return when fun: (:opened | :already_open, ref, conn, queue_time | nil -> value), conn: {module, pid}, value: var

Carries out a transaction using a connection from a pool.

Once a transaction is opened, all following calls to run/4 or transaction/4 will use the same connection/worker. If break/2 is invoked, all operations will return {:error, :noconnect} until the end of the top level transaction.

Nested calls to pool transaction will “flatten out” transactions. This means nested calls are mostly no-op and just execute the given function passing :already_opened as first argument. If there is any failure in a nested transaction, the whole transaction is marked as tainted, ensuring the outer most call fails.

Returns {:error, :noproc} if the pool is not alive, {:error, :noconnect} if no connection is available. Otherwise just returns the given function value without wrapping.

Examples

Pool.transaction(mod, pool, timeout,
  fn(:opened, _ref, _conn, queue_time) -> queue_time end)

Pool.transaction(mod, pool, timeout,
  fn(:opened, ref, _conn, _queue_time) ->
    :nested =
      Pool.transaction(mod, pool, timeout, fn(:already_opened, _ref, _conn, nil) ->
        :nested
      end)
  end)

Pool.transaction(mod, :pool1, timeout,
  fn(:opened, _ref1, _conn1, _queue_time1) ->
    :different_pool =
      Pool.transaction(mod, :pool2, timeout,
        fn(:opened, _ref2, _conn2, _queue_time2) -> :different_pool end)
  end)
Source
with_rollback(ref, fun)

Specs:

  • with_rollback(ref, (() -> return)) :: {:ok, return} | {:error, term} | {:raise, atom, term, Exception.stacktrace} when return: var

Executes the given function giving it the ability to rollback.

Returns {:ok, value} if no transaction ocurred, {:error, value} if the user rolled back or {:raise, kind, error, stack} in case there was a failure.

Source

Callbacks

break/3

Specs:

  • break(t, worker, timeout) :: :ok when worker: any

Break the current transaction or run.

Called when the function has failed and the connection should no longer be available to to the calling process.

Source
checkin/3

Specs:

  • checkin(t, worker, timeout) :: :ok when worker: any

Checkin a worker/connection to the pool.

Called when the top level run/4 finishes, if break/2 was not called inside the fun.

Source
checkout/2

Specs:

  • checkout(t, timeout) :: {:ok, worker, conn, queue_time} | {:error, :noproc | :noconnect} when worker: any, conn: {module, pid}

Checkout a worker/connection from the pool.

The connection should not be closed if the calling process exits without returning the connection.

Returns {:ok, worker, conn, queue_time} on success, where worker is the worker term and conn is a 2-tuple contain the connection’s module and pid. The conn tuple can be retrieved inside a transaction/4 with connection/1.

Returns {:error, :noproc} if the pool is not alive and {:error, :noconnect} if a connection is not available.

Source
close_transaction/3

Specs:

  • close_transaction(t, worker, timeout) :: :ok when worker: any

Close the transaction and signal to the worker the work with the connection is complete.

Called once the transaction at depth 1 is finished, if the transaction is not broken with break/2.

Source
open_transaction/2

Specs:

  • open_transaction(t, timeout) :: {:ok, worker, conn, queue_time} | {:error, :noproc | :noconnect} when worker: any, conn: {module, pid}

Open a transaction with a connection from the pool.

The connection should be closed if the calling process exits without returning the connection.

Returns {:ok, worker, conn, queue_time} on success, where worker is the worker term and conn is a 2-tuple contain the connection’s module and pid. The conn tuple can be retrieved inside a transaction/4 with connection/2.

Returns {:error, :noproc} if the pool is not alive and {:error, :noconnect} if a connection is not available.

Source
start_link/2

Specs:

  • start_link(module, opts) :: {:ok, pid} | {:error, any} when opts: Keyword.t

Start a pool of connections.

module is the connection module, which should define the Ecto.Adapters.Connection callbacks, and opts are its (and the pool’s) options.

A pool should support the following options:

  • :name - The name of the pool
  • :size - The number of connections to keep in the pool

Returns {:ok, pid} on starting the pool.

Returns {:error, reason} if the pool could not be started. If the reason is {:already_started, pid}}` a pool with the same name has already been started.

Source