Clio  develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
CacheLoader.hpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of clio: https://github.com/XRPLF/clio
4 Copyright (c) 2024, the clio developers.
5
6 Permission to use, copy, modify, and distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#pragma once
21
22#include "data/BackendInterface.hpp"
23#include "data/LedgerCacheInterface.hpp"
24#include "data/Types.hpp"
25#include "etl/CacheLoaderInterface.hpp"
26#include "etl/CacheLoaderSettings.hpp"
27#include "etl/impl/CacheLoader.hpp"
28#include "etl/impl/CursorFromAccountProvider.hpp"
29#include "etl/impl/CursorFromDiffProvider.hpp"
30#include "etl/impl/CursorFromFixDiffNumProvider.hpp"
31#include "util/Assert.hpp"
32#include "util/Profiler.hpp"
33#include "util/async/context/BasicExecutionContext.hpp"
34#include "util/config/ConfigDefinition.hpp"
35#include "util/log/Logger.hpp"
36
37#include <algorithm>
38#include <cstdint>
39#include <functional>
40#include <memory>
41#include <utility>
42
43namespace etl {
44
54template <typename ExecutionContextType = util::async::CoroExecutionContext>
57
58 util::Logger log_{"ETL"};
59 std::shared_ptr<BackendInterface> backend_;
60 std::reference_wrapper<data::LedgerCacheInterface> cache_;
61
62 CacheLoaderSettings settings_;
63 ExecutionContextType ctx_;
64 std::unique_ptr<CacheLoaderType> loader_;
65
66public:
76 std::shared_ptr<BackendInterface> backend,
78 )
79 : backend_{std::move(backend)}
80 , cache_{cache}
81 , settings_{makeCacheLoaderSettings(config)}
82 , ctx_{settings_.numThreads}
83 {
84 }
85
94 void
95 load(uint32_t const seq) override
96 {
97 ASSERT(not cache_.get().isFull(), "Cache must not be full. seq = {}", seq);
98
99 if (settings_.isDisabled()) {
100 cache_.get().setDisabled();
101 LOG(log_.warn()) << "Cache is disabled. Not loading";
102 return;
103 }
104
105 if (loadCacheFromFile()) {
106 return;
107 }
108
109 std::shared_ptr<impl::BaseCursorProvider> provider;
110 if (settings_.numCacheCursorsFromDiff != 0) {
111 LOG(log_.info()) << "Loading cache with cursor from num_cursors_from_diff="
112 << settings_.numCacheCursorsFromDiff;
113 provider = std::make_shared<impl::CursorFromDiffProvider>(
114 backend_, settings_.numCacheCursorsFromDiff
115 );
116 } else if (settings_.numCacheCursorsFromAccount != 0) {
117 LOG(log_.info()) << "Loading cache with cursor from num_cursors_from_account="
118 << settings_.numCacheCursorsFromAccount;
119 provider = std::make_shared<impl::CursorFromAccountProvider>(
120 backend_, settings_.numCacheCursorsFromAccount, settings_.cachePageFetchSize
121 );
122 } else {
123 LOG(log_.info()) << "Loading cache with cursor from num_diffs="
124 << settings_.numCacheDiffs;
125 provider = std::make_shared<impl::CursorFromFixDiffNumProvider>(
126 backend_, settings_.numCacheDiffs
127 );
128 }
129
130 loader_ = std::make_unique<CacheLoaderType>(
131 ctx_,
132 backend_,
133 cache_,
134 seq,
135 settings_.numCacheMarkers,
136 settings_.cachePageFetchSize,
137 provider->getCursors(seq)
138 );
139
140 if (settings_.isSync()) {
141 loader_->wait();
142 ASSERT(cache_.get().isFull(), "Cache must be full after sync load. seq = {}", seq);
143 }
144 }
145
149 void
150 stop() noexcept override
151 {
152 if (loader_ != nullptr)
153 loader_->stop();
154 }
155
159 void
160 wait() noexcept override
161 {
162 if (loader_ != nullptr)
163 loader_->wait();
164 }
165
166private:
167 bool
168 loadCacheFromFile()
169 {
170 if (not settings_.cacheFileSettings.has_value()) {
171 return false;
172 }
173 LOG(log_.info()) << "Loading ledger cache from " << settings_.cacheFileSettings->path;
174 auto const minLatestSequence =
175 backend_->fetchLedgerRange()
176 .transform([this](data::LedgerRange const& range) {
177 return std::max(
178 range.maxSequence - settings_.cacheFileSettings->maxAge, range.minSequence
179 );
180 })
181 .value_or(0);
182
183 auto const [success, duration_ms] = util::timed([&]() {
184 return cache_.get().loadFromFile(settings_.cacheFileSettings->path, minLatestSequence);
185 });
186
187 if (not success.has_value()) {
188 LOG(log_.warn()) << "Error loading cache from file: " << success.error();
189 return false;
190 }
191
192 LOG(log_.info()) << "Loaded cache from file in " << duration_ms
193 << " ms. Latest sequence: " << cache_.get().latestLedgerSequence();
194 backend_->forceUpdateRange(cache_.get().latestLedgerSequence());
195 return true;
196 }
197};
198
199} // namespace etl
Cache for an entire ledger.
Definition LedgerCacheInterface.hpp:40
void load(uint32_t const seq) override
Load the cache for the given sequence number.
Definition CacheLoader.hpp:95
void stop() noexcept override
Requests the loader to stop asap.
Definition CacheLoader.hpp:150
void wait() noexcept override
Waits for the loader to finish background work.
Definition CacheLoader.hpp:160
CacheLoader(util::config::ClioConfigDefinition const &config, std::shared_ptr< BackendInterface > backend, data::LedgerCacheInterface &cache)
Construct a new Cache Loader object.
Definition CacheLoader.hpp:74
Definition CacheLoader.hpp:49
A simple thread-safe logger for the channel specified in the constructor.
Definition Logger.hpp:96
Pump info(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::NFO severity.
Definition Logger.cpp:507
All the config data will be stored and extracted from this class.
Definition ConfigDefinition.hpp:50
auto timed(FnType &&func)
Profiler function to measure the time a function execution consumes.
Definition Profiler.hpp:40
Stores a range of sequences as a min and max pair.
Definition Types.hpp:262
An interface for the Cache Loader.
Definition CacheLoaderInterface.hpp:29
Settings for the cache loader.
Definition CacheLoaderSettings.hpp:34
std::optional< CacheFileSettings > cacheFileSettings
Definition CacheLoaderSettings.hpp:58