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.

@type owner_info() :: %{metadata: metadata(), owner_pid: pid()}

Information about the owner of a key returned by get_owner/3.

@type server() :: GenServer.server()

Ownership server.

Functions

Link to this function

allow(ownership_server, owner_pid, pid_to_allow, key, metadata)

View Source
@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.

Link to this function

get_owner(ownership_server, callers, key)

View Source
@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.

Link to this function

start_link(options \\ [])

View Source
@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