How to handle changing the implementation of Events when using Data.Acid
I have a moderately sized application that uses Data.Acid
for persistence and I've encountered a situation where I need to update the implementation of one of my Update
events for the next version of the server. I.e. I have something like
myUpdate :: Update MyState ()
myUpdate = <some outdated implementation>
Now, obviously I can't just change the implementation haphazardly as it would corrupt my transaction history, so I was wondering how people usually handle this. The way I see it my options are:
Stop the server. Run
createCheckpoint
for myAcidState
. Update theEvent
implementation and then restart the server. Since we load from a fresh snapshot, the changedUpdate
should never trigger for the old events.Create a a new
Update
with a new name (likemyUpdate_v2
) and update my server logic to only usemyUpdate_v2
everywhere instead of the originalmyUpdate
.
I think both options have their merits. (1) is nicer since I don't need to retain the old functionality in my codebase but it has to be done very carefully for each server I update or I risk corrupting data. (2) is safer (especially if I remove the old myUpdate
from my module's exports so I can be sure I don't accidentally use the old implementation anywhere), but it feels a bit ugly otherwise.
Is there some better way of doing this? I see this as something I will definitely encounter every then and again in a long-lived project so I would like to have a good, standard workflow for applying changes to the implementation of my events.
The solution is to not use higher order functions like 'alter'. The benefits of acid-state (ACID guarantees, running code remotely, etc) comes at the cost of only using serialisable data. This restriction is unlikely to ever be lifted.
Usually this is a not a big problem; Just specialise your code. If this doesn't cut it, maybe you want to keep your state in an MVar.