Spear.connect_to_persistent_subscription
connect_to_persistent_subscription
, go back to Spear module for more information.
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/3
s 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_000
ms - 5s) the time to await a subscription confirmation from the EventStoreDB.:raw?
- (default:false
) controls whether events are translated from low-levelSpear.Records.Persistent.read_resp/0
records toSpear.Event.t/0
s. By defaultSpear.Event.t/0
s 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