DpExchange.Webull.Supervisor (DpExchangeWebull v0.4.167)

Copy Markdown View Source

This venue's process tree — internal.

The limiter is configured from what capabilities/0 declares

The declaration is not decoration beside the mechanism; it is the mechanism's configuration, so the two cannot drift.

Webull is the venue whose REST budget is the binding constraint in the family — the prior adapter measured 118 ms per call across 342 symbols — so the ceiling here matters more than on venues with room to spare.

Production and UAT run side by side, with separate everything

A consumer trading live while testing against UAT is running two of this venue at once. Every default name derives from the environment so the two neither collide nor share a rate-limit bucket — the second of which is the dangerous one: UAT traffic metering against the production budget would surface as a throttle on a real order, with nothing pointing back at the cause.

A :name of your own is enough to run two of the same environment under different credentials: the feed, the limiter and the ledger are named <name>.Feed, <name>.RateLimiter and <name>.Ledger, and a facade call given the same name: addresses them. Explicit :feed / :limiter / :ledger still win.

The ledger: a restarted feed picks up where it was

Feed keeps what it was asked to do (wanted symbols, subscribers, replay options) in its own state, which a crash empties. DpExchange.Webull.Ledger is started before it, outlives it, and is written on every accepted change; a restarted feed reads it back (see Feed).

Summary

Functions

Returns a specification to start this module under a supervisor.

This venue's feed process, named the way limiter_name/1 names the limiter.

The process holding what the feed was asked to do, named the way limiter_name/1 is.

The limiter this venue meters against: :limiter if given, else <name>.RateLimiter for a tree started with its own :name, else the environment's default.

The limits this venue's DefaultRateLimiter is started with, for the environment opts resolves to.

This tree's registered name, environment-derived.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

feed_name(opts)

@spec feed_name(keyword()) :: atom()

This venue's feed process, named the way limiter_name/1 names the limiter.

ledger_name(opts)

@spec ledger_name(keyword()) :: atom()

The process holding what the feed was asked to do, named the way limiter_name/1 is.

limiter_name(opts)

@spec limiter_name(keyword()) :: atom()

The limiter this venue meters against: :limiter if given, else <name>.RateLimiter for a tree started with its own :name, else the environment's default.

limits(opts)

@spec limits(keyword()) :: %{
  required(atom()) => %{
    limit: pos_integer(),
    per_ms: pos_integer(),
    burst: pos_integer()
  }
}

The limits this venue's DefaultRateLimiter is started with, for the environment opts resolves to.

Public for the same reason limiter_name/1 and feed_name/1 are: it is a derivation a reader has to be able to check, and the figure it produces gates every REST call this package makes. Not part of the facade — DpExchange.Webull is the boundary.

start_link(opts)

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

supervisor_name(opts)

@spec supervisor_name(keyword()) :: atom()

This tree's registered name, environment-derived.