View Source ExSleeplock (ex_sleeplock v0.10.0)

API allowing creation of locks to throttle concurrent processing via obtaining a lock before executing functionality you want to limit.

Before a lock can be used it must be created using new/2. When new/2 is called a process is created to manage the lock. The lock is identified by a unique atom and the number of slots indicates how many processes can hold the lock at once. The name of the lock is the process name.

The preferred way to use a created lock is with the function execute/2. This function acquires the lock, executes the function passed in and then releases the lock (returning the function return value to the caller) This ensures that the lock is always released even if an exception is raised.

Summary

Types

General information about a lock

Number of processes that have obtained the lock and are currently running and the number of processes waiting for a lock

Functions

Aquire a lock

A non-blocking version of acquire/1

Execute the function passed in by first acquiring the lock

Return help message

Return lock's current state

Create a lock

Release an acquired lock

Types

@type lock_info() :: %{name: atom(), num_slots: pos_integer()}

General information about a lock

@type lock_state() :: %{running: non_neg_integer(), waiting: non_neg_integer()}

Number of processes that have obtained the lock and are currently running and the number of processes waiting for a lock

Functions

@spec acquire(atom()) :: :ok | {:error, :lock_not_found}

Aquire a lock

This will block until a lock can be acquired. When a lock is acquired the caller is responsible for calling release/1.

Arguments

  • name - a unique atom identifying the lock

Returns

  • :ok - after lock is acquired
  • {:error, :lock_not_found} - if called with a name that doesn't match an existing lock
@spec attempt(atom()) :: :ok | {:error, :unavailable} | {:error, :lock_not_found}

A non-blocking version of acquire/1

Arguments

  • name - a unique atom identifying the lock

Returns

  • :ok - lock is acquired
  • {:error, :unavailable} - lock is not acquired
  • {:error, :lock_not_found} - if called with a name that doesn't match an existing lock
@spec execute(atom(), (-> any())) :: any() | {:error, :lock_not_found}

Execute the function passed in by first acquiring the lock

The lock is automatically released when the function completes. This call blocks until a lock is acquired.

Arguments

  • name - a unique atom identifying the lock
  • fun - a function that executes after the lock is acquired

Returns

  • on success the call returns the value returned by the function supplied
  • {:error, :lock_not_found} - if called with a name that doesn't match an existing lock

Return help message

@spec lock_state(atom()) :: {:ok, lock_state()} | {:error, :lock_not_found}

Return lock's current state

@spec new(atom(), pos_integer()) ::
  {:ok, pid()}
  | {:error, :invalid, String.t()}
  | {:error, {:already_started, pid()}}

Create a lock

Arguments

  • name - a unique atom identifying the lock. The name becomes the process name for the lock
  • num_slots - a positive integer indicating how many processes are allowed to hold this lock at once

Returns

  • {:ok, pid} - on success a GenServer using the name supplied is started. This process is supervised by the library.
  • {:error, :invalid, msg} - returned when parameters are invalid
  • {:error, {:already_started, pid}} - returned when attempting to create the same lock more than once
@spec release(atom()) :: :ok | {:error, :lock_not_found}

Release an acquired lock

Arguments

  • name - a unique atom identifying the lock

Returns

  • :ok - always returned even if you do not have an acquired lock
  • {:error, :lock_not_found} - if called with a name that doesn't match an existing lock