54 lines
2.3 KiB
Markdown
54 lines
2.3 KiB
Markdown
Event log based store
|
|
|
|
The data rows of our table are to be recreated from an event log
|
|
All interactions with the rows is to happen exclusively via events from/in the log
|
|
For performance reasons we are to cache these data rows as well for quick lookup
|
|
|
|
Events in the log are to take form of:
|
|
type Event struct {
|
|
// Server generated sequence number of the event - ie when it was applied
|
|
Seq int `json:"seq"`
|
|
// Type of the event - create, update, delete, defined by the client
|
|
Type string `json:"type"`
|
|
// Hash of the event - server generated, gurantees the event was processed
|
|
Hash string `json:"hash"`
|
|
// ItemID of the item that is to be manipulated, defined by the client
|
|
ItemID string `json:"item_id"`
|
|
// EventID of the event - server generated, gurantees the event was processed
|
|
EventID string `json:"event_id"`
|
|
// Collection of the item that is to be manipulated, defined by the client
|
|
Collection string `json:"collection"`
|
|
// Data that is to be used for manipulation; for create events that's the full objects and for update events that's the diff
|
|
Data map[string]interface{} `json:"data"`
|
|
// Timestamp of the event - server generated, when the event was processed
|
|
Timestamp time.Time `json:"timestamp"`
|
|
}
|
|
Events are divided into 3 types, create update and delete events
|
|
Create events simply create the object as given in Data
|
|
Delete events simply mark an object as deleted (not actually delete!) via its ItemID
|
|
Update events are to modify a field of a row and never more than one field
|
|
Therefore its data is only the diff in the form of "age = 3"
|
|
|
|
When creating an event only the Type and ItemID must be provided
|
|
Data is optional (delete events have no data)
|
|
Hash, EventID and Seq are to be computed server side
|
|
|
|
On the server side with an incoming event:
|
|
Grab the latest event
|
|
Assign the event a sequence number that is incremented from the latest
|
|
Create its EventID (generate a uuid-v4)
|
|
Assign it a Timestamp
|
|
Compute the hash from the dump of the current event PLUS the previous event's hash
|
|
And only then apply the patch
|
|
For create events that is insert objects
|
|
For delete events that is mark objects as deleted
|
|
For update events get the object, apply the diff and sav the object
|
|
|
|
|
|
---
|
|
|
|
|
|
Actually for pocketbase we might want to generalize this
|
|
Maybe create a "Collection" field as well and allow the events to manipulate any table...
|
|
That way our Data isn't tied to a table...
|