Skip to content

Commit 9a8d47f

Browse files
feat(xdbg): V3→V4 migration latency monitor (#3338)
## Summary - Adds a **V3→V4 migration latency test** to xdbg (`test migration-latency` subcommand) - Integrates the test into the **client monitor entrypoint.sh loop** (runs every 5 minutes alongside identity/group/message tests) - Fixes a **pre-existing bug** where all PushGateway metric pushes silently failed (fire-and-forget `tokio::spawn` was cancelled when short-lived xdbg subprocesses exited) ## What it does 1. Creates a V3 identity and group on production 2. Sends a tagged message via V3 3. Polls the V4 testnet replication node until the message appears (or times out) 4. Records `xdbg_migration_latency_seconds` histogram, `xdbg_migration_success_total` / `xdbg_migration_failure_total` counters 5. Pushes all metrics to PushGateway (awaited, not fire-and-forget) ## Key design decisions - Migration test always uses V3 **production** and V4 **testnet** (`grpc.testnet.xmtp.network`), regardless of `WORKSPACE` env — this is the only migration path that exists - `push_metrics()` and `record_phase_metric()` changed from sync/spawn to **async with `.await`** — this fixes metrics for ALL existing tests (identity, group, message), not just migration ## Files changed - `src/app/test.rs` — new `migration_latency_test()` + `.await` on existing push calls - `src/metrics.rs` — dedicated migration histogram/counters + async push fix - `src/args.rs` — `MigrationLatency` variant + CLI args - `docker/entrypoint.sh` — migration test integration in loop - `src/app/generate/{identity,groups,messages}.rs` — `.await` on push calls (async fix) ## Verified in production Deployed to testnet-dev ECS, two full loop iterations confirmed: - Migration latency: **2.2s – 3.9s**, 100% success rate - All metrics flowing to PushGateway (zero push errors) - Identity, group, message tests all passing
1 parent 2f6afaa commit 9a8d47f

7 files changed

Lines changed: 408 additions & 30 deletions

File tree

apps/xmtp_debug/docker/entrypoint.sh

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
# monitoring loop — the daemon recovers on the next iteration.
55
set -uo pipefail
66

7-
: "${XDBG_LOOP_PAUSE:=300}" # default interval between loop iterations
7+
: "${XDBG_LOOP_PAUSE:=300}" # default interval between loop iterations
8+
: "${XDBG_V4_NODE_URL:=}" # V4/D14N node URL for migration latency test
9+
: "${XDBG_MIGRATION_TIMEOUT:=120}" # timeout for migration latency polling
810

911
function log {
1012
echo "[$(date '+%F %T')] $*"
@@ -20,6 +22,13 @@ case "${WORKSPACE}" in
2022
esac
2123
log "WORKSPACE='${WORKSPACE:-<unset>}' -> backend='${BACKEND}'"
2224

25+
# Migration test: always writes to V3 production and reads from V4 testnet,
26+
# because the only migrator path is V3 production → V4 testnet.
27+
# XDBG_V4_NODE_URL can be overridden via env, but defaults to the testnet
28+
# D14N replication node regardless of WORKSPACE.
29+
: "${XDBG_V4_NODE_URL:=https://grpc.testnet.xmtp.network:443}"
30+
log "V4 node URL (migration): ${XDBG_V4_NODE_URL}"
31+
2332
while true; do
2433
log "Reset environment.."
2534
XDBG_LOOP_PAUSE=0 xdbg -d -b "${BACKEND}" --perf --clear \
@@ -46,6 +55,17 @@ while true; do
4655
|| log "WARNING: message step $x failed"
4756
log "Running health checks..."
4857
bash "$(dirname "$0")/web-healthcheck.sh" || log "WARNING: health check failed"
58+
59+
# Migration latency test: always V3 production → V4 testnet (the only migration path).
60+
# Omits -d and --perf (D14N mode) since this writes to V3.
61+
# Uses -b production regardless of WORKSPACE.
62+
log "Migration latency test..."
63+
XDBG_LOOP_PAUSE=0 xdbg -b production test migration-latency \
64+
--v4-node-url "${XDBG_V4_NODE_URL}" \
65+
--migration-timeout "${XDBG_MIGRATION_TIMEOUT}" \
66+
--iterations 1 \
67+
|| log "WARNING: migration latency test $x failed"
68+
4969
log "Sleeping ${XDBG_LOOP_PAUSE} seconds..."
5070
sleep "${XDBG_LOOP_PAUSE}"
5171
done

apps/xmtp_debug/src/app/generate/groups.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ impl GenerateGroups {
8686
create_secs,
8787
"group_create",
8888
"xdbg_debug",
89-
);
89+
)
90+
.await;
9091

9192
if let Some(ref invitee) = first_invitee {
9293
check_member_visibility(&group_id, invitee, &network_clone).await;
@@ -99,7 +100,8 @@ impl GenerateGroups {
99100
total_secs,
100101
"group_total",
101102
"xdbg_debug",
102-
);
103+
)
104+
.await;
103105

104106
bar_pointer.inc(1);
105107

@@ -207,7 +209,7 @@ async fn create_group_on_network(
207209
member_ids.len() as f64,
208210
&[("phase", "add_members")],
209211
);
210-
push_metrics("xdbg_debug");
212+
push_metrics("xdbg_debug").await;
211213

212214
let group_id = group.group_id.clone();
213215
drop(client_guard);
@@ -261,5 +263,5 @@ async fn check_member_visibility(
261263
visibility_secs,
262264
&[("phase", "member_visibility"), ("success", vis_ok)],
263265
);
264-
push_metrics("xdbg_debug");
266+
push_metrics("xdbg_debug").await;
265267
}

apps/xmtp_debug/src/app/generate/identity.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ impl GenerateIdentity {
8686
init_secs,
8787
"client_init",
8888
"xdbg_debug",
89-
);
89+
)
90+
.await;
9091

9192
bar_pointer
9293
.set_message(format!("generated client {}", c.identity().inbox_id()));
@@ -197,7 +198,8 @@ impl GenerateIdentity {
197198
register_secs,
198199
"register",
199200
"xdbg_debug",
200-
);
201+
)
202+
.await;
201203

202204
Ok(identity)
203205
}
@@ -309,7 +311,7 @@ async fn poll_association_readiness(network: &args::BackendOpts, inbox_id_hex: &
309311
1.0,
310312
&[("phase", "assoc_ready"), ("success", assoc_ok)],
311313
);
312-
push_metrics("xdbg_debug");
314+
push_metrics("xdbg_debug").await;
313315

314316
Ok(())
315317
}
@@ -334,7 +336,8 @@ async fn measure_sync_and_lookup(
334336
sync_secs,
335337
"identity_read_sync",
336338
"xdbg_debug",
337-
);
339+
)
340+
.await;
338341

339342
// -- identity lookup latency --
340343
let t_lookup = Instant::now();
@@ -349,7 +352,8 @@ async fn measure_sync_and_lookup(
349352
lookup_secs,
350353
"identity_read",
351354
"xdbg_debug",
352-
);
355+
)
356+
.await;
353357

354358
Ok(())
355359
}
@@ -375,7 +379,8 @@ async fn verify_identities_readable(
375379
verify_secs,
376380
"verify_identity_read",
377381
"xdbg_debug",
378-
);
382+
)
383+
.await;
379384
}
380385
Ok(())
381386
}

apps/xmtp_debug/src/app/generate/messages.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ impl GenerateMessages {
321321
let send_latency = start.elapsed();
322322
let send_secs = send_latency.as_secs_f64();
323323

324-
record_phase_metric("send_message", send_secs, "send_message", "xdbg_debug");
324+
record_phase_metric("send_message", send_secs, "send_message", "xdbg_debug").await;
325325

326326
Ok(send_latency)
327327
} else {

0 commit comments

Comments
 (0)