Packages
extreme
1.1.0
1.1.4
1.1.3
1.1.2
1.1.1
1.1.1-rc01
1.1.0
1.1.0-rc9
1.1.0-rc8
1.1.0-rc7
1.1.0-rc6
1.1.0-rc5
1.1.0-rc4
1.1.0-rc3
1.1.0-rc2
1.1.0-rc1
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.2
0.9.1
0.9.0
0.8.1
0.8.0
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
Elixir TCP client for EventStore.
Current section
Files
Jump to
Current section
Files
lib/extreme/shared_subscription.ex
defmodule Extreme.SharedSubscription do
@moduledoc """
This module contains functions shared between `Extreme.Subscription` and `Extreme.ReadingSubscription`.
"""
alias Extreme.RequestManager
alias Extreme.Messages, as: Msg
require Logger
@doc """
Sends subscription request and waits for positive response. Returns `{:ok, subscription_confirmation}`.
"""
def subscribe(state) do
message =
Msg.SubscribeToStream.new(
event_stream_id: state.read_params.stream,
resolve_link_tos: state.read_params.resolve_link_tos
)
{:ok, subscription_confirmation} =
state.base_name
|> RequestManager.execute(message, state.correlation_id)
Logger.debug(fn ->
"Successfully subscribed to stream #{inspect(subscription_confirmation)}"
end)
{:ok, subscription_confirmation}
end
@doc """
Sends unsubscribe "fire and forget" request to EventStoreDB.
"""
def unsubscribe(state) do
spawn_link(fn ->
message = Msg.UnsubscribeFromStream.new()
:ok =
state.base_name
|> RequestManager.execute(message, state.correlation_id)
:ok =
state.base_name
|> RequestManager.unregister_subscription(state.correlation_id)
end)
:ok
end
@doc """
Executes `fun` function for decoding response and responds on that message.
"""
def process_push(fun, state), do: fun.() |> _process_push(state)
@doc """
Calls subscriber with {:on_event, event}, expecting :ok as result
in order to apply backpressure.
"""
def on_event(subscriber, event, ack_timeout),
do: GenServer.call(subscriber, {:on_event, event}, ack_timeout)
defp _process_push(
{_auth, _correlation_id,
%Msg.StreamEventAppeared{
event: %Msg.ResolvedEvent{event: %Msg.EventRecord{event_type: "$streamDeleted"}}
}},
state
) do
send(state.subscriber, {:extreme, :stream_hard_deleted})
RequestManager.unregister_subscription(state.base_name, state.correlation_id)
{:stop, {:shutdown, :stream_hard_deleted}, state}
end
defp _process_push(
{_auth, _correlation_id, %Msg.StreamEventAppeared{} = e},
state
) do
state.subscriber
|> on_event(e.event, state.read_params.ack_timeout)
|> case do
:ok ->
{:noreply, state}
:stop ->
Logger.info("Processing of event requested stopping subscription")
RequestManager.unregister_subscription(state.base_name, state.correlation_id)
{:stop, {:shutdown, :processing_of_event_requested_stopping_subscription}, state}
end
end
defp _process_push(
{_auth, _correlation_id, %Msg.SubscriptionDropped{reason: reason}},
state
) do
send(state.subscriber, {:extreme, reason})
RequestManager.unregister_subscription(state.base_name, state.correlation_id)
{:stop, {:shutdown, reason}, state}
end
defp _process_push(
{_auth, _correlation_id,
%Msg.PersistentSubscriptionConfirmation{subscription_id: subscription_id} = confirmation},
state
) do
Logger.debug(fn -> "Successfully subscribed #{inspect(confirmation)}" end)
{:noreply, %{state | status: :subscribed, subscription_id: subscription_id}}
end
defp _process_push(
{_auth, correlation_id, %Msg.PersistentSubscriptionStreamEventAppeared{} = e},
state
) do
:ok = GenServer.cast(state.subscriber, {:on_event, e.event, correlation_id})
{:noreply, state}
end
end