0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-20 17:01:55 +01:00

ircd::client: Encapsulation related reorg; still needs more work.

This commit is contained in:
Jason Volk 2022-06-14 11:21:51 -07:00
parent 07cc3a8f04
commit 169eda8da4
2 changed files with 64 additions and 59 deletions

View file

@ -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<socket> &);
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<mutable_buffer> head_buffer;
unique_buffer<mutable_buffer> content_buffer;
@ -69,12 +57,19 @@ struct ircd::client
void close(const net::close_opts &, net::close_callback);
ctx::future<void> 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<client>);
static void handle_ready(std::shared_ptr<client>, const error_code &ec);
bool async();
public:
client(std::shared_ptr<socket>);
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<socket> &);
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<seconds> async_timeout_default;
static ircd::conf::item<seconds> request_timeout_default;
static ircd::conf::item<size_t> header_max_size_default;
template<class T> using item = ircd::conf::item<T>;
static item<seconds> async_timeout_default;
static item<seconds> request_timeout_default;
static item<size_t> 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<size_t> stack_size;
static ircd::conf::item<size_t> pool_size;
static ircd::conf::item<size_t> max_client;
static ircd::conf::item<size_t> max_client_per_peer;
template<class T> using item = ircd::conf::item<T>;
static item<size_t> stack_size;
static item<size_t> pool_size;
static item<size_t> max_client;
static item<size_t> max_client_per_peer;
};
struct [[gnu::visibility("hidden")]]

View file

@ -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<client>);
static void handle_client_ready(std::shared_ptr<client>, 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> client,
const error_code &ec)
ircd::client::handle_ready(std::shared_ptr<client> 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,
/// 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> client)
ircd::client::handle_requests(std::shared_ptr<client> 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<microseconds>(), 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()
};