eis/eqpalg/utility/async_db_worker.h
Huamonarch f80a917ab7 Async-ify ExpTimes DB persistence with global singleton worker thread
Add AsyncDbWorker: a persistent background thread with dedup queue that
executes DB2 writes asynchronously, keeping the mon 20ms cycle free of
blocking I/O.

Changes:
- async_db_worker.h/.cc: singleton worker, submit() with rule_id dedup,
  drain_and_stop() for clean shutdown
- eqp_stat.h/.cc: new update_static(ruleid, shear_times, running_time)
  overload that skips redundant DB reads for known values (reduces
  5 SELECTs to 3 per persist cycle)
- exp_times.cc: extract persist_exp_times() as a standalone function,
  update_history_times() snapshots values and submits to worker
  (returns immediately), reset_dev_data() uses direct SHM update
- eqpalg_icei.cpp: alg_mgr_.reset() → drain_and_stop() in destructor
  ensures all algorithm threads are stopped before draining the worker

Risk: re-run cmake .. to pick up the new async_db_worker.cc file.
2026-05-13 13:32:50 +08:00

45 lines
1.1 KiB
C++

#pragma once
/**
* @file async_db_worker.h
* @brief 全局单例后台线程,异步执行 DB2 写入,避免阻塞 mon 20ms 周期
*
* 去重机制:同一 rule_id 重复 submit 时,旧任务被覆盖(只保留最新快照)。
* 进程退出时必须在其他单例析构前调用 drain_and_stop()。
*
* @author your name (you@domain.com)
* @version 0.1
* @date 2026-05-13
*/
#include <atomic>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include <unordered_map>
class AsyncDbWorker {
public:
static AsyncDbWorker &instance();
/// 提交任务;同 rule_id 覆盖旧任务(去重)
void submit(const std::string &rule_id, std::function<void()> task);
/// 排空队列并停止线程(进程退出前调用)
void drain_and_stop();
private:
AsyncDbWorker();
~AsyncDbWorker();
std::unique_ptr<std::thread> worker_;
std::mutex mtx_;
std::condition_variable cv_;
std::unordered_map<std::string, std::function<void()>> pending_;
std::atomic<bool> running_{true};
void loop();
};