#pragma once #include "PersistenceRequest.h" #include #include #include #include #include #include #include #include #include struct PersistenceWriterMetrics { std::size_t pendingCount = 0; uint64_t enqueuedCount = 0; uint64_t coalescedCount = 0; uint64_t writtenCount = 0; uint64_t failedCount = 0; }; struct PersistenceWriteResult { PersistenceTargetKind targetKind = PersistenceTargetKind::RuntimeState; std::string targetPath; std::string reason; bool succeeded = false; std::string errorMessage; bool newerRequestPending = false; }; class PersistenceWriter { public: using SnapshotSink = std::function; using ResultCallback = std::function; explicit PersistenceWriter( std::chrono::milliseconds debounceDelay = std::chrono::milliseconds(50), SnapshotSink sink = SnapshotSink()); ~PersistenceWriter(); void SetResultCallback(ResultCallback callback); bool WriteSnapshot(const PersistenceSnapshot& snapshot, std::string& error); bool EnqueueSnapshot(const PersistenceSnapshot& snapshot, std::string& error); bool StopAndFlush(std::chrono::milliseconds timeout, std::string& error); PersistenceWriterMetrics GetMetrics() const; private: struct PendingSnapshot { PersistenceSnapshot snapshot; std::chrono::steady_clock::time_point readyAt; }; bool ValidateSnapshot(const PersistenceSnapshot& snapshot, std::string& error) const; bool WriteSnapshotThroughSink(const PersistenceSnapshot& snapshot, std::string& error) const; void PublishWriteResult(const PersistenceSnapshot& snapshot, bool succeeded, const std::string& errorMessage, bool newerRequestPending); void StartWorkerLocked(); void WorkerMain(); std::size_t PendingCountLocked() const; std::chrono::milliseconds mDebounceDelay; SnapshotSink mSink; ResultCallback mResultCallback; mutable std::mutex mMutex; std::condition_variable mCondition; std::thread mWorker; bool mWorkerRunning = false; bool mStopping = false; bool mAcceptingRequests = true; std::unordered_map mDebouncedSnapshots; std::deque mImmediateSnapshots; uint64_t mEnqueuedCount = 0; uint64_t mCoalescedCount = 0; uint64_t mWrittenCount = 0; uint64_t mFailedCount = 0; };