coinprices/LocalPriceManager.hpp
Namespaces
Classes
Source code
#pragma once
#include "IPriceSource.hpp"
#include "PriceFetchError.hpp"
#include "PriceQuote.hpp"
#include "boost/asio.hpp"
#include "base/logger.hpp"
#include <chrono>
#include <functional>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <thread>
#include <utility>
#include <vector>
namespace sgns
{
class LocalPriceManager
{
public:
using Clock = std::function<std::chrono::system_clock::time_point()>;
using Strand = boost::asio::strand<boost::asio::io_context::executor_type>;
LocalPriceManager( std::shared_ptr<IPriceSource> coinGeckoTier,
std::shared_ptr<IPriceSource> gnusServiceTier,
std::chrono::milliseconds coalescingWindow = std::chrono::milliseconds( 50 ),
Clock now = [] { return std::chrono::system_clock::now(); } );
~LocalPriceManager();
LocalPriceManager( const LocalPriceManager & ) = delete;
LocalPriceManager &operator=( const LocalPriceManager & ) = delete;
PriceResult<std::vector<PriceQuote>> GetQuotes( const std::vector<std::string> &ids,
const std::string ¤cy = "usd" );
private:
struct PendingWaiter
{
std::vector<std::string> requestedIds; // full original request
std::vector<PriceQuote> immediate; // fresh-L1 subset (D-06)
std::promise<PriceResult<std::vector<PriceQuote>>> done;
};
struct PendingWindow
{
std::set<std::string> ids;
std::vector<PendingWaiter> waiters;
std::unique_ptr<boost::asio::steady_timer> timer;
};
void HandleRequestOnStrand( const std::vector<std::string> &ids,
const std::string ¤cy,
std::promise<PriceResult<std::vector<PriceQuote>>> done );
void DispatchBatchOnStrand( const std::string ¤cy );
void StoreInL1( const std::vector<PriceQuote> "es );
// Declaration order is load-bearing (reverse destruction: timers and
// state maps die before the io_context; the thread is joined in the
// dtor body BEFORE any member dies): ioc_ FIRST, thread_ LAST
// (P-1: the HttpStubServer member-layout precedent).
std::shared_ptr<boost::asio::io_context> ioc_;
std::unique_ptr<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> work_;
Strand strand_;
std::shared_ptr<IPriceSource> coinGeckoTier_;
std::shared_ptr<IPriceSource> gnusServiceTier_;
std::chrono::milliseconds coalescingWindow_;
Clock now_;
std::map<std::string, std::map<std::string, PriceQuote>> cache_;
std::map<std::string, PendingWindow> windows_;
base::Logger m_logger = sgns::base::createLogger( "LocalPriceManager" );
std::thread thread_;
};
} // namespace sgns
Updated on 2026-10-09 at 04:02:50 +0000