Brama (Brama v1.0.1)
View SourceBrama is a library for managing connections to external dependencies.
It provides features for:
- Connection monitoring
- Circuit breaking
- Self-healing
- Status notifications
Connection Management
Brama allows you to register connections to external services and track their status:
# Register a connection
Brama.register("payment_api")
# Check if a connection is available
Brama.available?("payment_api")
# Report success/failure
Brama.success("payment_api")
Brama.failure("payment_api", reason: "Timeout")
Circuit Breaking
Brama implements the circuit breaker pattern to prevent cascading failures:
# Circuit opens automatically after consecutive failures
Brama.failure("payment_api", reason: "Timeout") # After max_attempts, circuit opens
# Manual circuit control
Brama.open_circuit!("payment_api", reason: "Maintenance")
Brama.close_circuit!("payment_api")
Brama.reset_circuit!("payment_api")
Configuration
Brama supports both global and per-connection configuration:
# Update global settings
Brama.configure(max_attempts: 15, expiry: 120_000)
# Update specific connection
Brama.configure("payment_api", max_attempts: 5, expiry: 30_000)
# Register with progressive backoff
Brama.register("flaky_service",
expiry_strategy: :progressive,
initial_expiry: 10_000,
max_expiry: 300_000,
backoff_factor: 2.0
)
Event Subscription
Subscribe to events to get notified of state changes:
# Subscribe to all events for a specific connection
Brama.subscribe(connection: "payment_api")
# Subscribe to specific event types
Brama.subscribe(events: [:state_change, :failure])
# Subscribe with a filter function
Brama.subscribe(filter: fn event -> event.connection == "payment_api" end)
Summary
Functions
Checks if a connection is available (circuit is closed or half-open).
Manually closes the circuit for a connection.
Updates the configuration for a specific connection or globally.
Reports a failed connection attempt.
Manually opens the circuit for a connection.
Registers a new connection with Brama.
Resets the circuit for a connection (closes it and resets failure count).
Gets the current status of a connection.
Subscribes to connection events.
Reports a successful connection attempt.
Unregisters a connection from Brama.
Unsubscribes from connection events.
Functions
Checks if a connection is available (circuit is closed or half-open).
Parameters
identifier
: The connection identifieropts
: Options:scope
: Optional scope to match
Examples
iex> Brama.register("payment_api")
iex> Brama.available?("payment_api")
true
Manually closes the circuit for a connection.
Parameters
identifier
: The connection identifieropts
: Options:scope
: Optional scope to match
Examples
iex> Brama.register("payment_api")
iex> Brama.close_circuit!("payment_api")
:ok
Updates the configuration for a specific connection or globally.
Parameters
identifier
- Optional connection identifier. If not provided, updates global settingsopts
- Configuration options to update::max_attempts
- Maximum number of failures before opening circuit:expiry
- Time in milliseconds before open circuit transitions to half-open:expiry_strategy
- Either:fixed
or:progressive
for backoff:initial_expiry
- Initial expiry time for progressive backoff:max_expiry
- Maximum expiry time for progressive backoff:backoff_factor
- Factor for exponential backoff
Examples
# Update global settings
Brama.configure(max_attempts: 15, expiry: 120_000)
# Update specific connection
Brama.configure("payment_api", max_attempts: 5, expiry: 30_000)
# Configure progressive backoff
Brama.configure("flaky_service",
expiry_strategy: :progressive,
initial_expiry: 10_000,
max_expiry: 300_000,
backoff_factor: 2.0
)
Reports a failed connection attempt.
Parameters
identifier
: The connection identifieropts
: Options:scope
: Optional scope to match:reason
: Reason for the failure:metadata
: Additional metadata about the failure
Examples
iex> Brama.register("payment_api")
iex> Brama.failure("payment_api", reason: "Timeout")
:ok
Manually opens the circuit for a connection.
Parameters
identifier
: The connection identifieropts
: Options:scope
: Optional scope to match:reason
: Reason for opening the circuit:expiry
: Custom expiry time in milliseconds
Examples
iex> Brama.register("payment_api")
iex> Brama.open_circuit!("payment_api", reason: "Maintenance")
:ok
Registers a new connection with Brama.
Parameters
identifier
: A unique identifier for the connectionopts
: Options for the connection:scope
: Optional scope for grouping connections:max_attempts
: Maximum number of failures before opening the circuit (default: 5):expiry
: Time in milliseconds after which an open circuit transitions to half-open (default: 60000):metadata
: Additional metadata to store with the connection
Examples
iex> {:ok, result} = Brama.register("payment_api")
iex> Map.take(result, [:identifier, :state, :failure_count])
%{identifier: "payment_api", state: :closed, failure_count: 0}
iex> {:ok, result} = Brama.register("invoice_api", scope: "billing", max_attempts: 5)
iex> Map.take(result, [:identifier, :scope, :state, :failure_count])
%{identifier: "invoice_api", scope: "billing", state: :closed, failure_count: 0}
Resets the circuit for a connection (closes it and resets failure count).
Parameters
identifier
: The connection identifieropts
: Options:scope
: Optional scope to match
Examples
iex> Brama.register("payment_api")
iex> Brama.reset_circuit!("payment_api")
:ok
Gets the current status of a connection.
Parameters
identifier
: The connection identifieropts
: Options:scope
: Optional scope to match
Examples
iex> Brama.register("payment_api")
iex> {:ok, result} = Brama.status("payment_api")
iex> Map.take(result, [:state, :failure_count])
%{state: :closed, failure_count: 0}
Subscribes to connection events.
Parameters
opts
: Subscription options (at least one must be provided):connection
: Filter events by connection identifier:scope
: Filter events by connection scope:events
: List of event types to subscribe to:filter
: Custom filter function
Examples
iex> Brama.subscribe(events: [:state_change])
{:ok, pid}
Reports a successful connection attempt.
Parameters
identifier
: The connection identifieropts
: Options:scope
: Optional scope to match:metadata
: Additional metadata about the success
Examples
iex> Brama.register("payment_api")
iex> Brama.success("payment_api")
:ok
Unregisters a connection from Brama.
Parameters
identifier
: The connection identifieropts
: Options:scope
: Optional scope to match
Examples
iex> Brama.register("payment_api")
iex> Brama.unregister("payment_api")
:ok
Unsubscribes from connection events.
Parameters
subscription_id
: The subscription ID returned from subscribe/1
Examples
iex> {:ok, subscription} = Brama.subscribe(events: [:state_change])
iex> Brama.unsubscribe(subscription)
:ok