https://github.com/alecthomas/replaylog
A type safe implementation of an op replay log
https://github.com/alecthomas/replaylog
Last synced: over 1 year ago
JSON representation
A type safe implementation of an op replay log
- Host: GitHub
- URL: https://github.com/alecthomas/replaylog
- Owner: alecthomas
- License: apache-2.0
- Created: 2022-04-08T11:13:17.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2024-01-01T08:41:44.000Z (over 2 years ago)
- Last Synced: 2025-03-26T01:36:21.897Z (over 1 year ago)
- Language: Go
- Size: 11.7 KB
- Stars: 3
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: COPYING
Awesome Lists containing this project
README
# A type safe implementation of a replay log for Go
[](https://pkg.go.dev/github.com/alecthomas/replaylog) [](https://github.com/alecthomas/replaylog/actions)
[](https://goreportcard.com/report/github.com/alecthomas/replaylog) [](https://gophers.slack.com/messages/CN9DS8YF3)
A [replay log](https://ahmet.im/blog/the-replay-pattern/)
([related](https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying))
records the sequence of operations for mutating an empty
state to its final state. The previous final state can then be reconstructed
from the log by starting with an empty state, reading each operation
from the log, and applying it to the state until the final state is reached.
The Log is not safe for concurrent use across processes.
## Example
A simple key-value store:
```go
type KV map[string]string
type Set struct {
Key string `json:"k"`
Value string `json:"v"`
}
func (s *Set) Apply(kv KV) error {
kv[s.Key] = s.Value
return nil
}
type Delete struct {
Key string `json:"k"`
}
func (d *Delete) Apply(state KV) error {
delete(state, d.Key)
return nil
}
func main() {
ops := []Op[KV]{&Set{}, &Delete{}}
w, err := ioutil.TempFile("", "")
log, err := New[KV](w, ops...)
err = log.Append(&Set{Key: "foo", Value: "bar"})
err = log.Append(&Set{Key: "bar", Value: "waz"})
err = log.Append(&Delete{Key: "foo"})
state := KV{}
err = log.Rewind()
err = log.Replay(state)
fmt.Printf("%#v\n", state)
}
```