Skip to content

Commit 74ddf6b

Browse files
radikenclaude
andcommitted
shadow: per-pod start jitter knob (start_jitter_ms)
Lockstep process starts make every peer pair dial each other at the same simulated instant, forcing simultaneous-dial collisions that never occur on real hosts. pod-i now starts at 5000 + i*start_jitter_ms ms (default 0 keeps lockstep). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 6ee098c commit 74ddf6b

3 files changed

Lines changed: 17 additions & 8 deletions

File tree

src/deployments/experiments/libp2p/shadow_gossipsub.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class ExpConfig(BaseModel):
4747
# Floor (µs) for lsquic engine tick re-arms; needs the tick-floor node image.
4848
# 0 = stock lsquic behavior (which livelocks quic under Shadow).
4949
lsquic_tick_floor_us: NonNegativeInt = 0
50+
# Per-pod process start stagger (pod-i starts at 5000 + i*jitter ms); 0 = lockstep.
51+
start_jitter_ms: NonNegativeInt = 0
5052
# Job-pod resources, sized for ~10 peers; bump for bigger sims.
5153
cpu_request: str = "2"
5254
cpu_limit: str = "4"
@@ -91,6 +93,7 @@ async def _run(self):
9193
model_unblocked_syscall_latency=cfg.model_unblocked_syscall_latency,
9294
strace_logging_mode=cfg.strace_logging_mode,
9395
lsquic_tick_floor_us=cfg.lsquic_tick_floor_us,
96+
start_jitter_ms=cfg.start_jitter_ms,
9497
)
9598
publisher_config = render_publisher_config(
9699
num_nodes=cfg.num_nodes,

src/deployments/shadow/builders.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def render_shadow_yaml(
5656
model_unblocked_syscall_latency: bool = False,
5757
strace_logging_mode: str = "off",
5858
lsquic_tick_floor_us: int = 0,
59+
start_jitter_ms: int = 0,
5960
requester_app_path: str = _REQUESTER_APP_PATH,
6061
) -> dict:
6162
"""Build the shadow.yaml dict: N peer hosts running `./main` + a publisher host
@@ -85,16 +86,21 @@ def render_shadow_yaml(
8586
if discovery == "kad-dht":
8687
peer_env["NODE_ROLE"] = "RoleNormal"
8788
peer_env["SERVICE"] = "bootstrap-0"
88-
peer_process = {
89-
"path": "./main",
90-
"start_time": "5s",
91-
"expected_final_state": "running", # daemon: don't error when alive at stop_time
92-
"environment": peer_env,
93-
}
89+
# start_jitter_ms staggers per-pod process start so peers don't wake and dial at
90+
# one simulated instant (lockstep wakes force simultaneous-dial collisions that
91+
# never occur on real hosts).
9492
hosts = {
9593
f"pod-{i}": {
9694
"network_node_id": 0,
97-
"processes": [peer_process],
95+
"processes": [
96+
{
97+
"path": "./main",
98+
"start_time": f"{5000 + i * start_jitter_ms}ms",
99+
# daemon: don't error when alive at stop_time
100+
"expected_final_state": "running",
101+
"environment": peer_env,
102+
}
103+
],
98104
}
99105
for i in range(num_nodes)
100106
}

src/deployments/shadow/tests/test_builders.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def test_peer_process_is_daemon_with_env(self):
108108
)
109109
peer = sy["hosts"]["pod-0"]["processes"][0]
110110
assert peer["path"] == "./main"
111-
assert peer["start_time"] == "5s"
111+
assert peer["start_time"] == "5000ms"
112112
assert peer["expected_final_state"] == "running"
113113
env = peer["environment"]
114114
assert env["PEERS"] == "3"

0 commit comments

Comments
 (0)