58

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:

  1. Stop the server. Run createCheckpoint for my AcidState. Update the Event implementation and then restart the server. Since we load from a fresh snapshot, the changed Update should never trigger for the old events.

  2. Create a a new Update with a new name (like myUpdate_v2) and update my server logic to only use myUpdate_v2 everywhere instead of the original myUpdate.

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.

kocica
  • 6,412
  • 2
  • 14
  • 35
shang
  • 24,642
  • 3
  • 58
  • 86
  • Is it the MyState data structure that's changing or just the logic before the actual "write to disk"? – schellsan Feb 11 '14 at 08:07
  • 1
    It's common for both to change, but managing changes to the `MyState` data structure is trivial using `SafeCopy` migrations. However, there is no similar mechanism in place for updated logic when `Data.Acid` goes through the transaction log. – shang Feb 11 '14 at 09:51

1 Answers1

1

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.