Clio develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
LoadBalancer.hpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of clio: https://github.com/XRPLF/clio
4 Copyright (c) 2022, 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 "etl/ETLState.hpp"
25#include "etl/Source.hpp"
26#include "feed/SubscriptionManagerInterface.hpp"
27#include "rpc/Errors.hpp"
28#include "util/Mutex.hpp"
29#include "util/ResponseExpirationCache.hpp"
30#include "util/log/Logger.hpp"
31#include "util/newconfig/ConfigDefinition.hpp"
32
33#include <boost/asio.hpp>
34#include <boost/asio/io_context.hpp>
35#include <boost/asio/spawn.hpp>
36#include <boost/json/object.hpp>
37#include <boost/json/value.hpp>
38#include <grpcpp/grpcpp.h>
39#include <org/xrpl/rpc/v1/get_ledger.pb.h>
40#include <org/xrpl/rpc/v1/ledger.pb.h>
41#include <xrpl/proto/org/xrpl/rpc/v1/xrp_ledger.grpc.pb.h>
42
43#include <chrono>
44#include <concepts>
45#include <cstdint>
46#include <expected>
47#include <memory>
48#include <optional>
49#include <string>
50#include <string_view>
51#include <vector>
52
53namespace etl {
54
59 virtual ~LoadBalancerTag() = default;
60};
61
62template <typename T>
63concept SomeLoadBalancer = std::derived_from<T, LoadBalancerTag>;
64
73public:
74 using RawLedgerObjectType = org::xrpl::rpc::v1::RawLedgerObject;
75 using GetLedgerResponseType = org::xrpl::rpc::v1::GetLedgerResponse;
76 using OptionalGetLedgerResponseType = std::optional<GetLedgerResponseType>;
77
78private:
79 static constexpr std::uint32_t kDEFAULT_DOWNLOAD_RANGES = 16;
80
81 util::Logger log_{"ETL"};
82 // Forwarding cache must be destroyed after sources because sources have a callback to invalidate cache
83 std::optional<util::ResponseExpirationCache> forwardingCache_;
84 std::optional<std::string> forwardingXUserValue_;
85
86 std::vector<SourcePtr> sources_;
87 std::optional<ETLState> etlState_;
88 std::uint32_t downloadRanges_ =
89 kDEFAULT_DOWNLOAD_RANGES; /*< The number of markers to use when downloading initial ledger */
90
91 // Using mutext instead of atomic_bool because choosing a new source to
92 // forward messages should be done with a mutual exclusion otherwise there will be a race condition
93 util::Mutex<bool> hasForwardingSource_{false};
94
95public:
99 static constexpr std::string_view kADMIN_FORWARDING_X_USER_VALUE = "clio_admin";
100
104 static constexpr std::string_view kUSER_FORWARDING_X_USER_VALUE = "clio_user";
105
118 boost::asio::io_context& ioc,
119 std::shared_ptr<BackendInterface> backend,
120 std::shared_ptr<feed::SubscriptionManagerInterface> subscriptions,
121 std::shared_ptr<NetworkValidatedLedgersInterface> validatedLedgers,
122 SourceFactory sourceFactory = makeSource
123 );
124
136 static std::shared_ptr<LoadBalancer>
139 boost::asio::io_context& ioc,
140 std::shared_ptr<BackendInterface> backend,
141 std::shared_ptr<feed::SubscriptionManagerInterface> subscriptions,
142 std::shared_ptr<NetworkValidatedLedgersInterface> validatedLedgers,
143 SourceFactory sourceFactory = makeSource
144 );
145
146 ~LoadBalancer() override;
147
157 std::vector<std::string>
159 uint32_t sequence,
160 bool cacheOnly = false,
161 std::chrono::steady_clock::duration retryAfter = std::chrono::seconds{2}
162 );
163
177 OptionalGetLedgerResponseType
179 uint32_t ledgerSequence,
180 bool getObjects,
181 bool getObjectNeighbors,
182 std::chrono::steady_clock::duration retryAfter = std::chrono::seconds{2}
183 );
184
190 boost::json::value
191 toJson() const;
192
202 std::expected<boost::json::object, rpc::ClioError>
204 boost::json::object const& request,
205 std::optional<std::string> const& clientIp,
206 bool isAdmin,
207 boost::asio::yield_context yield
208 );
209
214 std::optional<ETLState>
215 getETLState() noexcept;
216
223 void
224 stop(boost::asio::yield_context yield);
225
226private:
239 template <typename Func>
240 void
241 execute(Func f, uint32_t ledgerSequence, std::chrono::steady_clock::duration retryAfter = std::chrono::seconds{2});
242
246 void
247 chooseForwardingSource();
248};
249
250} // namespace etl
This class is used to manage connections to transaction processing processes.
Definition LoadBalancer.hpp:72
boost::json::value toJson() const
Represent the state of this load balancer as a JSON object.
Definition LoadBalancer.cpp:279
LoadBalancer(util::config::ClioConfigDefinition const &config, boost::asio::io_context &ioc, std::shared_ptr< BackendInterface > backend, std::shared_ptr< feed::SubscriptionManagerInterface > subscriptions, std::shared_ptr< NetworkValidatedLedgersInterface > validatedLedgers, SourceFactory sourceFactory=makeSource)
Create an instance of the load balancer.
Definition LoadBalancer.cpp:77
OptionalGetLedgerResponseType fetchLedger(uint32_t ledgerSequence, bool getObjects, bool getObjectNeighbors, std::chrono::steady_clock::duration retryAfter=std::chrono::seconds{2})
Fetch data for a specific ledger.
Definition LoadBalancer.cpp:201
std::expected< boost::json::object, rpc::ClioError > forwardToRippled(boost::json::object const &request, std::optional< std::string > const &clientIp, bool isAdmin, boost::asio::yield_context yield)
Forward a JSON RPC request to a randomly selected rippled node.
Definition LoadBalancer.cpp:231
static std::shared_ptr< LoadBalancer > makeLoadBalancer(util::config::ClioConfigDefinition const &config, boost::asio::io_context &ioc, std::shared_ptr< BackendInterface > backend, std::shared_ptr< feed::SubscriptionManagerInterface > subscriptions, std::shared_ptr< NetworkValidatedLedgersInterface > validatedLedgers, SourceFactory sourceFactory=makeSource)
A factory function for the load balancer.
Definition LoadBalancer.cpp:63
std::vector< std::string > loadInitialLedger(uint32_t sequence, bool cacheOnly=false, std::chrono::steady_clock::duration retryAfter=std::chrono::seconds{2})
Load the initial ledger, writing data to the queue.
Definition LoadBalancer.cpp:178
std::optional< ETLState > getETLState() noexcept
Return state of ETL nodes.
Definition LoadBalancer.cpp:331
static constexpr std::string_view kUSER_FORWARDING_X_USER_VALUE
Value for the X-User header when forwarding user requests.
Definition LoadBalancer.hpp:104
void stop(boost::asio::yield_context yield)
Stop the load balancer. This will stop all subscription sources.
Definition LoadBalancer.cpp:341
static constexpr std::string_view kADMIN_FORWARDING_X_USER_VALUE
Value for the X-User header when forwarding admin requests.
Definition LoadBalancer.hpp:99
A simple thread-safe logger for the channel specified in the constructor.
Definition Logger.hpp:110
A container for data that is protected by a mutex. Inspired by Mutex in Rust.
Definition Mutex.hpp:96
All the config data will be stored and extracted from this class.
Definition ConfigDefinition.hpp:54
Definition LoadBalancer.hpp:63
This namespace contains everything to do with the ETL and ETL sources.
Definition CacheLoader.hpp:36
SourcePtr makeSource(util::config::ObjectView const &config, boost::asio::io_context &ioc, std::shared_ptr< BackendInterface > backend, std::shared_ptr< feed::SubscriptionManagerInterface > subscriptions, std::shared_ptr< NetworkValidatedLedgersInterface > validatedLedgers, std::chrono::steady_clock::duration forwardingTimeout, SourceBase::OnConnectHook onConnect, SourceBase::OnDisconnectHook onDisconnect, SourceBase::OnLedgerClosedHook onLedgerClosed)
Create a source.
Definition Source.cpp:41
A tag class to help identify LoadBalancer in templated code.
Definition LoadBalancer.hpp:58