Repository navigation
server: support opt-in mutation images for Recorder - #5
Merged
Merged
Conversation
This was referenced Oct 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Recorder consumers currently receive only a key and patch, so they cannot describe the value immediately before deletion or distinguish intermediate mutations by reading the row later. Add optional
Change.PreviousandChange.Value, captured inside the write transaction with key-only resource references.Image capture is explicitly opt-in through
SnapshotRecorder.Snapshots(method) SnapshotOptions, independently per generated operation. Ordinary recorders preserve their existing query/locking behavior.Recordersunions the requirements and captures each image once. Payload presence does not identify the operation;Change.Bydoes.A requested preimage locks the root row on PostgreSQL/MySQL until transaction completion; SQLite relies on write serialization/conflict handling. A requested creation image is read back from the database to preserve timestamp precision, defaults and trigger values, without an explicit row lock. Update postimages reuse the existing response read-back. The root lock does not provide an atomic snapshot of all related tables. Get-less resources are supported.
No publication or payday-specific API is added here. This supplies the optional mutation data needed by lesomnus/payday#74 and lesomnus/payday#75.
Validation:
FOR UPDATEregression tests for ordinary metadata recorders, postimage-only recorders and both images; nested recorder aggregation and Add-only resource coverage.BenchmarkRecorderSnapshotsPatchcompares metadata, postimage-only and both-image modes (single row, no relationships, no contention or audit/outbox/subscriber work). Run withgo test -C internal/apptest ./server/bare -run '^$' -bench BenchmarkRecorderSnapshotsPatch -benchmem; setAPPTEST_POSTGRESfor PostgreSQL.Measured on Linux amd64 / Ryzen 7 5825U, GOMAXPROCS=4; 3 runs of 2s each, other local test/build jobs stopped. Medians below are a small uncontended ORM-only workload, not end-to-end Watch throughput or a production estimate. PostgreSQL ran in a Docker container over TCP.