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.
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
Specs:
- ask(pid, timeout) :: {:ok, modconn} | {:error, Exception.t}
Asks for the module and the underlying connection process.
Specs:
- ask!(pid, timeout) :: modconn | no_return
Asks for the module and the underlying connection process.
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.
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.
Specs:
- open_transaction(pid, timeout) :: {:ok, modconn} | {:sandbox, modconn} | {:error, Exception.t}
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.
Specs:
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.
Starts a worker for the given module and params.
Starts a linked worker for the given module and params.
Callbacks
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.
Specs:
- disconnect(pid) :: :ok
Disconnects the given pid
.
If the given pid
no longer exists, it should not raise.