Download as pdf or txt
Download as pdf or txt
You are on page 1of 3

File Checkpoint

A File Checkpoint is an implementation of the Checkpoint Pattern that operates


via a file. It may or may not be durable depending on the precise implementation
but under nearly all circumstances should be durable.
It is relatively inexpensive to make a File Checkpoint durable. Unless you are in
a quite odd situation you should ensure that your File Checkpoint is durable
or make it quite explicit that it is not as people will generally assume it to be
durable seeing that it is stored in a file.
A very simple implementation of a File Checkpoint can be implemented quite
easily. Basically you need to read and write a value from a file.
Be extremely wary of a File Checkpoint which is not durable. They can cause
quite odd and unpredictable issues. You might be amazed how much complexity
can exist in file systems/hardware for when something is made durable if you
are not explicit about when it should be durable.
If using a File Checkpoint it is likely best to just grab one someone has already
implemented/tested. The amount of testing associated can easily end up in the
days to ensure that things are durable and does some other things (optimizations).
While this is actually a quite fun project to work on, it does not really deliver a
large amount of value and your time is almost certainly better spent elsewhere.
Here is the actual implementation from EventStore which does some of these
other things.
public class FileCheckpoint : ICheckpoint {
private readonly string _name;
private readonly string _filename;
private readonly FileStream _fileStream;

1
private long _last;
private long _lastFlushed;
private readonly bool _cached;

private readonly BinaryWriter _writer;


private readonly BinaryReader _reader;

public FileCheckpoint(string filename, string name, bool cached = false, bool mustEx
_filename = filename;
_name = name;
_cached = cached;
var old = File.Exists(filename);
_fileStream = new FileStream(_filename,
mustExist ? FileMode.Open : FileMode.OpenOrCreate,
FileAccess.ReadWrite,
FileShare.ReadWrite);
if (_fileStream.Length != 8)
_fileStream.SetLength(8);
_reader = new BinaryReader(_fileStream);
_writer = new BinaryWriter(_fileStream);
if (old)
_last = _lastFlushed = ReadCurrent();
else {
_last = initValue;
Flush();
}
}

private long ReadCurrent() {


_fileStream.Seek(0, SeekOrigin.Begin);
return _reader.ReadInt64();
}

public void Close(bool flush) {


if (flush)
Flush();

_reader.Close();
_writer.Close();
_fileStream.Close();
}

public string Name {


get { return _name; }
}

2
public void Write(long checkpoint) {
Interlocked.Exchange(ref _last, checkpoint);
}

public void Flush() {


var last = Interlocked.Read(ref _last);
if (last == _lastFlushed)
return;

_fileStream.Seek(0, SeekOrigin.Begin);
_writer.Write(last);

_fileStream.FlushToDisk();
Interlocked.Exchange(ref _lastFlushed, last);
}

public long Read() {


return _cached ? Interlocked.Read(ref _lastFlushed) : ReadCurrent();
}

public long ReadNonFlushed() {


return Interlocked.Read(ref _last);
}
}
This is most of the implementation out of EventStore. I took out a bit, as it was
not important to look through here. You can find the full source of it on github.
As you can see the checkpoint implementation is handling the reading/writing
of a checkpoint in this case to a FileStream.
There are however many other ways of implementing a file checkpoint aside
from just using a write/flush pattern. DirectIO (aligned reads/writes) is another
one that should be worth considering as is using a memory mapped file. The
reader can find implementations of these in the EventStore source base which is
available on github.
Performance between different models can vary heavily from environment to en-
vironment and your checkpoint implementation can absolutely have a noticeable
effect on your system’s performance as a whole as you will in many cases be
calling into it many times per second to do an IO operation. Checkpoints are
one of the areas to really focus on for performance of the system as a whole.

You might also like