lokinet/llarp/peerstats/peer_db.hpp

73 lines
2.9 KiB
C++
Raw Normal View History

2020-05-20 17:26:45 +00:00
#pragma once
#include <chrono>
#include <filesystem>
2020-05-20 17:26:45 +00:00
#include <unordered_map>
#include <sqlite_orm/sqlite_orm.h>
#include <router_id.hpp>
#include <util/time.hpp>
#include <peerstats/types.hpp>
#include <peerstats/orm.hpp>
2020-05-20 17:26:45 +00:00
namespace llarp
{
/// Maintains a database of stats collected about the connections with our Service Node peers.
/// This uses a sqlite3 database behind the scenes as persistance, but this database is
/// periodically flushed to, meaning that it will become stale as PeerDb accumulates stats without
/// a flush.
struct PeerDb
2020-05-20 17:26:45 +00:00
{
/// Loads the database from disk using the provided filepath. If the file is equal to
/// `std::nullopt`, the database will be loaded into memory (useful for testing).
///
/// This must be called prior to calling flushDatabase(), and will truncate any existing data.
///
/// This is a blocking call, both in the sense that it blocks on disk/database I/O and that it
/// will sit on a mutex while the database is loaded.
///
/// @param file is an optional file which doesn't have to exist but must be writable, if a value
/// is provided. If no value is provided, the database will be memory-backed.
/// @throws if sqlite_orm/sqlite3 is unable to open or create a database at the given file
void
loadDatabase(std::optional<std::filesystem::path> file);
2020-05-20 17:26:45 +00:00
/// Flushes the database. Must be called after loadDatabase(). This call will block during I/O
/// and should be called in an appropriate threading context. However, it will make a temporary
/// copy of the peer stats so as to avoid sitting on a mutex lock during disk I/O.
///
/// @throws if the database could not be written to (esp. if loadDatabase() has not been called)
void
flushDatabase();
2020-05-20 17:26:45 +00:00
/// Add the given stats to the cummulative stats for the given peer. For cummulative stats, the
/// stats are added together; for watermark stats, the max is kept.
///
/// This is intended to be used in the following pattern:
///
/// 1) Initialize an empty PeerStats
/// 2) Collect relevant stats
/// 3) Call accumulatePeerStats() with the stats
/// 4) Reset the stats to 0
/// 5) <Repeat 2-4 periodically>
void
accumulatePeerStats(const RouterID& routerId, const PeerStats& delta);
/// Provides a snapshot of the most recent PeerStats we have for the given peer. If we don't
/// have any stats for the peer, std::nullopt
2020-05-20 17:26:45 +00:00
///
/// @param routerId is the RouterID of the requested peer
/// @return a copy of the most recent peer stats or an empty one if no such peer is known
std::optional<PeerStats>
2020-05-20 17:26:45 +00:00
getCurrentPeerStats(const RouterID& routerId) const;
private:
std::unordered_map<RouterID, PeerStats, RouterID::Hash> m_peerStats;
std::mutex m_statsLock;
std::unique_ptr<PeerDbStorage> m_storage;
2020-05-20 17:26:45 +00:00
};
} // namespace llarp