Commit Graph
8 Commits
Author SHA1 Message Date
binwiederhier e536434097 Pass the BatchingQueue buffer size from the caller
The message cache decides how many batches may wait for its writer (queueBufferedBatches in
message/cache.go, next to the shutdown flush timeout it has to fit in); util stays policy-free.
2026-10-07 12:30:36 +00:00
binwiederhier 99d55175d4 Keep the message batch writer ahead of publish bursts
On cron bursts (top of the hour), the single batch writer fell behind: it wrote one INSERT round
trip per message, so against a busy remote Postgres it managed ~100 rows/s while ~300/s arrived.
New messages took up to ~40s to reach the database (polls missed them), and publishes blocked on
the unbuffered queue for up to ~25s.

- Postgres: write each batch with one multi-row INSERT (up to 1000 rows per statement) instead of
  one statement per row. SQLite keeps the row-by-row path.
- Skip DeleteScheduledBySequenceID when the client did not set a sequence ID: the sequence ID is
  then the message's own fresh ID, so no scheduled message can match. This saves a transaction on
  the primary for almost every publish.
- Buffer up to 100 batches in the BatchingQueue, so a briefly slow writer does not stall publishes.
- dbtest: add a latency proxy (CreateTestPostgresWithLatency, WithLatency) to test round trips.
2026-10-07 11:54:46 +00:00
binwiederhier bc1e879dc4 Persist batched messages on shutdown; graceful SIGTERM in serve
With cache-batch-size/-timeout set (ntfy.sh: 100 / 1500ms), accepted messages
wait in a BatchingQueue before they are written. Nothing drained that queue on
shutdown, and `ntfy serve` did not handle SIGTERM at all (only SIGHUP), so
every restart dropped up to one batch timeout's worth of accepted messages
from the cache: live subscribers got them, pollers and since= replays never
did.

- util.BatchingQueue.Close emits the pending elements and closes the output
  channel (Enqueue after Close is a no-op)
- message.Cache.Close closes the queue and waits for the batch writer before
  closing the database
- serve stops the server on SIGTERM/SIGINT and waits for Stop to finish (Run
  returns as soon as the listeners close); Stop is idempotent now, since the
  signal handler and serve both call it
2026-10-03 15:06:09 +00:00
binwiederhier 22f48c5ad3 Change mod path 2023-11-16 20:54:58 -05:00
Philipp Heckel db9ca80b69 Fix race condition making it possible for batches to be >batchSize 2022-11-16 11:16:07 -05:00
Philipp Heckel e147a41f92 Fix race in tests 2022-11-16 10:44:10 -05:00
Philipp Heckel ad860afb8b Polish async batching 2022-11-16 10:28:20 -05:00
Philipp Heckel b4933a5645 WIP: Batch message INSERTs 2022-11-15 14:24:56 -05:00