View Source NimbleOwnership (NimbleOwnership v0.1.0)
Module that allows you to manage ownership of resources across processes.
The idea is that you can track ownership of terms (keys) across processes, and allow processes to use a key through processes that are already allowed.
flowchart LR
pidA["Process A"]
pidB["Process B"]
pidC["Process C"]
res(["Resource"])
pidA -->|Owns| res
pidA -->|Allows| pidB
pidB -->|Can access| res
pidB -->|Allows| pidC
pidC -->|Can access| res
A typical use case for such a module is tracking resource ownership across processes in order to isolate access to resources in test suites. For example, the Mox library uses this module to track ownership of mocks across processes (in shared mode).
Usage
To track ownership of resources, you need to start a NimbleOwnership
server (a process),
through start_link/1
or child_spec/1
.
Then, you can allow a process access to a key through allow/5
. You can then check
if a PID can access the given key through get_owner/3
.
Metadata
You can store arbitrary metadata (metadata/0
) alongside each "allowance", that is,
alongside the relationship between a process and a key. This metadata is returned
together with the owner PID when you call get_owner/3
.
Summary
Types
Arbitrary key.
Arbitrary metadata associated with an allowance.
Information about the owner of a key returned by get_owner/3
.
Ownership server.
Functions
Allows pid_to_allow
to use key
through owner_pid
(on the given ownership_server
).
Returns a specification to start this module under a supervisor.
Retrieves the first PID in callers
that is allowed to use key
(on
the given ownership_server
).
Starts an ownership server.
Types
@type key() :: term()
Arbitrary key.
@type metadata() :: term()
Arbitrary metadata associated with an allowance.
Information about the owner of a key returned by get_owner/3
.
@type server() :: GenServer.server()
Ownership server.
Functions
@spec allow(server(), pid(), pid() | (-> pid()), key(), metadata()) :: :ok | {:error, NimbleOwnership.Error.t()}
Allows pid_to_allow
to use key
through owner_pid
(on the given ownership_server
).
Use this function when owner_pid
is allowed access to key
, and you want
to also allow pid_to_allow
to use key
.
metadata
is an arbitrary term that you can use to store additional information
about the allowance. It is returned by get_owner/3
.
This function returns an error when pid_to_allow
is already allowed to use
key
via another owner PID that is not owner_pid
.
Examples
iex> pid = spawn(fn -> Process.sleep(:infinity) end)
iex> {:ok, server} = NimbleOwnership.start_link()
iex> NimbleOwnership.allow(server, self(), pid, :my_key, %{counter: 1})
:ok
iex> NimbleOwnership.get_owner(server, [pid], :my_key)
%{owner_pid: self(), metadata: %{counter: 1}}
Returns a specification to start this module under a supervisor.
See Supervisor
.
@spec get_owner(server(), [pid(), ...], key()) :: owner_info() | nil
Retrieves the first PID in callers
that is allowed to use key
(on
the given ownership_server
).
See allow/5
for examples.
@spec start_link(keyword()) :: GenServer.on_start()
Starts an ownership server.
Options
This function supports all the options supported by GenServer.start_link/3
, namely:
:name
:timeout
:debug
:spawn_opt
:hibernate_after