Refactor web server (#667)

Fixs #674
This commit is contained in:
cyan317
2023-06-08 13:25:49 +01:00
committed by GitHub
parent 9836e4ceaf
commit 435db339df
35 changed files with 2857 additions and 1789 deletions

View File

@@ -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))

View File

@@ -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.