A transactional log consists of two components:
- a checkpoint
- an incremental log
The premise is as follows. The main program may periodically save its state via checkpointing. However, if the time between checkpoints is large (hours or greater), a lot of work may need to be recomputed in order to recover. The incremental log solves this problem by logging values between checkpoints. This way, if the program needs to recover, it can load the previous state from the checkpoint and then “fast-forward” by replaying the log. After each checkpoint, the log is cleared as its state has been saved.
The API provides three main methods: checkpoint, log, and recover. Semantics are as follows:
- Each call to checkpoint saves the current state and clears the log file
- A call to log saves the value to the log file
- recover operates by accepting two callback functions.
- the first creates the value if it is not yet stored.
- the second replays the log onto the checkpointed state.
A basic usage pattern is as follows:
import trax
logger = trax.Trax()
# if 'world' is not yet stored, this will store it before returning
# otherwise 'world' is loaded from the store
hello = logger.recover('hello', create=lambda:'world')
logger.checkpoint(existence='u')
for c in 'niverse':
logger.log(existence=c)
existence = logger.recover('existence', create=lambda: universe, replay_log=lambda state, log: state + log)
# existence == 'universe'$ python setup.py install --prefix $PREFIXMake sure to update the $PYHTONPATH environmental variable to include $PREFIX/lib/python$PYVERSION/site-packages
See the COPYING file.