Spear.connect_to_persistent_subscription

You're seeing just the function connect_to_persistent_subscription, go back to Spear module for more information.
Link to this function

connect_to_persistent_subscription(conn, subscriber, stream_name, group_name, opts \\ [])

View Source (since 0.6.0)

Specs

connect_to_persistent_subscription(
  connection :: Spear.Connection.t(),
  subscriber :: pid() | GenServer.name(),
  stream_name :: String.t(),
  group_name :: String.t(),
  opts :: Keyword.t()
) :: {:ok, subscription :: reference()} | {:error, any()}

Subscribes a process to an existing persistent subscription

Persistent subscriptions can be gracefully closed with cancel_subscription/3 just like subscriptions started with subscribe/4. The subscription will be cancelled by the connection process if the subscriber process exits.

Persistent subscriptions are an alternative to standard subscriptions (via subscribe/4) which use ack/3 and nack/4 to exert backpressure and allow out-of-order and batch processing within a single consumer and allow multiple connected consumers at once.

In standard subscriptions (via subscribe/4), if a client wishes to handle events in order without reprocessing, the client must keep track of its own position in a stream, either in memory or using some sort of persistence such as PostgreSQL or mnesia for durability.

In contrast, persistent subscriptions are stateful on the server-side: the EventStoreDB will keep track of which events have been positively and negatively acknowledged and will only emit events which have not yet been processed to any connected consumers.

This allows one to connect multiple subscriber processes to a persistent subscription stream-group combination in a strategy called Competing Consumers.

Note that persistent subscription events are not guaranteed to be processed in order like the standard subscriptions because of the ability to nack/4 and reprocess or park a message. While this requires special considerations when authoring a consumer, it allows one to easily write a consumer which does not head-of-line block in failure cases.

The subscriber will receive a message {:eos, subscription, reason} when the subscription is closed by the server. :closed denotes that the EventStoreDB connection has been severed and :dropped denotes that the EventStoreDB has explicitly told the subscriber that the subscription is terminated. This can occur for persistent subscriptions in the case where the subscription is deleted (e.g. via Spear.delete_persistent_subscription/4). subscription is the reference retuned by this function.

iex> Spear.create_persistent_subscription(conn, "asdf", "asdf", %Spear.PersistentSubscription.Settings{})
:ok
iex> Spear.connect_to_persistent_subscription(conn, self(), "asdf", "asdf")
{:ok, #Reference<0.515780924.2297430020.166204>}
iex> flush
:ok
iex> Spear.delete_persistent_subscription(conn, "asdf", "asdf")
:ok
iex> flush
{:eos, #Reference<0.515780924.2297430020.166204>, :dropped}
:ok

Like subscriptions from subscribe/4, events can be correlated to their subscription by the :subscription key in each Spear.Event.metadata map.

Backpressure

Persistent subscriptions allow the subscriber process to exert backpressure on the EventStoreDB so that the message queue is not flooded. This is implemented with a buffer of events which are considered by the EventStoreDB to be in-flight when they are sent to the client. Events remain in-flight until they are ack/3-ed, nack/4-ed, or until the :message_timeout duration is exceeded. If a client ack/3s a message, the EventStoreDB will send a new message if any are available.

The in-flight buffer size is controllable per subscriber through :buffer_size. Note that :message_timeout applies to each event: if the :buffer_size is 5 and five events arrive simultaneously, the client has the duration :message_timeout to acknowledge all five events before they are considered stale and are automatically considered nack-ed by the EventStoreDB.

The :buffer_size should align with the consumer's ability to batch process events.

Options

  • :timeout - (default: 5_000ms - 5s) the time to await a subscription confirmation from the EventStoreDB.
  • :raw? - (default: false) controls whether events are translated from low-level Spear.Records.Persistent.read_resp/0 records to Spear.Event.t/0s. By default Spear.Event.t/0s are sent to the subscriber.
  • :credentials - (default: nil) the credentials to use to connect to the subscription. When not specified, the connection-level credentials are used. Credentials must be a two-tuple {username, password}.
  • :buffer_size - (default: 1) the number of events allowed to be sent to the client at a time. These events are considered in-flight. See the backpressure section above for more information.

Examples

iex> Spear.connect_to_persistent_subscription(conn, self(), "my_stream", "my_group")
iex> flush
%Spear.Event{}
:ok