feat(nostr): sweep republishes events flagged as pending
A flagged row recovers on its own instead of waiting for the next sale that happens to land while the signer is healthy — or for an operator who already knows to run /republish-all, which was the only recovery path and requires knowing about drift that nothing reported. Retrying from the DB rather than an in-memory queue means the retry survives a restart, and it needs no theory about why the publish didn't land: the sweep covers the signer outage of #35 and the silent skip of #51 identically, along with causes nobody has hit yet. Runs every 5 minutes, take-down branch mirroring the publish/delete split the CRUD endpoints already use. Quiet by design — on a healthy instance the query returns nothing and it logs nothing. Refs #35
This commit is contained in:
parent
5d52a231d3
commit
643322131e
2 changed files with 69 additions and 0 deletions
20
crud.py
20
crud.py
|
|
@ -239,6 +239,26 @@ async def get_pending_events() -> list[Event]:
|
|||
)
|
||||
|
||||
|
||||
async def get_events_pending_republish() -> list[Event]:
|
||||
"""Events whose relay copy may be behind this row.
|
||||
|
||||
`nostr_publish_pending` is set before every publish attempt and
|
||||
cleared only on a confirmed success, so a row still flagged here
|
||||
either failed to publish or never got the chance. Drives the
|
||||
reconciliation sweep in `events_start`.
|
||||
|
||||
Ordered oldest-first so a backlog drains in the order it accrued.
|
||||
"""
|
||||
return await db.fetchall(
|
||||
"""
|
||||
SELECT * FROM events.events
|
||||
WHERE nostr_publish_pending = TRUE
|
||||
ORDER BY time ASC
|
||||
""",
|
||||
model=Event,
|
||||
)
|
||||
|
||||
|
||||
async def get_settings() -> EventsSettings:
|
||||
"""Singleton settings row, seeded by m010."""
|
||||
row = await db.fetchone("SELECT * FROM events.settings WHERE id = 1")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue