46.1 LazyCheckPointer

A worker thread should be doing check points

LSS::SynchronousCheckPoint() performs the following steps:

  1. Write all the dirty RPM nodes to the log within the scope of a SegmentWriter lock. Prepare a snapshot of the root block in memory
  2. Flush the log
  3. Write the division within the root block

This can take a reasonable amount of time - particularly given the need to flush the log, so it is a good idea to use a worker thread to perform check points.

Previous implementation

LazyCheckPointer previously used a SignaledTask which uses a worker thread to perform occasional check points of the LSS, by issuing calls to LSS::SynchronousCheckPoint(). Usually the worker thread is in an efficient wait state, blocking on an event. The event is signalled in order to wake up the thread to make it perform a check point.

New implementation

The LazyCheckPointer has been changed to use an AsyncSignaledTask to avoid it using a dedicated std::thread.


class LazyCheckPointer
{
public:
    LazyCheckPointer(LSS& lss);

    void Start();
    void Stop();
    void SignalNeedToCheckPoint();

private:
    LSS& lss_;
    std::shared_ptr<AsyncSignaledTask> signaledTask_;
};

LazyCheckPointer::LazyCheckPointer(LSS& lss) :
    lss_(lss),
    signaledTask_(MakeAsyncSignaledTask())
{
}

void LazyCheckPointer::Start()
{
    ceda::Start(*signaledTask_,
        [this](std::atomic<bool>& abort)
        {
            try
            {
                lss_.SynchronousCheckPoint();
            }
            catch(FileException&)
            {
                return;
            }
        });
}

void LazyCheckPointer::Stop()
{
    ceda::Stop(*signaledTask_);
}

void LazyCheckPointer::SignalNeedToCheckPoint()
{
    Signal(*signaledTask_);
}