Ecto v1.1.0 Ecto.Pool behaviour

Behaviour for using a pool of connections.

Summary

Types

The depth of nested transactions

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

Opaque connection reference

t()

A pool process

Functions

Breaks the active connection

Triggers a rollback that is handled by with_rollback/2

Runs a fun using a connection from a pool

Carries out a transaction using a connection from a pool

Executes the given function giving it the ability to rollback

Callbacks

Break the current transaction or run

Checkin a worker/connection to the pool

Checkout a worker/connection from the pool

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

Open a transaction with a connection from the pool

Start a pool of connections

Types

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.

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

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)
rollback(pool_mod, pool, value)

Triggers a rollback that is handled by with_rollback/2.

Raises if outside a transaction.

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)
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)
with_rollback(atom, ref, fun)

Specs

with_rollback(:opened | :already_open, 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.

Callbacks

break(t, worker, timeout)

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.

checkin(t, worker, timeout)

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.

checkout(t, timeout)

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.

close_transaction(t, worker, timeout)

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.

open_transaction(t, timeout)

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.

start_link(module, opts)

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
  • :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.