Instead of on every start: the schema is defined in one place again. Postgres gets
idx_message_topic_published_id (topic, published, id), SQLite idx_topic_published_time (topic,
published, time), both with IF NOT EXISTS (ntfy.sh got the Postgres one by hand). A downgrade to
v2.31.0 or earlier now needs the schema version set back by hand, as described in the release notes;
from v2.31.1 on, a newer schema only logs a warning (#2059).
Older ntfy versions read and write the version table as it always was: on SQLite the row id = 2
holds the minimum, on Postgres the row "<store>:min". No ALTER TABLE, no column check; a missing
row means 1. Two tests that read the SQLite version table without a WHERE now ask for id = 1.
SQLite gets a nop 15 -> 16 so the two backends keep the same version numbers;
the claim column is Postgres-only because SQLite is single-node by definition.
Also fixes a comment that no longer matched the code: claimMessagesDue stopped
marking rows published two commits ago.
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