Mouth: a cap pin serves only the event whose check made it
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
0b06c880d8
commit
34f6dc1c04
2 changed files with 8 additions and 1 deletions
|
|
@ -2124,3 +2124,9 @@ test("display name: a sender with an empty localpart is delivered under its own
|
|||
assert.equal(rounds[0][0].senderDisplay, "@:evil.test");
|
||||
assert.doesNotThrow(() => docs.pendingV4Tuple({ persona: "p", deliveries: rounds[0] }));
|
||||
});
|
||||
|
||||
test("round cap: a pin serves only the event whose check made it: a later event's target past its 60 s keep is read again, as counted", async () => {
|
||||
const { rounds, gets } = await capRun([quoting("$e1", "$x"), quoting("$e2", "$r"), quoting("$e3", "$x")], { lapseOnR: 2000 });
|
||||
assert.deepEqual(rounds.flat().map(d => d.eventId), ["$e1", "$e2", "$e3"]);
|
||||
assert.equal(gets("$x"), 2, "the read at t0 and one re-read for $e3");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ export function createMouth({
|
|||
const REPLY_READS_PER_ROUND = 8; // target GETs one sync round may make, whoever asks (basis or reply_to): an event whose uncached targets would pass it waits for the next round
|
||||
const KEEP_HIT_MS = 10 * 60 * 1000; // how long transient failures may keep a hit's sender alive after its last good read
|
||||
let replyReads = 0;
|
||||
const held = new Map(); // key -> entry: targets the round's cap check counted as cached, kept for the round so the 60 s keep cannot lapse between the check and the read and spend a GET the check did not count
|
||||
const held = new Map(); // key -> entry: targets the round's cap check counted as cached, kept for that event so the 60 s keep cannot lapse between the check and the read and spend a GET the check did not count
|
||||
const cachedTarget = key => {
|
||||
const known = authors.get(key);
|
||||
if (!known) return null;
|
||||
|
|
@ -382,6 +382,7 @@ export function createMouth({
|
|||
const relates = event.content["m.relates_to"];
|
||||
if (!replyLink || formOf(event.content) !== "message") return 0;
|
||||
const ids = new Set([relates?.["m.in_reply_to"]?.event_id, relates?.rel_type === "m.thread" ? relates.event_id : undefined].filter(id => typeof id === "string" && id !== ""));
|
||||
held.clear(); // events run one at a time: a pin serves only the event whose check made it
|
||||
let reads = 0;
|
||||
for (const id of ids) {
|
||||
const key = `${roomId} ${id}`, hit = cachedTarget(key);
|
||||
|
|
|
|||
Loading…
Reference in a new issue