A tap's span ends with its own requests' answers (#379)

traceparent keeps one trace for any request within a minute of the last,
and the tap span ran to the last answer in that trace, so a live update's
refresh 13 s later made a tap answered in 0.9 s read as 15 s (trace
a895551d20626fb6dc071d336262b772). Now a request counts towards the tap
only when one of the tap's own is in flight or it begins within two
seconds of the tap or its last answer; it still joins the trace.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 02:05:31 +00:00
parent 5ee633e700
commit 08b28f0598
3 changed files with 26 additions and 6 deletions

View File

@@ -243,6 +243,19 @@ test('a tap is its trace\'s root span, reported with its ids once it has an answ
assert.deepEqual([body.ev, body.ms, body.msg, body.span.length, body.trace.length], ['tap', 250, 'keydown', 16, 32]);
});
test('a request begun long after a tap\'s last answer does not stretch the tap (#379)', async () => {
run(`globalThis.sent = []; fetch = (url, o) => { sent.push([url, o]); return Promise.resolve({ ok: true, status: 204 }); }`);
run(`newTrace('pointerdown'); traceAt = Date.now()`);
await run(`api('/api/a')`);
const answered = run('answeredAt');
assert.ok(answered >= run('rootAt'), 'its own request ends it');
run('answeredAt -= 5000; rootAt -= 5000');
await run(`api('/api/later')`);
assert.equal(run('answeredAt'), answered - 5000, 'a refresh five seconds on is not the tap\'s');
assert.equal(run('tapBusy'), 0);
run(`rootKind = ''`);
});
test('a tap ended over a minute after its last request reports once, without recursing (#378)', () => {
run(`globalThis.sent = []; fetch = (url, o) => { sent.push([url, o]); return Promise.resolve({ ok: true, status: 204 }); }`);
run(`newTrace('pointerdown'); answeredAt = rootAt + 100; traceAt = Date.now() - 120_000`);