fix(11-07): roll back the savepoint when a swallowed read failed
- beachcomber and lighthouse released their savepoint whenever the inner function reported no error; a Gate that counts a failed read as off, or a channel function or delete snapshot that swallows one, left the caller's Postgres transaction aborted (25P02) and failed the write - a failed RELEASE now rolls back to the savepoint, as the READMEs promise - beachcomber gets its testcontainers harness and sync tests (TestSyncGates, TestSyncAfterCommit, TestSyncDeleteAndSoftDelete, TestSyncFailuresNonFatal, TestServiceSetup); lighthouse gets TestBroadcastSwallowedReadFailure
This commit is contained in:
@@ -31,7 +31,7 @@ The package itself knows no search server. An engine package registers itself fr
|
||||
|
||||
## Sync semantics
|
||||
|
||||
- **After commit.** The callbacks register the sync with `lagoon.AfterCommit`. Inside `lagoon.Transaction` it runs after that transaction commits, and not at all when it rolls back. A single-statement write, for which GORM opens its own transaction, syncs after that commit and not when the write fails. Inside a plain `gorm` transaction there is no commit hook, so the sync runs immediately through the transaction's handle. Its reads run in a savepoint, so a failed read never aborts the caller's transaction.
|
||||
- **After commit.** The callbacks register the sync with `lagoon.AfterCommit`. Inside `lagoon.Transaction` it runs after that transaction commits, and not at all when it rolls back. A single-statement write, for which GORM opens its own transaction, syncs after that commit and not when the write fails. Inside a plain `gorm` transaction there is no commit hook, so the sync runs immediately through the transaction's handle. Its reads run in a savepoint, so a failed read never aborts the caller's transaction, including a read that the application Gate swallows and counts as off.
|
||||
- **Inline and non-fatal.** The sync runs in the writing goroutine, after the commit, so a create followed by a search sees the document. Every engine request is bounded by the engine's timeout (`search.typesense.connection_timeout_seconds`), and the caller's context cancellation does not abandon it. A failure, a timeout or a panic is logged at Warn as `search: sync failed` with the index, key and operation. The write is already committed and stays so. The log never carries the document or the API key.
|
||||
- **Three gates, before any request.** Nothing is sent when:
|
||||
1. the engine is not configured (the `null` engine, or Typesense with an empty `search.typesense.api_key`);
|
||||
|
||||
Reference in New Issue
Block a user