mirror of
https://github.com/kuhyx/signal-bot.git
synced 2026-11-10 19:17:02 +01:00
Bot.listen awaited every frame to completion, so one Commons fetch or one attachment upload held up every text reply behind it (DOCS-latency.md). Each frame now runs in its own task, never more than LIMIT at once; the reader waits for a slot before spawning, so a burst applies back-pressure at the websocket instead of fanning out upstream. One person's commands stay serialised (user_lock.py): two quick !kot would otherwise both pass the cooldown gate before either recorded a use. Every served command reports its timings split into the bot's own time and everybody else's (served.py); /_selftest carries that block and tool/latency.py holds own_ms to 100 ms at p95, with the command's cooldown switched off for the run and put back afterwards. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
55 lines
1.4 KiB
Python
55 lines
1.4 KiB
Python
# Copyright (c) 2026 Krzysztof Rudnicki. MIT licence.
|
|
"""The bot's own share of one reply is everything that is not somebody else's."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from signal_bot.served import OWN_BUDGET_MS, Served
|
|
|
|
|
|
def _kot() -> Served:
|
|
return Served(
|
|
command="cat",
|
|
outcome="ok",
|
|
queue_ms=3,
|
|
dispatch_ms=2,
|
|
handler_ms=1400,
|
|
send_ms=900,
|
|
upstream_ms=480,
|
|
)
|
|
|
|
|
|
def test_own_time_excludes_sends_and_upstream_requests() -> None:
|
|
# 3 + 2 + 1400 of wall clock, of which 900 was signal-cli and 480 the
|
|
# cat API: 25 ms is what this repository's code cost.
|
|
assert _kot().own_ms == 25
|
|
|
|
|
|
def test_as_dict_is_the_selftest_shape_with_the_derived_number_included() -> None:
|
|
assert _kot().as_dict() == {
|
|
"command": "cat",
|
|
"outcome": "ok",
|
|
"queue_ms": 3,
|
|
"dispatch_ms": 2,
|
|
"handler_ms": 1400,
|
|
"send_ms": 900,
|
|
"upstream_ms": 480,
|
|
"own_ms": 25,
|
|
}
|
|
|
|
|
|
def test_a_refusal_has_no_handler_time_and_costs_only_the_gate() -> None:
|
|
refused = Served(
|
|
command="cat",
|
|
outcome="refused_cooldown",
|
|
queue_ms=0,
|
|
dispatch_ms=4,
|
|
handler_ms=0,
|
|
send_ms=0,
|
|
upstream_ms=0,
|
|
)
|
|
assert refused.own_ms == 4
|
|
|
|
|
|
def test_the_budget_is_the_one_the_latency_note_settled_on() -> None:
|
|
assert OWN_BUDGET_MS == 100
|