-module(distribute). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/distribute.gleam"). -export([version/0, configure/1, get_config/0, config_error_to_string/1, start_node/2, connect/1, nodes/0, self_node/0, is_distributed/0, has_peers/0, health/0, node_start_error_to_string/1, connect_error_to_string/1, start_monitor/0, subscribe/2, unsubscribe/2, install_telemetry/1, named/2, new_subject/1, register/2, lookup/1, unregister/1, unregister_typed/1, register_error_to_string/1, unregister_error_to_string/1, lookup_error_to_string/1, actor_start_error_to_string/1, start_registered_error_to_string/1, start_actor/3, start_actor_with_timeout/4, start_actor_observed/4, start_registered/3, start_registered_with_timeout/4, start_supervised/3, start_supervised_with_timeout/4, pool/4, pool_with_timeout/5, child_spec/3, child_spec_with_timeout/4, send/2, reply/3, 'receive'/1, receive_with_timeout/2, call/3, call_with_timeout/4, call_isolated/3, call_isolated_with_timeout/4, send_error_to_string/1, call_error_to_string/1, receive_error_to_string/1, encode_error_to_string/1, decode_error_to_string/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " `distribute`: Typed messaging for the BEAM.\n" "\n" " This library provides a safety layer over Erlang's native distribution.\n" " It focuses on hardening the **Node Boundary**: the physical edge where\n" " typed Gleam values become raw binary terms and vice versa.\n" "\n" " ## The Typed Boundary Concept\n" "\n" " In standard Erlang distribution, messages cross the wire as raw terms\n" " without type information. `distribute` forces you to define a protocol\n" " using `TypedName` and `Codec` before any data is sent.\n" "\n" " 1. **At the Sender**: messages are encoded, checked against payload\n" " limits, and transmitted via BEAM distribution.\n" " 2. **At the Receiver**: binaries have their size verified *before*\n" " decoding. If they exceed limits, they are rejected. If they are\n" " valid, they are decoded into typed Gleam values.\n" "\n" " This architecture ensures that an actor's mailbox is never flooded\n" " with unparseable or oversized data, and the compiler can prevent\n" " protocol mismatches at the call site.\n" "\n" " ## Core Philosophy\n" "\n" " - **Fail-Fast over Retry**: every failure (Timeout, TargetDown,\n" " DecodeError) is surfaced immediately. Managing retries and circuit\n" " breaking is left to the application layer.\n" " - **Memory First**: payload limits are enforced at the I/O boundary\n" " to protect nodes from OOM attacks or bugs.\n" " - **OTP Native**: every part of the library (supervisors, monitors,\n" " subjects) follows standard BEAM OTP patterns.\n" " - **Zero Cost Read**: configuration is stored in Erlang's\n" " `persistent_term` for O(1) reads with zero heap allocation.\n" "\n" " ## Typical Usage\n" "\n" " ```gleam\n" " // 1. Configure once at application startup\n" " let assert Ok(Nil) = distribute.configure(config.default())\n" "\n" " // 2. Define a protocol (Name + Codec)\n" " let counter = distribute.named(\"counter\", codec.int())\n" "\n" " // 3. Start a globally registered, supervised singleton\n" " let assert Ok(pid) = distribute.start_supervised(counter, 0, handler)\n" "\n" " // 4. Call from any node. Monitor-based TargetDown detection,\n" " default timeout from config\n" " let assert Ok(val) = distribute.call(gs, Get, codec.int_decoder())\n" " ```\n" "\n" " ## Default vs explicit timeout\n" "\n" " Every long-running operation has two shapes:\n" "\n" " - The **default form** reads from `config.get()`. This is the path\n" " you want 90% of the time. A single `configure(...)` at boot tunes\n" " the whole surface (`call`, `receive`, `start_actor`,\n" " `start_registered`, `start_supervised`, `pool`, `child_spec`,\n" " `call_isolated`).\n" " - The **`_with_timeout` form** is the explicit override. Pick it\n" " only when the request has a hard deadline that diverges from\n" " `config.default_*`.\n" "\n" " ## Error handling without extra imports\n" "\n" " Every public error type (and its `*_to_string` formatter) is\n" " re-exported here. Pattern-matching on `CallError`, `RegisterError`,\n" " `LookupError`, etc., requires only `import distribute`.\n" "\n" " ## Reply-Subject helpers live in `distribute/receiver`\n" "\n" " Handlers that answer a `call` typically need `receiver.receive_typed`\n" " or `receiver.selecting_typed` to operate on the raw reply-Subject.\n" " These are intra-handler primitives: import the module directly.\n" "\n" " ```gleam\n" " import distribute/receiver\n" " case receiver.receive_typed(reply_to, codec.int_decoder(), 1000) {\n" " Ok(value) -> ...\n" " Error(receiver.ReceiveTimeout) -> ...\n" " Error(receiver.DecodeError(_)) -> ...\n" " }\n" " ```\n" "\n" " ## API surface, by concern\n" "\n" " - **Boot & config**: `configure`, `get_config`, `version`, `Config`,\n" " `ConfigError`, `config_error_to_string`.\n" " - **Node lifecycle**: `start_node`, `connect`, `nodes`, `self_node`,\n" " `is_distributed`, `has_peers`, `health`, `ClusterHealth`,\n" " `NodeStartError`, `ConnectError`,\n" " `node_start_error_to_string`, `connect_error_to_string`.\n" " - **Cluster events**: `start_monitor`, `subscribe`, `unsubscribe`,\n" " `ClusterEvent`, `MonitorMessage`.\n" " - **Protocol**: `named`, `new_subject`, `register`, `lookup`,\n" " `unregister`, `unregister_typed`, `TypedName`, `GlobalSubject`,\n" " `RegisterError`, `UnregisterError`, `LookupError`,\n" " `register_error_to_string`, `unregister_error_to_string`,\n" " `lookup_error_to_string`.\n" " - **Actor lifecycle**: `start_actor` / `start_actor_with_timeout` /\n" " `start_actor_observed`, `start_registered` /\n" " `start_registered_with_timeout`, `start_supervised` /\n" " `start_supervised_with_timeout`, `pool` / `pool_with_timeout`,\n" " `child_spec` / `child_spec_with_timeout`, `HandlerStep`,\n" " `ActorStartError`, `StartRegisteredError`,\n" " `actor_start_error_to_string`, `start_registered_error_to_string`.\n" " - **Messaging**: `send`, `reply`, `receive` / `receive_with_timeout`,\n" " `call` / `call_with_timeout`, `call_isolated` /\n" " `call_isolated_with_timeout`, `SendError`, `CallError`,\n" " `ReceiveError`, `EncodeError`, `DecodeError`,\n" " `send_error_to_string`, `call_error_to_string`,\n" " `receive_error_to_string`, `encode_error_to_string`,\n" " `decode_error_to_string`.\n" "\n" " Most users only need `import distribute`. Low-level modules\n" " (`distribute/actor`, `distribute/global`, `distribute/registry`,\n" " `distribute/codec`, `distribute/receiver`, `distribute/cluster`,\n" " `distribute/cluster_monitor`, `distribute/codec/composite`,\n" " `distribute/codec/tagged`, `distribute/config`) remain available for\n" " advanced cases not covered by the facade. e.g. `whereis`,\n" " `register_pid`, `register_typed`, `from_pid`, `from_subject`,\n" " `lookup_with_timeout`, `lookup_async`, `start_registered_observed`,\n" " `receive_typed`, `selecting_typed`.\n" ). -file("src/distribute.gleam", 145). ?DOC( " Library version, hardcoded. Must stay in sync with `gleam.toml`\n" " at release time. Gleam has no compile-time API to read the\n" " manifest, so this is a release-time discipline, not a runtime\n" " invariant.\n" ). -spec version() -> binary(). version() -> <<"4.0.0"/utf8>>. -file("src/distribute.gleam", 156). ?DOC(" Set global runtime configuration. Call once at application startup.\n"). -spec configure(distribute@config:config()) -> {ok, nil} | {error, distribute@config:config_error()}. configure(Cfg) -> distribute@config:configure(Cfg). -file("src/distribute.gleam", 161). ?DOC(" Read the current global configuration (or defaults if never configured).\n"). -spec get_config() -> distribute@config:config(). get_config() -> distribute@config:get(). -file("src/distribute.gleam", 165). -spec config_error_to_string(distribute@config:config_error()) -> binary(). config_error_to_string(Err) -> distribute@config:config_error_to_string(Err). -file("src/distribute.gleam", 184). ?DOC( " Start a distributed BEAM node.\n" "\n" " `name` must contain `@` (e.g. `\"myapp@127.0.0.1\"`).\n" " `cookie` must be `[a-zA-Z0-9_-]+` and 1..255 bytes (validated by FFI).\n" ). -spec start_node(binary(), binary()) -> {ok, nil} | {error, distribute@cluster:start_error()}. start_node(Name, Cookie) -> distribute@cluster:start_node(Name, Cookie). -file("src/distribute.gleam", 188). -spec connect(binary()) -> {ok, nil} | {error, distribute@cluster:connect_error()}. connect(Node) -> distribute@cluster:connect(Node). -file("src/distribute.gleam", 192). -spec nodes() -> list(binary()). nodes() -> distribute@cluster:nodes(). -file("src/distribute.gleam", 196). -spec self_node() -> binary(). self_node() -> distribute@cluster:self_node(). -file("src/distribute.gleam", 201). ?DOC(" Whether this node is running BEAM distribution (via `erlang:is_alive/0`).\n"). -spec is_distributed() -> boolean(). is_distributed() -> distribute@cluster:is_distributed(). -file("src/distribute.gleam", 208). ?DOC( " Whether this node has at least one connected peer. *Not* a health\n" " check. A single-node deployment is operationally fine and will\n" " return `False` here. Use this only to gate cluster-wide operations.\n" ). -spec has_peers() -> boolean(). has_peers() -> distribute@cluster:has_peers(). -file("src/distribute.gleam", 213). ?DOC(" Full cluster health snapshot with parallel pings.\n"). -spec health() -> distribute@cluster:cluster_health(). health() -> distribute@cluster:health(). -file("src/distribute.gleam", 217). -spec node_start_error_to_string(distribute@cluster:start_error()) -> binary(). node_start_error_to_string(Err) -> distribute@cluster:start_error_to_string(Err). -file("src/distribute.gleam", 221). -spec connect_error_to_string(distribute@cluster:connect_error()) -> binary(). connect_error_to_string(Err) -> distribute@cluster:connect_error_to_string(Err). -file("src/distribute.gleam", 235). ?DOC( " Start the cluster monitor actor. It listens for Erlang node events\n" " and broadcasts them to all Gleam subscribers.\n" ). -spec start_monitor() -> {ok, gleam@erlang@process:subject(distribute@cluster_monitor:message())} | {error, gleam@otp@actor:start_error()}. start_monitor() -> distribute@cluster:start_monitor(). -file("src/distribute.gleam", 242). -spec subscribe( gleam@erlang@process:subject(distribute@cluster_monitor:message()), gleam@erlang@process:subject(distribute@cluster_monitor:cluster_event()) ) -> nil. subscribe(Monitor, Listener) -> distribute@cluster:subscribe(Monitor, Listener). -file("src/distribute.gleam", 249). -spec unsubscribe( gleam@erlang@process:subject(distribute@cluster_monitor:message()), gleam@erlang@process:subject(distribute@cluster_monitor:cluster_event()) ) -> nil. unsubscribe(Monitor, Listener) -> distribute@cluster:unsubscribe(Monitor, Listener). -file("src/distribute.gleam", 268). ?DOC( " Install (or replace) the global telemetry sink for observability.\n" " This single opt-in sink receives all load-bearing events from the library\n" " (registry, atom budget, payload limits, codec failures, timeouts).\n" " See `distribute/telemetry` for the full semantics and event structure.\n" ). -spec install_telemetry(fun((distribute@telemetry:event()) -> nil)) -> nil. install_telemetry(Sink) -> distribute@telemetry:install(Sink). -file("src/distribute.gleam", 290). ?DOC( " Create a `TypedName` from a bundled `Codec`.\n" "\n" " ```gleam\n" " let counter = distribute.named(\"counter\", codec.int())\n" " ```\n" ). -spec named(binary(), distribute@codec:codec(HXO)) -> distribute@registry:typed_name(HXO). named(Name, C) -> distribute@registry:named(Name, C). -file("src/distribute.gleam", 297). ?DOC( " Create a new `GlobalSubject` owned by the current process, from a\n" " bundled `Codec`. For separate encoder/decoder, drop down to\n" " `global.new` directly.\n" ). -spec new_subject(distribute@codec:codec(HXR)) -> distribute@global:global_subject(HXR). new_subject(C) -> distribute@global:new(erlang:element(2, C), erlang:element(3, C)). -file("src/distribute.gleam", 325). ?DOC( " Register a `GlobalSubject` under its `TypedName`. The typed pair is\n" " the recommended path; for raw-PID registration import\n" " `distribute/registry` and call `registry.register/2` directly.\n" ). -spec register( distribute@registry:typed_name(HXU), distribute@global:global_subject(HXU) ) -> {ok, nil} | {error, distribute@registry:register_error()}. register(Typed_name, Subject) -> distribute@registry:register_global(Typed_name, Subject). -file("src/distribute.gleam", 335). ?DOC( " Look up a `GlobalSubject` by its `TypedName`. For polling variants\n" " (blocking and async) see `registry.lookup_with_timeout` /\n" " `registry.lookup_async`.\n" ). -spec lookup(distribute@registry:typed_name(HXZ)) -> {ok, distribute@global:global_subject(HXZ)} | {error, nil}. lookup(Typed_name) -> distribute@registry:lookup(Typed_name). -file("src/distribute.gleam", 341). ?DOC( " Unregister a globally registered name. Idempotent cleanup paths can\n" " `let _ = unregister(name)`.\n" ). -spec unregister(binary()) -> {ok, nil} | {error, distribute@registry:unregister_error()}. unregister(Name) -> distribute@registry:unregister(Name). -file("src/distribute.gleam", 348). ?DOC( " Type-safe sibling of `unregister/1`: pulls the name string from the\n" " `TypedName` the caller already holds. Recommended for graceful\n" " shutdown paths so the cleanup site never has to hardcode the name.\n" ). -spec unregister_typed(distribute@registry:typed_name(any())) -> {ok, nil} | {error, distribute@registry:unregister_error()}. unregister_typed(Typed_name) -> distribute@registry:unregister_typed(Typed_name). -file("src/distribute.gleam", 354). -spec register_error_to_string(distribute@registry:register_error()) -> binary(). register_error_to_string(Err) -> distribute@registry:register_error_to_string(Err). -file("src/distribute.gleam", 358). -spec unregister_error_to_string(distribute@registry:unregister_error()) -> binary(). unregister_error_to_string(Err) -> distribute@registry:unregister_error_to_string(Err). -file("src/distribute.gleam", 362). -spec lookup_error_to_string(distribute@registry:lookup_error()) -> binary(). lookup_error_to_string(Err) -> distribute@registry:lookup_error_to_string(Err). -file("src/distribute.gleam", 375). ?DOC(" Render a `gleam_otp/actor.StartError` as a human-readable string.\n"). -spec actor_start_error_to_string(gleam@otp@actor:start_error()) -> binary(). actor_start_error_to_string(Err) -> case Err of init_timeout -> <<"Actor init timed out"/utf8>>; {init_failed, Reason} -> <<"Actor init failed: "/utf8, Reason/binary>>; {init_exited, _} -> <<"Actor init process exited"/utf8>> end. -file("src/distribute.gleam", 383). -spec start_registered_error_to_string( distribute@actor:start_registered_error() ) -> binary(). start_registered_error_to_string(Err) -> distribute@actor:start_registered_error_to_string(Err). -file("src/distribute.gleam", 389). ?DOC( " Start a named actor using `config.get().default_init_timeout_ms`.\n" " Use `start_actor_with_timeout/4` for an explicit timeout.\n" ). -spec start_actor( distribute@registry:typed_name(HYK), HYM, fun((HYK, HYM) -> distribute@receiver:handler_step(HYM)) ) -> {ok, distribute@global:global_subject(HYK)} | {error, gleam@otp@actor:start_error()}. start_actor(Typed_name, Initial_state, Handler) -> distribute@actor:start_default(Typed_name, Initial_state, Handler). -file("src/distribute.gleam", 398). ?DOC(" Start a named actor with an explicit init timeout.\n"). -spec start_actor_with_timeout( distribute@registry:typed_name(HYR), HYT, fun((HYR, HYT) -> distribute@receiver:handler_step(HYT)), integer() ) -> {ok, distribute@global:global_subject(HYR)} | {error, gleam@otp@actor:start_error()}. start_actor_with_timeout(Typed_name, Initial_state, Handler, Init_timeout_ms) -> distribute@actor:start(Typed_name, Initial_state, Handler, Init_timeout_ms). -file("src/distribute.gleam", 412). ?DOC( " Start a named actor with a decode-error callback. Useful for\n" " logging or metering malformed messages across nodes (e.g. during\n" " rolling deploys with mismatched codec versions). Uses\n" " `config.get().default_init_timeout_ms`. If you need a custom\n" " init timeout, drop down to `actor.start_observed` directly.\n" ). -spec start_actor_observed( distribute@registry:typed_name(HYY), HZA, fun((HYY, HZA) -> distribute@receiver:handler_step(HZA)), fun((distribute@codec:decode_error()) -> nil) ) -> {ok, distribute@global:global_subject(HYY)} | {error, gleam@otp@actor:start_error()}. start_actor_observed(Typed_name, Initial_state, Handler, On_decode_error) -> distribute@actor:start_observed( Typed_name, Initial_state, Handler, erlang:element(3, distribute@config:get()), On_decode_error ). -file("src/distribute.gleam", 431). ?DOC( " Start an actor and register it globally in one step. Uses\n" " `config.get().default_init_timeout_ms`. Use\n" " `start_registered_with_timeout/4` for an explicit timeout, or\n" " `actor.start_registered_observed` for the decode-error hook variant.\n" ). -spec start_registered( distribute@registry:typed_name(HZF), HZH, fun((HZF, HZH) -> distribute@receiver:handler_step(HZH)) ) -> {ok, distribute@global:global_subject(HZF)} | {error, distribute@actor:start_registered_error()}. start_registered(Typed_name, Initial_state, Handler) -> distribute@actor:start_registered_default( Typed_name, Initial_state, Handler ). -file("src/distribute.gleam", 440). ?DOC(" Like `start_registered`, with an explicit init timeout.\n"). -spec start_registered_with_timeout( distribute@registry:typed_name(HZM), HZO, fun((HZM, HZO) -> distribute@receiver:handler_step(HZO)), integer() ) -> {ok, distribute@global:global_subject(HZM)} | {error, distribute@actor:start_registered_error()}. start_registered_with_timeout( Typed_name, Initial_state, Handler, Init_timeout_ms ) -> distribute@actor:start_registered( Typed_name, Initial_state, Handler, Init_timeout_ms ). -file("src/distribute.gleam", 455). ?DOC(" Start a supervised actor using `config.get().default_init_timeout_ms`.\n"). -spec start_supervised( distribute@registry:typed_name(HZT), HZV, fun((HZT, HZV) -> distribute@receiver:handler_step(HZV)) ) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@otp@actor:start_error()}. start_supervised(Typed_name, Initial_state, Handler) -> distribute@actor:start_supervised_default( Typed_name, Initial_state, Handler ). -file("src/distribute.gleam", 464). ?DOC(" Like `start_supervised`, with an explicit init timeout.\n"). -spec start_supervised_with_timeout( distribute@registry:typed_name(HZZ), IAB, fun((HZZ, IAB) -> distribute@receiver:handler_step(IAB)), integer() ) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@otp@actor:start_error()}. start_supervised_with_timeout( Typed_name, Initial_state, Handler, Init_timeout_ms ) -> distribute@actor:start_supervised( Typed_name, Initial_state, Handler, Init_timeout_ms ). -file("src/distribute.gleam", 479). ?DOC(" Start N supervised actors using `config.get().default_init_timeout_ms`.\n"). -spec pool( distribute@registry:typed_name(IAF), integer(), IAH, fun((IAF, IAH) -> distribute@receiver:handler_step(IAH)) ) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@otp@actor:start_error()}. pool(Typed_name, Size, Initial_state, Handler) -> distribute@actor:pool_default(Typed_name, Size, Initial_state, Handler). -file("src/distribute.gleam", 489). ?DOC(" Like `pool`, with an explicit init timeout.\n"). -spec pool_with_timeout( distribute@registry:typed_name(IAL), integer(), IAN, fun((IAL, IAN) -> distribute@receiver:handler_step(IAN)), integer() ) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@otp@actor:start_error()}. pool_with_timeout(Typed_name, Size, Initial_state, Handler, Init_timeout_ms) -> distribute@actor:pool( Typed_name, Size, Initial_state, Handler, Init_timeout_ms ). -file("src/distribute.gleam", 500). ?DOC(" OTP child spec using `config.get().default_init_timeout_ms`.\n"). -spec child_spec( distribute@registry:typed_name(IAR), IAT, fun((IAR, IAT) -> distribute@receiver:handler_step(IAT)) ) -> gleam@otp@supervision:child_specification(distribute@global:global_subject(IAR)). child_spec(Typed_name, Initial_state, Handler) -> distribute@actor:child_spec_default(Typed_name, Initial_state, Handler). -file("src/distribute.gleam", 509). ?DOC(" Like `child_spec`, with an explicit init timeout.\n"). -spec child_spec_with_timeout( distribute@registry:typed_name(IAX), IAZ, fun((IAX, IAZ) -> distribute@receiver:handler_step(IAZ)), integer() ) -> gleam@otp@supervision:child_specification(distribute@global:global_subject(IAX)). child_spec_with_timeout(Typed_name, Initial_state, Handler, Init_timeout_ms) -> distribute@actor:child_spec( Typed_name, Initial_state, Handler, Init_timeout_ms ). -file("src/distribute.gleam", 535). -spec send(distribute@global:global_subject(IBD), IBD) -> {ok, nil} | {error, distribute@global:send_error()}. send(Subject, Message) -> distribute@global:send(Subject, Message). -file("src/distribute.gleam", 543). ?DOC(" Send a response through a reply subject. Used by handlers to answer a `call`.\n"). -spec reply( gleam@erlang@process:subject(bitstring()), IBI, fun((IBI) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}) ) -> {ok, nil} | {error, distribute@global:send_error()}. reply(Reply_to, Response, Encoder) -> distribute@global:reply(Reply_to, Response, Encoder). -file("src/distribute.gleam", 553). ?DOC( " Receive a typed message using `config.get().default_call_timeout_ms`.\n" " Use `receive_with_timeout/2` for an explicit timeout.\n" ). -spec 'receive'(distribute@global:global_subject(IBM)) -> {ok, IBM} | {error, distribute@codec:decode_error()}. 'receive'(Subject) -> distribute@global:receive_default(Subject). -file("src/distribute.gleam", 558). ?DOC(" Like `receive`, with an explicit timeout.\n"). -spec receive_with_timeout(distribute@global:global_subject(IBQ), integer()) -> {ok, IBQ} | {error, distribute@codec:decode_error()}. receive_with_timeout(Subject, Timeout_ms) -> distribute@global:'receive'(Subject, Timeout_ms). -file("src/distribute.gleam", 588). ?DOC( " Synchronous request/response with monitor-based `TargetDown` detection.\n" " Uses `config.get().default_call_timeout_ms`. Use `call_with_timeout/4`\n" " for an explicit timeout.\n" "\n" " ## Late-reply caveat: choose `call_isolated` for long-running callers\n" "\n" " `call` is the cheap default. It is **safe** for short-lived callers\n" " (CLI tools, request handlers, scripts) whose process exits shortly\n" " after the call returns: orphan late-replies die with the process.\n" "\n" " It is **not** the right choice for long-lived processes (OTP\n" " actors, supervisors, manager loops) that issue many `call`s under\n" " sustained timeouts. A reply that arrives *after* `call` returns\n" " `Error(Timeout)` cannot be evicted from the caller's mailbox by\n" " the BEAM (no `erlang:alias/0`-aware Subject layout in the current\n" " `gleam_erlang`); selective receive scans every orphan on every\n" " subsequent `process.receive`, and tens of thousands of orphans\n" " quietly degrade the caller's throughput.\n" "\n" " For that shape, prefer `call_isolated/3`: it runs each call inside\n" " a short-lived unlinked proxy process whose mailbox is reaped on\n" " exit. See `global.call/4` and `docs/safety_and_limits.md` for the\n" " full design rationale.\n" ). -spec call( distribute@global:global_subject(IBU), fun((gleam@erlang@process:subject(bitstring())) -> IBU), fun((bitstring()) -> {ok, IBX} | {error, distribute@codec:decode_error()}) ) -> {ok, IBX} | {error, distribute@global:call_error()}. call(Target, Make_request, Response_decoder) -> distribute@global:call_default(Target, Make_request, Response_decoder). -file("src/distribute.gleam", 598). ?DOC( " Like `call`, with an explicit timeout. Inherits the same\n" " late-reply caveat. See `call/3`.\n" ). -spec call_with_timeout( distribute@global:global_subject(ICB), fun((gleam@erlang@process:subject(bitstring())) -> ICB), fun((bitstring()) -> {ok, ICE} | {error, distribute@codec:decode_error()}), integer() ) -> {ok, ICE} | {error, distribute@global:call_error()}. call_with_timeout(Target, Make_request, Response_decoder, Timeout_ms) -> distribute@global:call(Target, Make_request, Response_decoder, Timeout_ms). -file("src/distribute.gleam", 614). ?DOC( " Mailbox-safe variant of `call` using\n" " `config.get().default_call_timeout_ms`. Each invocation runs inside\n" " a short-lived unlinked proxy process so orphan late-replies die\n" " with the proxy instead of polluting the caller's mailbox.\n" " Recommended for long-running callers issuing many RPCs under\n" " sustained timeouts. See `global.call_isolated` for the full design\n" " rationale.\n" ). -spec call_isolated( distribute@global:global_subject(ICI), fun((gleam@erlang@process:subject(bitstring())) -> ICI), fun((bitstring()) -> {ok, ICL} | {error, distribute@codec:decode_error()}) ) -> {ok, ICL} | {error, distribute@global:call_error()}. call_isolated(Target, Make_request, Response_decoder) -> distribute@global:call_isolated_default( Target, Make_request, Response_decoder ). -file("src/distribute.gleam", 623). ?DOC(" Like `call_isolated`, with an explicit timeout.\n"). -spec call_isolated_with_timeout( distribute@global:global_subject(ICP), fun((gleam@erlang@process:subject(bitstring())) -> ICP), fun((bitstring()) -> {ok, ICS} | {error, distribute@codec:decode_error()}), integer() ) -> {ok, ICS} | {error, distribute@global:call_error()}. call_isolated_with_timeout(Target, Make_request, Response_decoder, Timeout_ms) -> distribute@global:call_isolated( Target, Make_request, Response_decoder, Timeout_ms ). -file("src/distribute.gleam", 632). -spec send_error_to_string(distribute@global:send_error()) -> binary(). send_error_to_string(Err) -> distribute@global:send_error_to_string(Err). -file("src/distribute.gleam", 636). -spec call_error_to_string(distribute@global:call_error()) -> binary(). call_error_to_string(Err) -> distribute@global:call_error_to_string(Err). -file("src/distribute.gleam", 640). -spec receive_error_to_string(distribute@receiver:receive_error()) -> binary(). receive_error_to_string(Err) -> distribute@receiver:receive_error_to_string(Err). -file("src/distribute.gleam", 644). -spec encode_error_to_string(distribute@codec:encode_error()) -> binary(). encode_error_to_string(Err) -> distribute@codec:encode_error_to_string(Err). -file("src/distribute.gleam", 648). -spec decode_error_to_string(distribute@codec:decode_error()) -> binary(). decode_error_to_string(Err) -> distribute@codec:decode_error_to_string(Err).