41.6 LazyFlusher
LSS::Flush() needs to be called on a regular basis in order to flush the log to avoid data
loss if there is a system failure (such as loss of power).
This is a synchronous call - i.e. it won't return until the log has been flushed.
LSS::Flush() is threadsafe, so it is permissible for a worker thread to call this function.
LazyFlusher employs a low priority background thread in order to make repeated calls to
LSS::Flush().
The rate at which it will flush the log is determined by the int variable
LssSettings::flushTimeMilliSec which defaults to 1000 milliseconds.
When the system is I/O bound writing to disk, we don't want to waste time flushing partially full
segments to disk. To support this concept, LazyFlusher::SignalDontNeedToFlush() is called each
time a full segment is written to disk by the lazy writer. When this is called repeatedly, the
TimeOutTask will be prevented from timing out and therefore the LazyFlusher
avoids flushing the log.
This ensures that auto-flushing has no impact on the maximum write performance.
LazyFlusher previously used a TimeOutTask but that was using a dedicated thread, so instead an AsyncPeriodicTimer is used.
Note that it is important that Reset() on the AsyncPeriodicTimer can be called from within
the timeout task - i.e. without creating a dead-lock.
This is because LSS::Flush() will very often synchronously call
LazyFlusher::SignalDontNeedToFlush().
Code
class LazyFlusher
{
public:
LazyFlusher(LSS& lss);
void Start();
void Stop();
void SignalDontNeedToFlush();
private:
LSS& lss_;
std::shared_ptr<AsyncPeriodicTimer> timer_;
};