Document stores: removing a connection leaves its unsent copies failing for good, on every *Send now* #511
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#511
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found on 2026-09-29 in a read-only review of postulo at
95348908d, reading the copy scheduler and the connection delete view, and confirmed by callingsend_now()on the snapshot with a failed copy whose connection is gone.Checked again on 2026-10-01 against
mainat0a5cad587: still present. The code is now atdocuments/models.py:843-850(DocumentCopy.connection) andplugins/views.py:464-476(ConnectionDeleteView);documents/archiving.py,core/metrics.pyandcore/importer.pyhave not moved.DocumentCopy.connectionisSET_NULL, so when a person removes a store connection, every copy that had not yet arrived stays behind with nothing to send it to. Nothing clears or closes those rows. Each Send to stores now resets their attempts and fails them again, and the scheduler picks them up again after each press. The document keeps a permanent "failed" line naming the old connection, and the operator's failure gauge counts it for good.documents/models.py:815-822(DocumentCopy.connection,on_delete=models.SET_NULL),plugins/views.py:463-475(ConnectionDeleteView, which does nothing about copies),documents/archiving.py:224-242(send_now: every copy that is notSENTis retried, withcopy.attempts = 0),documents/archiving.py:123-124(send_copyfails a copy with no connection: "The connection is gone or switched off."),documents/archiving.py:173-189(pending_copiesdeliberately keeps copies whose connection row is gone),core/metrics.py:249-250(postulo_failures{kind="document_copies"}counts everyFAILEDcopy).schedule_copiesgives the document a new copy for the new connection, but the old copy hasconnection=NULLand statusfailed. Every Send to stores now on that document then answers "%(sent)d copies sent, %(failed)d failed", or "The copy could not be sent; the document says why" once the new store already has the file, and the document shows a failed copy for a connection that no longer exists. Reproduced on the snapshot: three calls ofsend_now()on such a document each returned(0, 1), and the copy endedfailed,attempts 1, due again five minutes later inpending_copies(). With no press, the scheduler dials it untilMAX_ATTEMPTSand it then staysfailedindefinitely.postulo_failuressees a failure that can never resolve.SENT(apre_deletereceiver onConnection, so the admin and account deletion are covered too, not onlyConnectionDeleteView). KeepSENTcopies, which are the references #130 and the importer (core/importer.py:81-100) mean to keep with no connection behind them. For rows already orphaned, a data migration deletes copies withconnection IS NULLand a status other thansent;send_nowandpending_copiesshould then also excludeconnection__isnull=Truerows that are notSENT, so an orphan can never be retried.Done when
tests/test_stores.pyremoves a store connection that has a failed and a sent copy, and asserts that the failed copy is gone, the sent copy remains withconnectionempty, andsend_now()on the document afterwards returns(0, 0).