MultiNodeWarpSim

Multi-node warp simulation harness for use in tests. See the file-level KDoc for the full determinism contract and setup ceremony; construct via multiNodeWarpSim or — preferably — run the whole test through warpSimTest.

The harness owns the mesh (loom), one Seam and one WarpNode per peer, and the shared execution log the default tracked-echo registries record into.

Properties

Link copied to clipboard

The in-process mesh all seams are woven on.

Link copied to clipboard

Live node map — entries are removed by disconnect.

Link copied to clipboard

Peer ids in join order (peer-1 hosts; the rest joined in index order).

Link copied to clipboard

The Quilter cadence every node runs on — settle derives its pump interval from it.

Link copied to clipboard

Each peer's Seam on the mesh.

Link copied to clipboard

A virtual clock reading the test scheduler's current time — the clock every default node runs on. Pass it to any extra WarpNode a custom nodeFactory builds so ring stamps and settle windows share the test's virtual timeline.

Functions

Link copied to clipboard
suspend fun awaitResults(taskIds: Collection<TaskId>, on: Collection<PeerId> = nodes.keys.toList(), within: Duration = DEFAULT_AWAIT)

Suspend until every node in on has a result for every id in taskIds; fail fast with a state dump otherwise. The standard "tasks executed and boards converged" await.

Link copied to clipboard
suspend fun awaitTrue(what: String, within: Duration = DEFAULT_AWAIT, cond: () -> Boolean)

Suspend until cond holds, polling every virtual millisecond; fail fast with a state dump after within virtual time otherwise. The generic bounded await underneath awaitResults.

Link copied to clipboard
fun closeAll()

Close every live node and cancel its scope. Called by warpSimTest at teardown.

Link copied to clipboard
suspend fun disconnect(id: PeerId)

Remove id from the mesh: close its node, tear its seam (it disappears from every other peer's roster), and cancel its coroutines. The departed-peer scenario — surviving nodes rebuild their rings and re-home the peer's tasks.

Link copied to clipboard
fun dumpState(reason: String): String

Render a per-node diagnostic snapshot — results-board sizes, execution / failover / duplicate counters, and the tracked execution log — so a non-converging mesh names itself instead of just timing out. Used as the body of the AssertionError thrown by the bounded await helpers, and callable directly from a failing assertion.

Link copied to clipboard

The TaskDescriptor uses: WARP_SIM_ECHO_OP with the task id as args.

Link copied to clipboard
fun enqueueEcho(taskId: TaskId, on: PeerId = peerIds.first())

Enqueue taskId as a tracked echo task on the node of on (default: the host).

Link copied to clipboard
fun executedBy(taskId: TaskId): List<PeerId>

Every peer that executed taskId, in execution order (empty if none has yet).

Link copied to clipboard

All task ids that have been executed by at least one peer.

Link copied to clipboard
fun node(index: Int): WarpNode

The live node at join-order index. Fails if it was disconnected.

Link copied to clipboard
fun peer(index: Int): PeerId

The peer id at join-order index (0-based; index 0 is the host).

Link copied to clipboard
fun recordExecution(peer: PeerId, taskId: TaskId)

Record that peer executed taskId. Called by trackedEchoRegistry ops; call it from custom ops to keep executedBy / executedTaskIds (and dumpState) accurate.

Link copied to clipboard
suspend fun settle(rounds: Int = DEFAULT_SETTLE_ROUNDS)

Advance virtual time through rounds anti-entropy intervals, one claim settle window (when strategy has one), then rounds more intervals — the bounded, fixed-budget drain for "let the mesh converge / prove it stays quiet" phases. For waits with a concrete target, prefer awaitResults / awaitTrue: they finish as soon as the condition holds and fail fast with a dump when it never does.

Link copied to clipboard
fun taskOwnedBy(owner: PeerId, prefix: String = "task"): TaskId

A TaskId ("$prefix-<i>") that the consistent-hash ring assigns to owner under the full-mesh roster — lets a test target a specific node deterministically. Matches the ring WarpNode builds (TaskRing defaults) while all peers are live and unpartitioned.

Link copied to clipboard

An OpRegistry with one pass-through op, WARP_SIM_ECHO_OP, that records every invocation into the sim-wide execution log (executedBy / executedTaskIds) before echoing its args. The default registry for every node; call from a custom registryFactory to keep tracking while adding further ops.