Ecto.Adapters.Worker behaviour

Defines a worker to be used by adapters.

The worker is responsible for managing the connection to the database, automatically starting a new one if it crashes. The ask/2 and ask!/2 functions can be used any time to retrieve the connection and its module.

The worker also adds support for laziness, allowing developers to create workers but connect to the database only when needed for the first time. Finally, the worker also provides transaction semantics, with open/close commands as well as a sandbox mode.

In order to use a worker, adapter developers need to implement two callbacks in a module, connect/1 and disconnect/1 defined in this module. The worker is started by passing the module that implements the callbacks and as well as the connection arguments.

Transaction modes

The worker supports transactions. The idea is that, once a transaction is open, the worker is going to monitor the client and disconnect if the client crashes without properly closing the connection.

Most of the transaction functions are about telling the worker how to react on crashes, the client is still responsible for keeping the transaction state.

The worker also supports a sandbox transaction, which means transaction management is done on the client and opening a transaction is then disabled.

Finally, operations like break_transaction/2 can be used when something goes wrong, ensuring a disconnection happens.

Source

Summary

ask!(worker, timeout)

Asks for the module and the underlying connection process

ask(worker, timeout)

Asks for the module and the underlying connection process

break_transaction(worker, timeout)

Breaks a transaction

close_transaction(worker, timeout)

Closes a transaction

open_transaction(worker, timeout)

Opens a transaction

sandbox_transaction(worker, timeout)

Starts a sandbox transaction

start(arg1)

Starts a worker for the given module and params

start_link(arg1)

Starts a linked worker for the given module and params

Types

modconn :: {module :: atom, conn :: pid}

Functions

ask(worker, timeout)

Specs:

Asks for the module and the underlying connection process.

Source
ask!(worker, timeout)

Specs:

  • ask!(pid, timeout) :: modconn | no_return

Asks for the module and the underlying connection process.

Source
break_transaction(worker, timeout)

Specs:

  • break_transaction(pid, timeout) :: :broken | :not_open | :sandbox

Breaks a transaction.

Automatically forces the worker to disconnect unless in sandbox mode. Returns :not_open if a transaction was not open.

Source
close_transaction(worker, timeout)

Specs:

  • close_transaction(pid, timeout) :: :not_open | :closed

Closes a transaction.

Both sandbox and open transactions can be closed. Returns :not_open if a transaction was not open.

Source
open_transaction(worker, timeout)

Specs:

Opens a transaction.

Invoked when the client wants to open up a connection.

The worker process starts to monitor the caller and will wipeout all connection state in case of crashes.

It returns an :ok tuple if the transaction can be opened, a :sandbox tuple in case the transaction could not be openned because it is in sandbox mode or an :error tuple, usually when the adapter is unable to connect.

FAQ

Question: What happens if open_transaction/2 is called when a transaction is already open?

Answer: If a transaction is already open, the previous transaction along side its connection will be discarded and a new one will be started transparently. The reasoning is that if the client is calling open_transaction/2 when one is already open, is because the client lost its state, and we should treat it transparently by disconnecting the old state and starting a new one.

Source
sandbox_transaction(worker, timeout)

Specs:

  • sandbox_transaction(pid, timeout) :: {:ok, modconn} | {:sandbox, modconn} | :already_open

Starts a sandbox transaction.

A sandbox transaction is not monitored by the worker. This functions returns an :ok tuple in case a sandbox transaction has started, a :sandbox tuple if it was already in sandbox mode or :already_open if it was previously open.

Source
start(arg1)

Starts a worker for the given module and params.

Source
start_link(arg1)

Starts a linked worker for the given module and params.

Source

Callbacks

connect/1

Specs:

  • connect(Keyword.t) :: {:ok, pid} | {:error, term}

Connects to the underlying database.

Should return a process which is linked to the caller process or an error.

Source
disconnect/1

Specs:

  • disconnect(pid) :: :ok

Disconnects the given pid.

If the given pid no longer exists, it should not raise.

Source