This is a summary of the design rules your application has to follow to work with Madeleine.
All of them. At the same time.
Snapshots are taken of the system by marshalling the whole system to a file. If your classes can't be marshalled/unmarshalled then Madeleine won't be able to store/restore the system.
Deterministic means that, given the same commands, they have to always give the same results.
For the much of your code this won't be a problem, but there are a few common issues:
You can't use the system clock (see instead ClockedSystem and TimeActor).
Kernel.rand()
uses the system clock internally by
default. Use Kernel.srand()
to seed the random number
generator before using rand()
.
You generally can't access the outside world from within your prevalent system. Instead do IO outside of the prevalent system and call into the system when needed.
Everything that modifies the prevalent system must be done through a
command object sent to the Madeleine instance, using
execute_command(aCommand)
. Queries that don't modify the
system can be done either through direct method calls or through
command objects.
A command object is an object that implements the method
execute(system)
. They are an example of the "Command"
design pattern.
Madeleine keeps track of changes between snapshots by logging marshalled commands.
Unlike a RDBMS, Madeleine can't roll back a command (yet). This means that your commands will have to do their error checking and raise any errors before modifying the system. Failing to do this will cause an inconsistent command log.
Unmarshalling such a command would create clones of the original objects, which would then be modified instead of the real objects. The commands must find the objects to modify.