DpExchange.Coinbase.Feed (DpExchangeCoinbase v0.1.1)

Copy Markdown View Source

This venue's subscription lifecycle — internal. The facade's subscribe/2, unsubscribe/2, update_symbols/2 and coverage/1 are served from here.

What a consumer can and cannot learn

A consumer learns what is arriving, through coverage/1. It cannot learn how: this module owns the socket, the sharding and the pacing, and none of that reaches the facade.

Coverage is observed, never intended

A symbol enters the coverage map when a payload for it arrives, never when it is subscribed. That distinction is the strongest guarantee in the contract and it exists because a venue once reported 325 symbols subscribed and confirmed while 174 were delivering. Reporting the subscription would have said 325.

A symbol that has been subscribed and has delivered nothing is simply absent, which the facade documents as :not_covered.

Sharding

Coinbase carries its whole subscription on one connection. That is measured, not assumed: once its self-killing heartbeat was fixed it subscribed 401 of 401 pairs on a single socket, and sharding it anyway opened 14 connections for no gain.

So there is no shard arithmetic here. A venue that needs it — one whose socket stops accepting subscribes after about ten pairs — adds it in its package, where the measurement lives.

Summary

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

coverage(feed \\ __MODULE__)

@spec coverage(GenServer.server()) :: %{
  required(String.t()) => :stream | :internal_poll | :not_covered
}

start_link(opts)

@spec start_link(keyword()) :: GenServer.on_start()

subscribe(feed \\ __MODULE__, symbols, opts \\ [])

@spec subscribe(GenServer.server(), [String.t()], keyword()) :: :ok | {:error, term()}

subscribe_notices(feed \\ __MODULE__, opts \\ [])

@spec subscribe_notices(
  GenServer.server(),
  keyword()
) :: :ok

unsubscribe(feed \\ __MODULE__, symbols)

@spec unsubscribe(GenServer.server(), [String.t()]) :: :ok | {:error, term()}

update_symbols(feed \\ __MODULE__, symbols)

@spec update_symbols(GenServer.server(), [String.t()]) :: :ok | {:error, term()}