DpExchange.Coinbase.Supervisor (DpExchangeCoinbase v0.2.25)

Copy Markdown View Source

This venue's process tree — internal. A consumer starts DpExchange.Coinbase and gets this; it never names or reaches into the children.

The venue starts its own rate limiter, and that is the point

Rate limiting is venue-internal under the facade contract, and this is what that means in practice: the ceilings capabilities/0 declares are the ceilings the limiter is configured with. The declaration is not decoration that happens to sit beside the mechanism — it is the mechanism's configuration, so the two cannot drift apart.

The ceiling follows whether this instance was given credentials

capabilities/0 declares two ceilings and says outright that credentials buy the higher one: "Pass credentials and this package uses the authenticated path, which has the higher ceiling; pass none and it uses the public one." That is a claim about Rest's request paths, and the limiter has to agree with it — a limiter fixed at public_ceiling regardless of opts[:credentials] would throttle a credentialed consumer's authenticated calls to a third of what the venue actually allows them, while the moduledoc kept promising the higher number. limits/1 reads the same opts this supervisor was started with (the same map Feed reads :credentials out of) and configures the bucket from authenticated_ceiling when one was given, public_ceiling otherwise — so the mechanism agrees with the declaration for whichever path this instance is actually going to take, not only for the unauthenticated one.

It also fixes a real usability trap. Core.HttpClient fails closed when no limiter is running, which is correct — an unmetered package is how a venue answers with HTTP 429 while a budget panel reads comfortable. But it means a venue package that expected someone else to start a limiter answers {:error, "Rate limiter unavailable"} to every call, and the error does not say what is missing. Measured while writing this package's tier-2 tests, which is exactly the tier that catches integration gaps a fake cannot.

A consumer may still supply its own limiter through Core.Config's :rate_limit_module, per process — this is a working default, not a lock.

What is deliberately not here

No aggregate supervisor over multiple venues, and no auto-start. A consumer puts DpExchange.Coinbase in its own tree and chooses restart strategy, shutdown order and naming. A consumer that has not asked for this venue never finds a socket open.

Summary

Functions

Returns a specification to start this module under a supervisor.

This venue's feed process.

The limiter this venue meters against, for Core.HttpClient's :limiter option.

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.

limiter_name(opts)

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

The limiter this venue meters against, for Core.HttpClient's :limiter option.

start_link(opts)

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