From 169eda8da4f25a4518f645e406ec45a4394c7116 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Tue, 14 Jun 2022 11:21:51 -0700 Subject: [PATCH] ircd::client: Encapsulation related reorg; still needs more work. --- include/ircd/client.h | 45 ++++++++++++++----------- ircd/client.cc | 78 +++++++++++++++++++++---------------------- 2 files changed, 64 insertions(+), 59 deletions(-) diff --git a/include/ircd/client.h b/include/ircd/client.h index 9a931225b..f3aea4ab1 100644 --- a/include/ircd/client.h +++ b/include/ircd/client.h @@ -17,10 +17,6 @@ namespace ircd const ipport &remote(const client &); const ipport &local(const client &); - - //TODO: want to upgrade - char *read(client &, char *&start, char *const &stop); - parse::read_closure read_closure(client &); } /// Remote party connecting to our daemon to make requests. @@ -41,14 +37,6 @@ struct ircd::client static ctx::dock dock; static uint64_t ctr; // monotonic - static void create(net::listener &, const std::shared_ptr &); - static size_t count(const net::ipport &remote); // cmp is by IP only, not port - static void terminate_all(); - static void interrupt_all(); - static void close_all(); - static void wait_all(); - static void spawn(); - struct conf *conf {&default_conf}; unique_buffer head_buffer; unique_buffer content_buffer; @@ -69,12 +57,19 @@ struct ircd::client void close(const net::close_opts &, net::close_callback); ctx::future close(const net::close_opts & = {}); + private: void discard_unconsumed(const http::request::head &); bool resource_request(const http::request::head &); bool handle_request(parse::capstan &pc); bool main(); + + static char *read(client &, char *&start, char *const &stop); //TODO: XXX + static parse::read_closure read_closure(client &); //TODO: XXX + static void handle_requests(std::shared_ptr); + static void handle_ready(std::shared_ptr, const error_code &ec); bool async(); + public: client(std::shared_ptr); client(client &&) = delete; client(const client &) = delete; @@ -82,6 +77,14 @@ struct ircd::client client &operator=(const client &) = delete; ~client() noexcept; + static void create(net::listener &, const std::shared_ptr &); + static size_t count(const net::ipport &remote); // cmp is by IP only, not port + static void terminate_all(); + static void interrupt_all(); + static void close_all(); + static void wait_all(); + static void spawn(); + friend const ipport &remote(const client &); friend const ipport &local(const client &); }; @@ -89,9 +92,11 @@ struct ircd::client /// Confs can be attached to individual clients to change their behavior struct ircd::client::conf { - static ircd::conf::item async_timeout_default; - static ircd::conf::item request_timeout_default; - static ircd::conf::item header_max_size_default; + template using item = ircd::conf::item; + + static item async_timeout_default; + static item request_timeout_default; + static item header_max_size_default; /// Default time limit for how long a client connection can be in "async mode" /// (or idle mode) after which it is disconnected. @@ -110,10 +115,12 @@ struct ircd::client::conf /// Settings apply to all clients and cannot be configured per-client struct ircd::client::settings { - static ircd::conf::item stack_size; - static ircd::conf::item pool_size; - static ircd::conf::item max_client; - static ircd::conf::item max_client_per_peer; + template using item = ircd::conf::item; + + static item stack_size; + static item pool_size; + static item max_client; + static item max_client_per_peer; }; struct [[gnu::visibility("hidden")]] diff --git a/ircd/client.cc b/ircd/client.cc index e6fd705bc..1454a972f 100644 --- a/ircd/client.cc +++ b/ircd/client.cc @@ -48,8 +48,7 @@ ircd::client::settings::pool_size /// Linkage for the default settings decltype(ircd::client::settings) -ircd::client::settings -{}; +ircd::client::settings; // // client::conf conf::item's @@ -78,8 +77,7 @@ ircd::client::conf::header_max_size_default /// Linkage for the default conf decltype(ircd::client::default_conf) -ircd::client::default_conf -{}; +ircd::client::default_conf; decltype(ircd::client::log) ircd::client::log @@ -109,8 +107,7 @@ decltype(ircd::client::dock) ircd::client::dock; decltype(ircd::client::ctr) -ircd::client::ctr -{}; +ircd::client::ctr; // Linkage for the container of all active clients for iteration purposes. template<> @@ -149,6 +146,22 @@ noexcept // util // +const ircd::ipport & +ircd::local(const client &client) +{ + return client.local; +} + +const ircd::ipport & +ircd::remote(const client &client) +{ + return client.it->first; +} + +// +// tool +// + void ircd::client::spawn() { @@ -282,7 +295,7 @@ ircd::client::count(const net::ipport &remote) } ircd::parse::read_closure -ircd::read_closure(client &client) +ircd::client::read_closure(client &client) { // Returns a function the parser can call when it wants more data return [&client](char *&start, char *const &stop) @@ -296,9 +309,9 @@ ircd::read_closure(client &client) } char * -ircd::read(client &client, - char *&start, - char *const &stop) +ircd::client::read(client &client, + char *&start, + char *const &stop) { assert(client.sock); auto &sock(*client.sock); @@ -312,18 +325,6 @@ ircd::read(client &client, return base; } -const ircd::ipport & -ircd::local(const client &client) -{ - return client.local; -} - -const ircd::ipport & -ircd::remote(const client &client) -{ - return client.it->first; -} - // // async loop // @@ -335,9 +336,6 @@ namespace ircd static bool handle_ec_short_read(client &); static bool handle_ec_eof(client &); static bool handle_ec(client &, const error_code &); - - static void handle_client_requests(std::shared_ptr); - static void handle_client_ready(std::shared_ptr, const error_code &ec); } /// This function is the basis for the client's request loop. We still use @@ -374,7 +372,7 @@ ircd::client::async() auto handler { - std::bind(ircd::handle_client_ready, shared_from(*this), ph::_1) + std::bind(client::handle_ready, shared_from(*this), ph::_1) }; // Re-purpose the request time counter into an async timer by marking it. @@ -393,25 +391,25 @@ ircd::client::async() /// request pool, which may not be available immediately so this handler might /// be queued for some time after this call returns. void -ircd::handle_client_ready(std::shared_ptr client, - const error_code &ec) +ircd::client::handle_ready(std::shared_ptr client, + const error_code &ec) { if(!handle_ec(*client, ec)) return; auto handler { - std::bind(ircd::handle_client_requests, std::move(client)) + std::bind(client::handle_requests, std::move(client)) }; - if(client::pool.avail() == 0) + if(pool.avail() == 0) log::dwarning { - client::log, "Client context pool exhausted. %zu requests queued.", - client::pool.queued() + log, "Client context pool exhausted. %zu requests queued.", + pool.queued() }; - client::pool(std::move(handler)); + pool(std::move(handler)); } /// A request context has been dispatched and is now handling this client. @@ -420,7 +418,7 @@ ircd::handle_client_ready(std::shared_ptr client, /// client will release this ctx and its stack and fall back to async mode /// or die. void -ircd::handle_client_requests(std::shared_ptr client) +ircd::client::handle_requests(std::shared_ptr client) try { // The ircd::ctx now handling this request is referenced and accessible @@ -435,15 +433,15 @@ try assert(client->reqctx); assert(client->reqctx == ctx::current); client->reqctx = nullptr; - if(client::pool.avail() <= 1) - client::dock.notify_all(); + if(pool.avail() <= 1) + dock.notify_all(); }}; #ifdef RB_DEBUG - timer timer; + util::timer timer; log::debug { - client::log, "%s enter", + log, "%s enter", client->loghead() }; #endif @@ -458,7 +456,7 @@ try char buf[64]; log::debug { - client::log, "%s leave %s", + log, "%s leave %s", client->loghead(), pretty(buf, timer.at(), true) }; @@ -470,7 +468,7 @@ catch(const std::exception &e) { log::error { - client::log, "%s fault :%s", + log, "%s fault :%s", client->loghead(), e.what() };