fix(modules): stop a module before purging its tables #146
Reference in New Issue
Block a user
No description provided.
Delete Branch "fix/module-uninstall-stop-before-purge"
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?
Phase 4 slice 4's website half. Found while proving acceptance criterion 2 — "uninstall leaves the data, purge removes it" — against the real
module-uov0.3.0 release on a brand-new empty database. The criterion passes; this is what running it turned up.The defect
DELETE /admin/modules/:id?purge=trueran in the order purge → stop → removeDir. Sopurge.sqldropped 27 tables while the module was stillstarted, and it stayed started untillifecycle.stop()finished — up to the five-secondonShutdownbudget. In that window the module is serving and ingesting against a schema that no longer exists: module-uo's uo-link WebSocket keeps writing shard events into dropped tables, and requests in flight answer 500 where a stopped module answers 404.Why the old order was not required
The comment justified it as "purge while the SQL is still readable". But
install.purgeFile()readsmodule.jsonoff disk andlifecycle.stop()touches no filesystem —removeDiris the only destructive step, and it is last either way. So purge only ever had to precede the delete, never the stop.New order: resolve the purge file → stop → purge → removeDir → removeRow. The 400 for a module that ships no
purge.sqlis resolved before anything is stopped, so a request that is going to be refused leaves the module exactly as it found it — previously it would have been a 400 that took the module down as a side effect (it happened not to, only because the check preceded the stop by accident of position).Trade-off, stated
If the purge now fails, the module is left stopped-and-disabled rather than untouched. That is recoverable from the panel (Enable, then Restart); a live module on a half-dropped schema is not.
Tests
The existing order test now pins both orderings in one assertion —
['stop', 'purge', 'removeDir', 'removeRow']— with the reason each is one line away from being wrong written next to it, plus a new test that a refused purge stops nothing.routes.manifest.jsonandswagger/swagger-output.jsonregenerated: byte-identicalThe smoke this came out of
Real Gitea release URL, empty
purge_smokedatabase, isolated modules volume:startedpurged: 27, every table gone, row gone, directory gonestarted/ whiledisableddisabledAI disclosure
🤖 Generated with Claude Code
https://claude.ai/code/session_018ocYxQWk3EhZe5gWRJXFU8