delivery

command
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 19, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

README

Coordinated update delivery

This guest compares two ways to deliver one small configuration update from an origin to the other participants. Each participant runs the same WASM program with a distinct role. Role 0 is the origin. The group can contain 2–8 distinct executors; the demonstration uses five.

The guest opens no external service and needs no executor upgrade when its application algorithm changes. It uses the existing group readiness exchange, requested start and TCP listener, plus the optional debuglet_io_v1.accept_tcp extension. Executors must support that bounded accept operation. Build the guest with the supported compiler:

GOOS=wasip1 GOARCH=wasm go build -trimpath -ldflags='-s -w' \
  -o delivery.wasm ./examples/experiments/delivery

Use the ordinary experiment runner or console grouped custom program flow. Give every participant the same delivery.wasm and arguments below, changing only -role from 0 through 4:

-algorithm=direct -role=0 -participants=5 -deadline-ms=5000
-retry-ms=250 -repair-ms=750 -payload-bytes=512 -update-id=demo-1
-blocked-from=-1 -blocked-to=-1

Arguments are the complete WASI argument vector: Debuglet does not insert a program name before -algorithm. Do not add an executable-name argument.

Enable listen_tcp, allow the participants' reachable listener addresses in both operator and submitted destination policies, and reserve the same limits for each algorithm. A 60-second host run limit leaves room for group readiness and the five-second application window. The example generates a deterministic 512-byte update; its content hash is verified after reception. This is a small configuration delivery experiment, not a software download benchmark.

Endpoints come exclusively from each participant's readiness metadata. Roles, algorithm and settings must agree, and executors, run IDs and listener endpoints must be distinct. Metadata does not grant network access. Use actual published TCP endpoints when hosts map ports; no UDP support or NAT traversal is assumed.

Algorithms

direct queues a copy for every recipient without waiting for any recipient's acknowledgement. Unacknowledged copies are retried every retry-ms. Socket operations are bounded and serviced sequentially; multiple copies may be in flight, but the guest does not claim parallel Go socket execution.

relay first uses a binary tree: a role's parent is (role-1)/2. With five participants the edges are 0→1, 0→2, 1→3 and 1→4. A recipient verifies the update, forwards it to its children and acknowledges both the origin and its immediate sender, avoiding a duplicate ACK when those are the same node. Each sender retries its unacknowledged copies using the same interval as direct delivery.

After repair-ms, the origin asks an already acknowledged participant to resend to each missing recipient. Helpers rotate in role order on subsequent repair rounds. Only verified recipients can act as helpers. Duplicate data is verified and acknowledged again without reapplying the update or restarting the tree. Repeated repair can therefore recover a lost acknowledgement as well as a missing data message. This is a bounded repair rule, not a general gossip, routing, election or membership protocol.

All participants keep receiving until their local application deadline, even after their own update is verified or the origin has all ACKs. This lets them answer late duplicates and repair requests. Origin completion time is recorded once, on the last distinct valid recipient ACK; waiting afterward does not increase that duration. No messages are deliberately started after the local deadline. Accept waits at most 20 ms, connect at most one second, and accepted reads/writes at most 250 ms, each additionally bounded by the remaining window. An unreachable endpoint can delay servicing other messages within those bounds.

Controlled comparison

Run both algorithms in the healthy case first. Keep participant roles, update, resource limits, deadline and settings fixed between paired trials.

-blocked-from=0 -blocked-to=1 selects a simulated connection failure in that direction. The sending guest suppresses every application message kind on that directed pair before opening a socket. No bytes are transmitted for a suppressed send, and a separate simulated_failure event records the decision. All participants must receive the same setting. The healthy setting is -1 for both fields.

This is an application fault model, not measured packet loss, a TCP reset, a router fault or evidence about an ISP. It does not bypass destination policy. Useful comparisons include:

  • 0→1 breaks a direct recipient and the relay tree's first hop; an acknowledged helper can repair the relay branch.
  • 1→3 breaks a relay edge while leaving the direct baseline unaffected; it demonstrates repair overhead without guaranteeing that relay wins.
  • 4→0 blocks a recipient's ACKs to the origin. That recipient may verify the update while the origin still reports a missing ACK.

Healthy direct delivery can be faster and cheaper. Report each observed result instead of declaring an algorithm universally better. A few live trials are demonstrations, not statistical performance estimates. Five executors on one machine are five local instances, not five geographic vantage points.

Output contract

Every stdout line is JSON with schema: "debuglet.delivery.v1", type, algorithm, role, participants, experiment_id, run_id, and update_sha256. Setup failures may have empty experiment/run/hash values.

Events have type: "event", event and elapsed_ms. Time is local to that guest's actual start; readiness uses zero. Events are ready, start, send, receive, verified, acknowledged, repair, send_error, invalid_message and simulated_failure. Network events include peer_role, message_kind (data, ack or repair) and bytes; invalid frames have only their received byte count. A helper's repair event names the recipient it was asked to help. The ready event also includes config.

send means the complete frame was accepted by the local socket write; it does not prove remote delivery. receive follows frame and protocol validation. verified is emitted once after payload hash verification. acknowledged is emitted by the origin for each newly acknowledged recipient. Draw directed message edges only from observed send/receive records, not from the static tree or a missing result. Do not order different hosts' events as if their local elapsed clocks were synchronized.

Each guest finishes with type: "summary" and:

Field Meaning
outcome complete, deadline or error; non-origin completion means its own update was verified
verified Whether this participant verified the update; the origin starts with its own verified payload
completion_ms Origin-local elapsed time to all recipient ACKs, otherwise null
finished_ms Local elapsed time when this guest summarizes
acked_roles, missing_ack_roles Origin only; distinct recipient roles, excluding role 0
sent_bytes, received_bytes Application bytes actually written/read, including four-byte length prefixes and every data, ACK and repair frame; partial operations are included
send_errors, simulated_failures Real failed sends and simulated suppressed sends counted separately
duplicates Valid duplicate update messages received
config deadline_ms, retry_ms, repair_ms, payload_bytes, update_id, blocked_from, blocked_to
error Present on a setup/runtime error

Use the origin's ACK summary for experiment completion. A missing ACK is not proof of non-delivery. A missing guest summary remains unknown. An origin may record all ACKs and later report a runtime error; retain both observations. Aggregate sent application bytes across participants for traffic comparisons; adding sent and received totals counts the same transfer twice. These are not wire-byte or independently authenticated accounting claims. The framing and hash detect malformed or inconsistent updates, not malicious participants.

Bounds are 1–512 payload bytes, 1–64 bytes for the update ID, a 1000–15000 ms application window, a 100–2000 ms retry interval and retry-ms <= repair-ms < deadline-ms. Frames are limited to 2048 JSON bytes. The host lifetime, permission and resource limits remain authoritative. Failed group submission must be inspected using its retained receipt, never blindly replayed as a replacement experiment.

Documentation

Overview

delivery compares direct fan-out with peer-assisted delivery of one update.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL