Skip to main content

Module wan_presence

Module wan_presence 

Source
Expand description

Publish this install’s presence record to the account’s relay, so a signed-in phone off the LAN can list it (agentmux-mobile’s SPEC_FLEET_HOST_TAGS_AND_CLOUD_HOSTS_2026_10_06 §6.3).

The record (agentmux_common::install_presence, version 2) is built from the LAN fleet feed’s snapshot (agent names, kinds and states, the channel count) plus this install’s platform, hostname, channel and version, and signed with the WAN instance key, the same identity wan_publish certifies agent keys with. It goes to the account the shared MuxBus sign-in names, with the same token and relay base URL wan_publish uses.

When. The rules live in machine, a pure state machine (signed_out, publishing, retrying, unsupported, rejected); Driver runs it. While publishing: on start, on every change of the agents, their kinds or the channel count (debounced DEBOUNCE), on a change of agent states alone at most every STATE_MIN_INTERVAL (agentmux-mobile’s SPEC_AGENT_STATUS_AND_LIVE_PANE_FEED_2026_10_07 §3.3, so busy agents don’t publish on every turn), and every minute otherwise. A failure backs off with jitter; a relay without the route (404) is tried again within minutes, and at once on a sign-in, a network change, a wake from sleep or a new relay version. Not signed in: no request at all. One request at a time, so an older record never lands after a newer one. Neither the token nor the signature is ever logged.

Goodbye. On a clean quit (goodbye_on_shutdown), a sign-out (goodbye_before_sign_out, then signed_out) and when publishing is turned off, one last record (v3, gone) tells the relay this computer went offline, so devices stop listing it as live at once rather than minutes later. Best effort, at most GOODBYE_TIMEOUT; a relay that refuses it (an older one) is not asked again, and nothing waits on it.

Who publishes is policy: not a dev build, a headless srv, an isolated home or a test harness, unless forced; never when the setting is off.

presence.status reads status; presence.publish-now calls publish_now; a sign-in calls sign_in_changed; a change of the settings calls settings_changed.

Modules§

machine 🔒
The presence publisher’s decisions, apart from its I/O. Given what just happened (Event) and the time (Now), Machine::next settles the state, says what to do (Action) and how long to wait before the next Event::Due. Nothing here reads a clock, a random number or the network, so every rule is tested with a fake clock; super::Driver runs it against the relay.
policy 🔒
Which installs publish their presence. A normal signed-in desktop does, unless the user turns off “Publish this computer to my devices” (cloud:publishpresence, setting_on). A task dev build, a headless srv, an isolated home and a test harness don’t by default: each would leave an entry in the account’s list of computers that is not a computer anyone uses. FORCE_ENV turns publishing on for one of those, for testing presence itself; the setting still wins over it.

Structs§

Driver 🔒
Runs Machine against the relay: does what each step says, then waits for the step’s wait, a signal (Event::SignIn, Event::PublishNow, Event::NetworkChanged, Event::Woke, Event::SettingsChanged, Event::Goodbye) or a change of the snapshot. While publishing, a change is debounced as before; otherwise it only marks the record dirty.
LiveSession 🔒
Publisher 🔒
The running publisher’s session and relay, for a goodbye said from outside the driver.
RelayReply 🔒
What one relay request came to: the answer, and the relay’s clock.
Shared 🔒
What the driver shares with the rest of srv.
Timing 🔒
The publisher’s waits, apart so tests can shorten them.

Constants§

DEBOUNCE 🔒
A change is published once the agents, kinds and channel count have been quiet this long.
GOODBYE_TIMEOUT 🔒
The longest a goodbye may take, so a quit or a sign-out is never held up.
LIVE_TIMING 🔒
OUT_OF_BOUNDS 🔒
PUBLISH_TIMEOUT_SECS 🔒
STATE_MIN_INTERVAL 🔒
The least time between two publishes when only agent states changed.
WAKE_SLACK 🔒
A watch tick this much later on the wall clock than it should be means the computer slept in between.
WATCH_EVERY 🔒
How often the network addresses and the clock are looked at, for a network change or a wake from sleep.

Statics§

PUBLISHER 🔒
SHARED 🔒
SIGNALS 🔒

Traits§

Session 🔒
What a try needs besides the relay: the sign-in, the signed record, and whether to publish at all.

Functions§

attempt 🔒
One try: the record for snapshot as version v, or nothing without a sign-in.
build_record 🔒
The record for snapshot, as version v. An agent whose kind isn’t known is left out: the record requires one, and the feed doesn’t guess. An agent whose state isn’t known carries none, and one with no line no line.
farewell_from 🔒
Hold the publisher and say goodbye if one is due: whether the relay stored it. At most GOODBYE_TIMEOUT.
farewell_now 🔒
goodbye_before_sign_out 🔒
A sign-out, before the sign-in is cleared (the goodbye needs it): say goodbye, at most GOODBYE_TIMEOUT, and publish nothing more until signed_out. Whether the relay stored it.
goodbye_on_shutdown 🔒
A clean quit: say goodbye, at most GOODBYE_TIMEOUT. Nothing is published after it.
header_date 🔒
network_addresses 🔒
This computer’s addresses, loopback aside, sorted; None when they can’t be read.
network_changed 🔒
Whether the addresses moved; an unreadable list is no change.
parse_http_date 🔒
An HTTP date (Date, Retry-After) as unix ms.
parse_retry_after 🔒
Retry-After: seconds, or a date read against the relay’s own Date (else this computer’s clock).
publish_now 🔒
Forget the backoff and try at once. False when no publisher runs.
put_presence 🔒
PUT /wan-instances/:instance_id/presence. A pure HTTP operation, like wan_publish::publish_record, so tests can point it at a stub.
random_unit 🔒
Uniform in [0, 1), for jitter, from the OS’s random source.
relay_health 🔒
The relay’s unauthenticated GET /api/health: its version, and its clock.
send_goodbye 🔒
Send the goodbye for snapshot (v3, gone): whether the relay stored it, which only a 2xx says (a 409 means it kept a newer, live record). Gives up after timeout. A relay that refuses v3 (an older one) gets nothing more: the record is never sent again as v1 or v2.
settings_changed 🔒
The settings changed: whether to publish is read again.
settle 🔒
Wait until the agents, kinds and channel count have been quiet for DEBOUNCE, at most a publish interval in all. A change of states alone does not restart the wait: busy agents would otherwise hold a new agent back for the full interval. false on shutdown.
sign_in_changed 🔒
A sign-in, sign-out or account change in this process: try at once.
signed_out 🔒
The sign-in is cleared (or clearing it failed): publishing may go on, and the status says “signed off” when the goodbye was stored.
spawn 🔒
Start the publisher. No-op without a WAN identity store (nothing to sign with). headless is srv’s --headless (policy). Stops with token (srv shutdown).
status 🔒
The publisher’s status; None until it has one (or without a publisher).
structure_changed 🔒
Whether anything but agent states and lines differs: the agents, their kinds or the channel count.
wait_to_publish 🔒
After a change of the snapshot, wait until it is time to publish: a change of the agents, kinds or channel count once those have settled (settle); a change of agent states or lines alone once STATE_MIN_INTERVAL has passed since sent_at. A structural change during that wait switches to settling. false on shutdown.
watch_network_and_sleep 🔒
Every WATCH_EVERY, tell the publisher about a wake from sleep or a change of network addresses. Cheap: a clock read and the interface list.
woke 🔒
Whether the computer slept between two watch ticks tick apart: the wall clock moved much further than the monotonic clock (which stops during sleep on Linux and macOS), or much further than the tick itself (where the monotonic clock runs on through sleep).