masque_upstream_pool (masque v0.7.0)
View SourceRegistry for pooled upstream MASQUE connections.
Callers ask for an owner that can open a MASQUE tunnel against the configured upstream proxy. The registry either returns a cached masque_upstream_owner pid that has spare stream capacity, or spawns a fresh one that self-dials and notifies the registry when it is ready. Single-flight: multiple callers for the same fingerprint while a dial is in progress all block on the same result.
Fingerprints encode host + port + transport + a hash of connection-affecting opts (verify, cacerts, ssl_opts, alpn). Two callers with different trust or ALPN settings get different owners even if they target the same host:port.
The registry itself never blocks on a handshake; the async spawn of the owner process handles that. A slow upstream only stalls callers on its own key.
h1 is not handled here - the pool is opt-in for h2 / h3 only. Callers that want to pool an h1 upstream receive {error, pool_unsupported_for_transport} and should fall back to the direct per-tunnel path.
Summary
Functions
Get an owner for the given fingerprint. Opens a new one on cache miss, blocks briefly on a concurrent dial for the same fingerprint, returns {error, _} on dial failure.
Tear down every pooled owner. Used on application shutdown and in tests. Safe to call while callers are in flight - they receive {error, shutdown}.
Build a fingerprint from the host / port / transport and the connection-affecting subset of Opts. Stable under re-ordering of list-valued opts so two callers that pass ssl_opts in different order still hash to the same key.
Types
-type fingerprint() :: {Host :: binary() | string(), Port :: inet:port_number(), Transport :: h2 | quic_h3, OptsHash :: binary()}.
Functions
-spec checkout(fingerprint(), map()) -> {ok, pid()} | {error, term()}.
Get an owner for the given fingerprint. Opens a new one on cache miss, blocks briefly on a concurrent dial for the same fingerprint, returns {error, _} on dial failure.
Opts carries everything the owner needs to dial: host, port, connect_opts, optional transport_mod (for tests), plus any owner-level tuning (idle_timeout_ms, max_streams).
-spec close_all() -> ok.
Tear down every pooled owner. Used on application shutdown and in tests. Safe to call while callers are in flight - they receive {error, shutdown}.
-spec fingerprint(binary() | string(), inet:port_number(), h2 | quic_h3, map()) -> fingerprint().
Build a fingerprint from the host / port / transport and the connection-affecting subset of Opts. Stable under re-ordering of list-valued opts so two callers that pass ssl_opts in different order still hash to the same key.