Pristine.Ports.Semaphore behaviour (Pristine v0.3.0)

Copy Markdown View Source

Port for connection/concurrency limiting via semaphores.

This port provides connection limiting capabilities to prevent resource exhaustion when making many concurrent requests.

Use Cases

  • Limiting concurrent HTTP connections to a specific host
  • Preventing thread pool exhaustion in async operations
  • Implementing backpressure in high-throughput systems

Summary

Callbacks

Attempt to acquire a permit from the semaphore.

Acquire a permit with backoff using a registry-backed semaphore.

Get the number of available permits.

Initialize a named semaphore with a given limit.

Release a previously acquired permit back to the semaphore.

Release a permit for a registry-backed semaphore.

Execute a function while holding a semaphore permit.

Callbacks

acquire(name, timeout)

(optional)
@callback acquire(name :: term(), timeout :: timeout()) :: :ok | {:error, :timeout}

Attempt to acquire a permit from the semaphore.

Returns :ok if a permit was acquired, or {:error, :timeout} if the permit could not be acquired within the timeout.

acquire_blocking(registry, name, max, backoff, opts)

(optional)
@callback acquire_blocking(
  registry :: term(),
  name :: term(),
  max :: pos_integer(),
  backoff :: term(),
  opts :: keyword()
) :: :ok

Acquire a permit with backoff using a registry-backed semaphore.

available(name)

(optional)
@callback available(name :: term()) :: non_neg_integer()

Get the number of available permits.

init(name, limit)

(optional)
@callback init(name :: term(), limit :: pos_integer()) :: :ok

Initialize a named semaphore with a given limit.

The limit specifies the maximum number of concurrent permits that can be held at any given time.

release(name)

(optional)
@callback release(name :: term()) :: :ok

Release a previously acquired permit back to the semaphore.

release(registry, name)

(optional)
@callback release(registry :: term(), name :: term()) :: :ok

Release a permit for a registry-backed semaphore.

with_permit(name, timeout, function)

@callback with_permit(name :: term(), timeout :: timeout(), (-> result)) ::
  result | {:error, :timeout}
when result: term()

Execute a function while holding a semaphore permit.

Acquires a permit before executing the function and releases it after the function completes (even if it raises an exception).

Returns {:error, :timeout} if the permit cannot be acquired within the specified timeout.

Parameters

  • name - The semaphore name/identifier
  • timeout - Maximum time in milliseconds to wait for a permit, or :infinity to wait forever
  • fun - The zero-arity function to execute