Loading src/api.cpp +52 −16 Original line number Diff line number Diff line Loading @@ -30,6 +30,9 @@ #include <vector> #include <algorithm> #include <cstring> #include <atomic> #include <thread> #include <chrono> #include <json-c/json.h> #include <json-c/json_types.h> Loading Loading @@ -93,6 +96,49 @@ namespace { rd = next; return true; } std::atomic<bool> g_client_recovery_vacuum_running(false); std::atomic<long long> g_client_recovery_last_vacuum_ms(0); long long now_monotonic_ms() { using namespace std::chrono; return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count(); } void schedule_client_recovery_vacuum(AuthBackend &backend) { if (backend.getType() != AuthBackendType::File) return; const long long now = now_monotonic_ms(); const long long last = g_client_recovery_last_vacuum_ms.load(std::memory_order_relaxed); if (now - last < 30000) { return; } bool expected = false; if (!g_client_recovery_vacuum_running.compare_exchange_strong(expected, true)) { return; } std::thread([&backend]() { try { size_t sizeBefore = 0; size_t sizeAfter = 0; backend.vacuum(sizeBefore, sizeAfter); backend.getIndex().invalidate(); g_client_recovery_last_vacuum_ms.store(now_monotonic_ms(), std::memory_order_relaxed); std::cerr << "[api] background client auth recovery vacuum: " << sizeBefore << " -> " << sizeAfter << std::endl; } catch (const std::exception &e) { std::cerr << "[api] background client auth recovery failed: " << e.what() << std::endl; } catch (...) { std::cerr << "[api] background client auth recovery failed: unknown error" << std::endl; } g_client_recovery_vacuum_running.store(false); }).detach(); } } class Api { Loading Loading @@ -388,26 +434,16 @@ public: return conn; // Recovery path for observed degraded state: under heavy request load // the backend can require compaction before name lookups are reliable. // Only run this when the client record wasn't found at all. // the backend can require index refresh / compaction before lookups // become reliable. Keep request path non-blocking. if (!foundClient && _Backend.getType() == AuthBackendType::File) { try { size_t sizeBefore = 0; size_t sizeAfter = 0; _Backend.vacuum(sizeBefore, sizeAfter); _Backend.getIndex().invalidate(); std::cerr << "[api] client auth recovery vacuum: " << sizeBefore << " -> " << sizeAfter << std::endl; } catch (const std::exception &e) { std::cerr << "[api] client auth recovery failed: " << e.what() << std::endl; } catch (...) { std::cerr << "[api] client auth recovery failed: unknown error" << std::endl; } if (const ClientConnections *conn = tryClientLookup(foundClient)) return conn; // If lookup still fails, schedule asynchronous compaction once. schedule_client_recovery_vacuum(_Backend); } return nullptr; // not found or wrong secret Loading Loading
src/api.cpp +52 −16 Original line number Diff line number Diff line Loading @@ -30,6 +30,9 @@ #include <vector> #include <algorithm> #include <cstring> #include <atomic> #include <thread> #include <chrono> #include <json-c/json.h> #include <json-c/json_types.h> Loading Loading @@ -93,6 +96,49 @@ namespace { rd = next; return true; } std::atomic<bool> g_client_recovery_vacuum_running(false); std::atomic<long long> g_client_recovery_last_vacuum_ms(0); long long now_monotonic_ms() { using namespace std::chrono; return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count(); } void schedule_client_recovery_vacuum(AuthBackend &backend) { if (backend.getType() != AuthBackendType::File) return; const long long now = now_monotonic_ms(); const long long last = g_client_recovery_last_vacuum_ms.load(std::memory_order_relaxed); if (now - last < 30000) { return; } bool expected = false; if (!g_client_recovery_vacuum_running.compare_exchange_strong(expected, true)) { return; } std::thread([&backend]() { try { size_t sizeBefore = 0; size_t sizeAfter = 0; backend.vacuum(sizeBefore, sizeAfter); backend.getIndex().invalidate(); g_client_recovery_last_vacuum_ms.store(now_monotonic_ms(), std::memory_order_relaxed); std::cerr << "[api] background client auth recovery vacuum: " << sizeBefore << " -> " << sizeAfter << std::endl; } catch (const std::exception &e) { std::cerr << "[api] background client auth recovery failed: " << e.what() << std::endl; } catch (...) { std::cerr << "[api] background client auth recovery failed: unknown error" << std::endl; } g_client_recovery_vacuum_running.store(false); }).detach(); } } class Api { Loading Loading @@ -388,26 +434,16 @@ public: return conn; // Recovery path for observed degraded state: under heavy request load // the backend can require compaction before name lookups are reliable. // Only run this when the client record wasn't found at all. // the backend can require index refresh / compaction before lookups // become reliable. Keep request path non-blocking. if (!foundClient && _Backend.getType() == AuthBackendType::File) { try { size_t sizeBefore = 0; size_t sizeAfter = 0; _Backend.vacuum(sizeBefore, sizeAfter); _Backend.getIndex().invalidate(); std::cerr << "[api] client auth recovery vacuum: " << sizeBefore << " -> " << sizeAfter << std::endl; } catch (const std::exception &e) { std::cerr << "[api] client auth recovery failed: " << e.what() << std::endl; } catch (...) { std::cerr << "[api] client auth recovery failed: unknown error" << std::endl; } if (const ClientConnections *conn = tryClientLookup(foundClient)) return conn; // If lookup still fails, schedule asynchronous compaction once. schedule_client_recovery_vacuum(_Backend); } return nullptr; // not found or wrong secret Loading