mirror of
https://github.com/XRPLF/clio.git
synced 2026-07-30 10:30:19 +00:00
@@ -20,22 +20,21 @@
|
||||
#include <rpc/BookChangesHelper.h>
|
||||
#include <rpc/RPCHelpers.h>
|
||||
#include <subscriptions/SubscriptionManager.h>
|
||||
#include <webserver/WsBase.h>
|
||||
|
||||
void
|
||||
Subscription::subscribe(std::shared_ptr<WsBase> const& session)
|
||||
Subscription::subscribe(SessionPtrType const& session)
|
||||
{
|
||||
boost::asio::post(strand_, [this, session]() { addSession(session, subscribers_, subCount_); });
|
||||
}
|
||||
|
||||
void
|
||||
Subscription::unsubscribe(std::shared_ptr<WsBase> const& session)
|
||||
Subscription::unsubscribe(SessionPtrType const& session)
|
||||
{
|
||||
boost::asio::post(strand_, [this, session]() { removeSession(session, subscribers_, subCount_); });
|
||||
}
|
||||
|
||||
void
|
||||
Subscription::publish(std::shared_ptr<Message> const& message)
|
||||
Subscription::publish(std::shared_ptr<std::string> const& message)
|
||||
{
|
||||
boost::asio::post(strand_, [this, message]() { sendToSubscribers(message, subscribers_, subCount_); });
|
||||
}
|
||||
@@ -65,7 +64,7 @@ getLedgerPubMessage(
|
||||
}
|
||||
|
||||
boost::json::object
|
||||
SubscriptionManager::subLedger(boost::asio::yield_context& yield, std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::subLedger(boost::asio::yield_context& yield, SessionPtrType session)
|
||||
{
|
||||
subscribeHelper(session, ledgerSubscribers_, [this](SessionPtrType session) { unsubLedger(session); });
|
||||
|
||||
@@ -87,25 +86,25 @@ SubscriptionManager::subLedger(boost::asio::yield_context& yield, std::shared_pt
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::unsubLedger(std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::unsubLedger(SessionPtrType session)
|
||||
{
|
||||
ledgerSubscribers_.unsubscribe(session);
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::subTransactions(std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::subTransactions(SessionPtrType session)
|
||||
{
|
||||
subscribeHelper(session, txSubscribers_, [this](SessionPtrType session) { unsubTransactions(session); });
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::unsubTransactions(std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::unsubTransactions(SessionPtrType session)
|
||||
{
|
||||
txSubscribers_.unsubscribe(session);
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::subAccount(ripple::AccountID const& account, std::shared_ptr<WsBase> const& session)
|
||||
SubscriptionManager::subAccount(ripple::AccountID const& account, SessionPtrType const& session)
|
||||
{
|
||||
subscribeHelper(session, account, accountSubscribers_, [this, account](SessionPtrType session) {
|
||||
unsubAccount(account, session);
|
||||
@@ -113,32 +112,32 @@ SubscriptionManager::subAccount(ripple::AccountID const& account, std::shared_pt
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::unsubAccount(ripple::AccountID const& account, std::shared_ptr<WsBase> const& session)
|
||||
SubscriptionManager::unsubAccount(ripple::AccountID const& account, SessionPtrType const& session)
|
||||
{
|
||||
accountSubscribers_.unsubscribe(session, account);
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::subBook(ripple::Book const& book, std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::subBook(ripple::Book const& book, SessionPtrType session)
|
||||
{
|
||||
subscribeHelper(
|
||||
session, book, bookSubscribers_, [this, book](SessionPtrType session) { unsubBook(book, session); });
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::unsubBook(ripple::Book const& book, std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::unsubBook(ripple::Book const& book, SessionPtrType session)
|
||||
{
|
||||
bookSubscribers_.unsubscribe(session, book);
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::subBookChanges(std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::subBookChanges(SessionPtrType session)
|
||||
{
|
||||
subscribeHelper(session, bookChangesSubscribers_, [this](SessionPtrType session) { unsubBookChanges(session); });
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::unsubBookChanges(std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::unsubBookChanges(SessionPtrType session)
|
||||
{
|
||||
bookChangesSubscribers_.unsubscribe(session);
|
||||
}
|
||||
@@ -150,8 +149,8 @@ SubscriptionManager::pubLedger(
|
||||
std::string const& ledgerRange,
|
||||
std::uint32_t txnCount)
|
||||
{
|
||||
auto message =
|
||||
std::make_shared<Message>(boost::json::serialize(getLedgerPubMessage(lgrInfo, fees, ledgerRange, txnCount)));
|
||||
auto message = std::make_shared<std::string>(
|
||||
boost::json::serialize(getLedgerPubMessage(lgrInfo, fees, ledgerRange, txnCount)));
|
||||
|
||||
ledgerSubscribers_.publish(message);
|
||||
}
|
||||
@@ -197,7 +196,7 @@ SubscriptionManager::pubTransaction(Backend::TransactionAndMetadata const& blobs
|
||||
}
|
||||
}
|
||||
|
||||
auto pubMsg = std::make_shared<Message>(boost::json::serialize(pubObj));
|
||||
auto pubMsg = std::make_shared<std::string>(boost::json::serialize(pubObj));
|
||||
txSubscribers_.publish(pubMsg);
|
||||
|
||||
auto accounts = meta->getAffectedAccounts();
|
||||
@@ -249,14 +248,14 @@ SubscriptionManager::pubBookChanges(
|
||||
std::vector<Backend::TransactionAndMetadata> const& transactions)
|
||||
{
|
||||
auto const json = RPC::computeBookChanges(lgrInfo, transactions);
|
||||
auto const bookChangesMsg = std::make_shared<Message>(boost::json::serialize(json));
|
||||
auto const bookChangesMsg = std::make_shared<std::string>(boost::json::serialize(json));
|
||||
bookChangesSubscribers_.publish(bookChangesMsg);
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::forwardProposedTransaction(boost::json::object const& response)
|
||||
{
|
||||
auto pubMsg = std::make_shared<Message>(boost::json::serialize(response));
|
||||
auto pubMsg = std::make_shared<std::string>(boost::json::serialize(response));
|
||||
txProposedSubscribers_.publish(pubMsg);
|
||||
|
||||
auto transaction = response.at("transaction").as_object();
|
||||
@@ -269,19 +268,19 @@ SubscriptionManager::forwardProposedTransaction(boost::json::object const& respo
|
||||
void
|
||||
SubscriptionManager::forwardManifest(boost::json::object const& response)
|
||||
{
|
||||
auto pubMsg = std::make_shared<Message>(boost::json::serialize(response));
|
||||
auto pubMsg = std::make_shared<std::string>(boost::json::serialize(response));
|
||||
manifestSubscribers_.publish(pubMsg);
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::forwardValidation(boost::json::object const& response)
|
||||
{
|
||||
auto pubMsg = std::make_shared<Message>(boost::json::serialize(response));
|
||||
auto pubMsg = std::make_shared<std::string>(boost::json::serialize(response));
|
||||
validationsSubscribers_.publish(pubMsg);
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::subProposedAccount(ripple::AccountID const& account, std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::subProposedAccount(ripple::AccountID const& account, SessionPtrType session)
|
||||
{
|
||||
subscribeHelper(session, account, accountProposedSubscribers_, [this, account](SessionPtrType session) {
|
||||
unsubProposedAccount(account, session);
|
||||
@@ -289,50 +288,50 @@ SubscriptionManager::subProposedAccount(ripple::AccountID const& account, std::s
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::subManifest(std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::subManifest(SessionPtrType session)
|
||||
{
|
||||
subscribeHelper(session, manifestSubscribers_, [this](SessionPtrType session) { unsubManifest(session); });
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::unsubManifest(std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::unsubManifest(SessionPtrType session)
|
||||
{
|
||||
manifestSubscribers_.unsubscribe(session);
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::subValidation(std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::subValidation(SessionPtrType session)
|
||||
{
|
||||
subscribeHelper(session, validationsSubscribers_, [this](SessionPtrType session) { unsubValidation(session); });
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::unsubValidation(std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::unsubValidation(SessionPtrType session)
|
||||
{
|
||||
validationsSubscribers_.unsubscribe(session);
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::unsubProposedAccount(ripple::AccountID const& account, std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::unsubProposedAccount(ripple::AccountID const& account, SessionPtrType session)
|
||||
{
|
||||
accountProposedSubscribers_.unsubscribe(session, account);
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::subProposedTransactions(std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::subProposedTransactions(SessionPtrType session)
|
||||
{
|
||||
subscribeHelper(
|
||||
session, txProposedSubscribers_, [this](SessionPtrType session) { unsubProposedTransactions(session); });
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::unsubProposedTransactions(std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::unsubProposedTransactions(SessionPtrType session)
|
||||
{
|
||||
txProposedSubscribers_.unsubscribe(session);
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::subscribeHelper(std::shared_ptr<WsBase> const& session, Subscription& subs, CleanupFunction&& func)
|
||||
SubscriptionManager::subscribeHelper(SessionPtrType const& session, Subscription& subs, CleanupFunction&& func)
|
||||
{
|
||||
subs.subscribe(session);
|
||||
std::scoped_lock lk(cleanupMtx_);
|
||||
@@ -342,7 +341,7 @@ SubscriptionManager::subscribeHelper(std::shared_ptr<WsBase> const& session, Sub
|
||||
template <typename Key>
|
||||
void
|
||||
SubscriptionManager::subscribeHelper(
|
||||
std::shared_ptr<WsBase> const& session,
|
||||
SessionPtrType const& session,
|
||||
Key const& k,
|
||||
SubscriptionMap<Key>& subs,
|
||||
CleanupFunction&& func)
|
||||
@@ -353,7 +352,7 @@ SubscriptionManager::subscribeHelper(
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionManager::cleanup(std::shared_ptr<WsBase> session)
|
||||
SubscriptionManager::cleanup(SessionPtrType session)
|
||||
{
|
||||
std::scoped_lock lk(cleanupMtx_);
|
||||
if (!cleanupFuncs_.contains(session))
|
||||
|
||||
@@ -22,16 +22,16 @@
|
||||
#include <backend/BackendInterface.h>
|
||||
#include <config/Config.h>
|
||||
#include <log/Logger.h>
|
||||
#include <subscriptions/Message.h>
|
||||
#include <webserver/interface/ConnectionBase.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class WsBase;
|
||||
using SessionPtrType = std::shared_ptr<Server::ConnectionBase>;
|
||||
|
||||
class Subscription
|
||||
{
|
||||
boost::asio::io_context::strand strand_;
|
||||
std::unordered_set<std::shared_ptr<WsBase>> subscribers_ = {};
|
||||
std::unordered_set<SessionPtrType> subscribers_ = {};
|
||||
std::atomic_uint64_t subCount_ = 0;
|
||||
|
||||
public:
|
||||
@@ -46,13 +46,13 @@ public:
|
||||
~Subscription() = default;
|
||||
|
||||
void
|
||||
subscribe(std::shared_ptr<WsBase> const& session);
|
||||
subscribe(SessionPtrType const& session);
|
||||
|
||||
void
|
||||
unsubscribe(std::shared_ptr<WsBase> const& session);
|
||||
unsubscribe(SessionPtrType const& session);
|
||||
|
||||
void
|
||||
publish(std::shared_ptr<Message> const& message);
|
||||
publish(std::shared_ptr<std::string> const& message);
|
||||
|
||||
std::uint64_t
|
||||
count() const
|
||||
@@ -70,8 +70,7 @@ public:
|
||||
template <class Key>
|
||||
class SubscriptionMap
|
||||
{
|
||||
using ptr = std::shared_ptr<WsBase>;
|
||||
using subscribers = std::set<ptr>;
|
||||
using subscribers = std::set<SessionPtrType>;
|
||||
|
||||
boost::asio::io_context::strand strand_;
|
||||
std::unordered_map<Key, subscribers> subscribers_ = {};
|
||||
@@ -89,13 +88,13 @@ public:
|
||||
~SubscriptionMap() = default;
|
||||
|
||||
void
|
||||
subscribe(std::shared_ptr<WsBase> const& session, Key const& key);
|
||||
subscribe(SessionPtrType const& session, Key const& key);
|
||||
|
||||
void
|
||||
unsubscribe(std::shared_ptr<WsBase> const& session, Key const& key);
|
||||
unsubscribe(SessionPtrType const& session, Key const& key);
|
||||
|
||||
void
|
||||
publish(std::shared_ptr<Message> const& message, Key const& key);
|
||||
publish(std::shared_ptr<std::string> const& message, Key const& key);
|
||||
|
||||
std::uint64_t
|
||||
count() const
|
||||
@@ -106,7 +105,7 @@ public:
|
||||
|
||||
template <class T>
|
||||
inline void
|
||||
sendToSubscribers(std::shared_ptr<Message> const& message, T& subscribers, std::atomic_uint64_t& counter)
|
||||
sendToSubscribers(std::shared_ptr<std::string> const& message, T& subscribers, std::atomic_uint64_t& counter)
|
||||
{
|
||||
for (auto it = subscribers.begin(); it != subscribers.end();)
|
||||
{
|
||||
@@ -126,7 +125,7 @@ sendToSubscribers(std::shared_ptr<Message> const& message, T& subscribers, std::
|
||||
|
||||
template <class T>
|
||||
inline void
|
||||
addSession(std::shared_ptr<WsBase> session, T& subscribers, std::atomic_uint64_t& counter)
|
||||
addSession(SessionPtrType session, T& subscribers, std::atomic_uint64_t& counter)
|
||||
{
|
||||
if (!subscribers.contains(session))
|
||||
{
|
||||
@@ -137,7 +136,7 @@ addSession(std::shared_ptr<WsBase> session, T& subscribers, std::atomic_uint64_t
|
||||
|
||||
template <class T>
|
||||
inline void
|
||||
removeSession(std::shared_ptr<WsBase> session, T& subscribers, std::atomic_uint64_t& counter)
|
||||
removeSession(SessionPtrType session, T& subscribers, std::atomic_uint64_t& counter)
|
||||
{
|
||||
if (subscribers.contains(session))
|
||||
{
|
||||
@@ -148,14 +147,14 @@ removeSession(std::shared_ptr<WsBase> session, T& subscribers, std::atomic_uint6
|
||||
|
||||
template <class Key>
|
||||
void
|
||||
SubscriptionMap<Key>::subscribe(std::shared_ptr<WsBase> const& session, Key const& account)
|
||||
SubscriptionMap<Key>::subscribe(SessionPtrType const& session, Key const& account)
|
||||
{
|
||||
boost::asio::post(strand_, [this, session, account]() { addSession(session, subscribers_[account], subCount_); });
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
void
|
||||
SubscriptionMap<Key>::unsubscribe(std::shared_ptr<WsBase> const& session, Key const& account)
|
||||
SubscriptionMap<Key>::unsubscribe(SessionPtrType const& session, Key const& account)
|
||||
{
|
||||
boost::asio::post(strand_, [this, account, session]() {
|
||||
if (!subscribers_.contains(account))
|
||||
@@ -177,7 +176,7 @@ SubscriptionMap<Key>::unsubscribe(std::shared_ptr<WsBase> const& session, Key co
|
||||
|
||||
template <class Key>
|
||||
void
|
||||
SubscriptionMap<Key>::publish(std::shared_ptr<Message> const& message, Key const& account)
|
||||
SubscriptionMap<Key>::publish(std::shared_ptr<std::string> const& message, Key const& account)
|
||||
{
|
||||
boost::asio::post(strand_, [this, account, message]() {
|
||||
if (!subscribers_.contains(account))
|
||||
@@ -189,7 +188,6 @@ SubscriptionMap<Key>::publish(std::shared_ptr<Message> const& message, Key const
|
||||
|
||||
class SubscriptionManager
|
||||
{
|
||||
using SessionPtrType = std::shared_ptr<WsBase>;
|
||||
clio::Logger log_{"Subscriptions"};
|
||||
|
||||
std::vector<std::thread> workers_;
|
||||
@@ -288,10 +286,10 @@ public:
|
||||
unsubBook(ripple::Book const& book, SessionPtrType session);
|
||||
|
||||
void
|
||||
subBookChanges(std::shared_ptr<WsBase> session);
|
||||
subBookChanges(SessionPtrType session);
|
||||
|
||||
void
|
||||
unsubBookChanges(std::shared_ptr<WsBase> session);
|
||||
unsubBookChanges(SessionPtrType session);
|
||||
|
||||
void
|
||||
subManifest(SessionPtrType session);
|
||||
@@ -354,15 +352,11 @@ private:
|
||||
using CleanupFunction = std::function<void(SessionPtrType const)>;
|
||||
|
||||
void
|
||||
subscribeHelper(std::shared_ptr<WsBase> const& session, Subscription& subs, CleanupFunction&& func);
|
||||
subscribeHelper(SessionPtrType const& session, Subscription& subs, CleanupFunction&& func);
|
||||
|
||||
template <typename Key>
|
||||
void
|
||||
subscribeHelper(
|
||||
std::shared_ptr<WsBase> const& session,
|
||||
Key const& k,
|
||||
SubscriptionMap<Key>& subs,
|
||||
CleanupFunction&& func);
|
||||
subscribeHelper(SessionPtrType const& session, Key const& k, SubscriptionMap<Key>& subs, CleanupFunction&& func);
|
||||
|
||||
/**
|
||||
* This is how we chose to cleanup subscriptions that have been closed.
|
||||
|
||||
Reference in New Issue
Block a user