Ankusa.Listener (ankusa v0.7.0)

Copy Markdown View Source

What every HTTP listener the instance runs (the ingest edge, the admin API, the route-management API, the claim-check gateway, the metrics listener) has in common: the connection limits and timeouts of Ankusa.Config's listener section, and the optional TLS block each listener carries.

Bandit's own defaults are tuned for a browser-facing app (a 60 s header read timeout, unlimited keep-alive, 16 384 connections for each of 100 acceptors, HTTP/2 on), so the instance passes every limit explicitly: see bandit_options/2.

TLS

A tls block is nil (plain HTTP) or a map:

KeyDefaultMeaning
certfile, keyfilerequiredPEM files of the server certificate and its key
cacertfilenilPEM bundle of the CAs that sign client certificates; required by verify: :verify_peer
verify:verify_none:verify_peer makes the listener demand a client certificate that chains to cacertfile (mTLS): a client without one is refused at the handshake, and the accepted certificate is available to the request as Plug.Conn.get_peer_data/1's :ssl_cert
versions[:"tlsv1.2", :"tlsv1.3"]protocol versions offered
ciphersnila list of OpenSSL-style names ("ECDHE-RSA-AES256-GCM-SHA384") or TLS 1.3 names ("TLS_AES_256_GCM_SHA384"); nil leaves the Erlang/OTP defaults

Summary

Types

A normalised tls block.

Functions

The Bandit options that apply config.listener's limits and the listener's own tls block. The caller adds :plug, :port and :ip.

The default number of acceptors: two per scheduler.

How long the ingress listener waits, on a stop, for the requests it is serving before it closes their connections (Thousand Island's :shutdown_timeout, which defaults to 15 s: the batcher's own record deadline, so a commit that starts late would be killed mid-fsync and the provider would see a reset for a committed hook).

Validate one tls block (key is its dotted config name, for messages) and return it as a map with every key present and every path absolute, or nil. Raises ArgumentError naming the key.

Types

tls()

@type tls() :: %{
  certfile: Path.t(),
  keyfile: Path.t(),
  cacertfile: Path.t() | nil,
  verify: :verify_none | :verify_peer,
  versions: [:"tlsv1.2" | :"tlsv1.3"],
  ciphers: [String.t()] | nil
}

A normalised tls block.

Functions

bandit_options(config, tls, thousand_island_extra \\ [])

@spec bandit_options(Ankusa.Config.t(), tls() | nil, keyword()) :: keyword()

The Bandit options that apply config.listener's limits and the listener's own tls block. The caller adds :plug, :port and :ip.

listener.max_connections is spread over listener.num_acceptors (Thousand Island counts connections per acceptor). thousand_island_extra is appended to the Thousand Island options (the ingress listener passes its :shutdown_timeout).

default_acceptors()

@spec default_acceptors() :: pos_integer()

The default number of acceptors: two per scheduler.

ingress_shutdown_timeout_ms(config)

@spec ingress_shutdown_timeout_ms(Ankusa.Config.t()) :: pos_integer()

How long the ingress listener waits, on a stop, for the requests it is serving before it closes their connections (Thousand Island's :shutdown_timeout, which defaults to 15 s: the batcher's own record deadline, so a commit that starts late would be killed mid-fsync and the provider would see a reset for a committed hook).

A request may wait its whole record deadline (Ankusa.Edge.Batcher.record_deadline_ms/0) before its batch starts committing, then needs the store commit (2000 ms of budget; under wal: :dual also one intake publish, intake.publish_timeout_ms), and the listener keeps 5000 ms in hand. Under wal: :none the request waits for its sinks instead: direct_publish_timeout_ms plus the margin.

normalize_tls!(tls, key)

@spec normalize_tls!(term(), String.t()) :: tls() | nil

Validate one tls block (key is its dotted config name, for messages) and return it as a map with every key present and every path absolute, or nil. Raises ArgumentError naming the key.