View Source Spear.Connection (Spear v1.4.1)

A GenServer which brokers a connection to an EventStoreDB

Spear.Connection will attempt to connect immediately after GenServer init. Failures to connect will result in back-off retries in segments of 500ms. Any GenServer to a connection process may return {:error, :closed} if the connection process is alive but the HTTP2 connection to the EventStoreDB is not yet (re)established. Spear.Connection will automatically attempt to re-connect to the EventStoreDB if the connection is severed.

Spear.Connection processes accept GenServer.call/3s of :close to force a disconnect from an EventStoreDB and a subsequent GenServer.cast/2 of :connect to reconnect based on the configuration supplied at init-time.

If configuration parameters must change between disconnects and reconnects, spawning and killing connections with a DynamicSupervisor is recommended.

Configuration

See the Spear.Connection.Configuration module for available configuration of connections.

TLS/SSL configuration and credentials

See the Security guide for information about certificates, credentials, and access control lists (ACLs).

Keep-alive

Spear and the EventStoreDB use gRPC keep-alive to ensure that any hung connections are noticed and restarted.

EventStoreDB has its own configuration for keep-alive and each Spear client's configuration should not necessarily match the server configuration. With a :keep_alive_interval too low on the Spear-side and with very many connected clients, the keep-alive pings can effectively become a DDoS even while no clients perform any operations. This does not necessarily apply to the keep-alive settings in EventStoreDB: a client connects to a single EventStoreDB but an EventStoreDB may have hundreds or more clients connected at once.

:keep_alive_interval does not express an interval in the way of :timer.send_interval/3. Instead the keep-alive timer is optimized to reset upon any data received from the connection.

This means that (assuming consistent network, which is generous) either the Spear client or EventStoreDB server will dominate the keep-alive ping communication, the driver of the conversation being which ever has the lowest keep-alive interval configured. For this reason, it is generally advisable to set the client keep-alive just higher than the server keep-alive, adding noise for network latency, since the client's keep-alive routine will only trigger when the server's keep-alive message is behind schedule.

Note that there may not be much value in attempting to optimize the keep-alive settings unless the network is very unstable: keep-alive only has utility when the client, server, or network is seriously delayed or silently severed.

Examples

iex> {:ok, conn} = Spear.Connection.start_link(connection_string: "esdb://localhost:2113")
iex> Spear.stream!(conn, "es_supported_clients") |> Enum.take(3)
[%Spear.Event{}, %Spear.Event{}, %Spear.Event{}]

Summary

Types

t()

A connection process

Functions

Declares whether an API+RPC combination is read-only or not

Returns the list of read-only APIs

Starts a connection process

Types

@type t() :: pid() | GenServer.name()

A connection process

A connection process (either referred to as conn or connection in the documentation) may either be a PID or a name such as a module or otherwise atom.

Examples

iex> {:ok, conn} = Spear.Connection.start_link(connection_string: "esdb://localhost:2113")
{:ok, #PID<0.225.0>}
iex> Spear.read_stream(conn, "es_supported_clients", max_count: 1)
{:ok,
 #Stream<[
   enum: #Function<62.80860365/2 in Stream.unfold/2>,
   funs: [#Function<48.80860365/1 in Stream.map/2>]
 ]>}

Functions

Link to this function

read_api?(api, rpc)

View Source (since 0.8.0)
@spec read_api?(api :: module(), rpc :: atom()) :: boolean()

Declares whether an API+RPC combination is read-only or not

Examples

iex> Spear.Connection.read_api?(Spear.Records.Streams, :Read)
true
iex> Spear.Connection.read_api?(Spear.Records.Streams, :Append)
false
Link to this function

read_apis()

View Source (since 0.8.0)
@spec read_apis() :: %{required(api :: module()) => [rpc :: atom()]}

Returns the list of read-only APIs

This list is used to determine which requests are allowed for read-only clients.

@spec start_link(opts :: Keyword.t()) :: {:ok, t()} | GenServer.on_start()

Starts a connection process

This function can be called directly in order to link it to the current process, but the more common workflow is to start a Spear.Connection GenServer as a part of a supervision tree.

Examples

E.g. in an application's supervision tree defined in lib/my_app/application.ex:

children = [
  {Spear.Connection, name: MyConnection, connection_string: "esdb://localhost:2113"}
]
Supervisor.start_link(children, strategy: :one_for_one)