I'm using acid-state in a project and I quite like it. I like how easy it is to add persistence to plain Haskell datatypes without much boilerplate.
As far as I understand, acid-state keeps a log of events, instead of writing out the entire new state on every update. What I'm looking for is a way for me to review a log of recent changes to the state from within the application, as a (read-only) list. (Something like git log
, though I don't need branching or being able to go back to an older commit.)
Of course I can write to my own separate log file with details of all state changes, or even model my data as a list of diffs, but I prefer something that is automatic and allows me to use plain datatypes as much as possible.
Is there a library similar to acid-state, or perhaps some internal functionality of acid-state that I could use for this?
Here's the approach I ended up with:
I was already using a wrapper around
Data.Acid.update
(because it's running in a monad with restricted IO) and I realized that the wrapper could store the event to my own log. TheUpdateEvent update
constraint impliesSafeCopy update
and withrunPut . safePut
I can serialize that to aByteString
. However... this is a binary representation, not intended to be humand-readable, and I wanted to be able to review it. I realized that reading the acid-state event log from disk would have the same problem.So I added
Show update
to the constraints of my wrapper. At every place that uses the state I added:(StandaloneDeriving might be a little controversial, but it does not cause a problem with orphans here, as it's in the same file.)
In the wrapper I now call
show
on the update and write the result to my own log file. Of course this loses the atomicity of the update: it is possible the application crashes between theupdate
call and my own logging call, but I'm willing to accept that risk.