0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

ircd::client: Improve main exception propagation for termination/shutdown related.

This commit is contained in:
Jason Volk 2018-08-19 18:09:43 -07:00
parent 1492770f6b
commit ee9343a68f
2 changed files with 29 additions and 17 deletions

View file

@ -59,7 +59,7 @@ struct ircd::client
void discard_unconsumed(const http::request::head &); void discard_unconsumed(const http::request::head &);
bool resource_request(const http::request::head &); bool resource_request(const http::request::head &);
bool handle_request(parse::capstan &pc); bool handle_request(parse::capstan &pc);
bool main() noexcept; bool main();
bool async(); bool async();
public: public:

View file

@ -105,9 +105,12 @@ ircd::client::init::init()
ircd::client::init::~init() ircd::client::init::~init()
noexcept noexcept
{ {
const ctx::uninterruptible::nothrow ui;
interrupt(); interrupt();
close(); close();
wait(); wait();
assert(client::list.empty()); assert(client::list.empty());
} }
@ -139,12 +142,14 @@ ircd::client::interrupt_all()
if(context.active()) if(context.active())
log::warning log::warning
{ {
"Interrupting %zu requests; dropping %zu requests...", "Terminating %zu active of %zu client request contexts; %zu pending; %zu queued",
context.active(), context.active(),
context.pending() context.size(),
context.pending(),
context.queued()
}; };
context.interrupt(); context.terminate();
} }
void void
@ -182,27 +187,34 @@ ircd::client::wait_all()
if(context.active()) if(context.active())
log::dwarning log::dwarning
{ {
"Joining %zu active of %zu remaining request contexts...", "Waiting on %zu active of %zu client request contexts; %zu pending; %zu queued.",
context.active(), context.active(),
context.size() context.size(),
context.pending(),
context.queued()
}; };
while(!client::list.empty()) while(!client::list.empty())
{
if(!dock.wait_for(seconds(2)) && !client::list.empty()) if(!dock.wait_for(seconds(2)) && !client::list.empty())
log::warning log::warning
{ {
"Waiting for %zu clients to close...", client::list.size() "Waiting for %zu clients to close...", client::list.size()
}; };
}
log::debug log::debug
{ {
"Waiting for %zu request contexts to join...", "Joining %zu active of %zu client request contexts; %zu pending; %zu queued",
context.size() context.active(),
context.size(),
context.pending(),
context.queued()
}; };
context.join(); context.join();
log::debug
{
"All client contexts, connections, and requests are clear.",
};
} }
ircd::parse::read_closure ircd::parse::read_closure
@ -300,7 +312,7 @@ namespace ircd
static bool handle_ec_eof(client &); static bool handle_ec_eof(client &);
static bool handle_ec(client &, const error_code &); static bool handle_ec(client &, const error_code &);
static void handle_client_request(std::shared_ptr<client>) noexcept; static void handle_client_request(std::shared_ptr<client>);
static void handle_client_ready(std::shared_ptr<client>, const error_code &ec); static void handle_client_ready(std::shared_ptr<client>, const error_code &ec);
} }
@ -379,7 +391,7 @@ ircd::handle_client_ready(std::shared_ptr<client> client,
/// or die. /// or die.
void void
ircd::handle_client_request(std::shared_ptr<client> client) ircd::handle_client_request(std::shared_ptr<client> client)
noexcept try try
{ {
// The ircd::ctx now handling this request is referenced and accessible // The ircd::ctx now handling this request is referenced and accessible
// in client for the duration of this handling. // in client for the duration of this handling.
@ -399,14 +411,14 @@ noexcept try
else else
client->close(net::dc::SSL_NOTIFY).wait(); client->close(net::dc::SSL_NOTIFY).wait();
} }
catch(...) catch(const std::exception &e)
{ {
log::derror log::derror
{ {
"socket(%p) client(%p) (below main) :%s", "socket(%p) client(%p) (below main) :%s",
client->sock.get(), client->sock.get(),
client.get(), client.get(),
what(std::current_exception()) e.what()
}; };
} }
@ -604,7 +616,7 @@ catch(const std::exception &e)
/// async mode and relinquishes this stack. returning false will disconnect /// async mode and relinquishes this stack. returning false will disconnect
/// the client rather than putting it back into async mode. /// the client rather than putting it back into async mode.
/// ///
/// Exceptions do not pass below main() therefor anything unhandled is an /// Normal exceptions do not pass below main() therefor anything unhandled is an
/// internal server error and the client is disconnected. The exception handler /// internal server error and the client is disconnected. The exception handler
/// here though is executing on a request ctx stack, and we can choose to take /// here though is executing on a request ctx stack, and we can choose to take
/// advantage of that; in contrast to the handle_ec() switch which handles /// advantage of that; in contrast to the handle_ec() switch which handles
@ -612,7 +624,7 @@ catch(const std::exception &e)
/// ///
bool bool
ircd::client::main() ircd::client::main()
noexcept try try
{ {
parse::buffer pb{head_buffer}; parse::buffer pb{head_buffer};
parse::capstan pc{pb, read_closure(*this)}; do parse::capstan pc{pb, read_closure(*this)}; do
@ -735,7 +747,7 @@ catch(const std::exception &e)
catch(const ctx::terminated &) catch(const ctx::terminated &)
{ {
close(net::dc::RST, net::close_ignore); close(net::dc::RST, net::close_ignore);
return false; throw;
} }
/// Handle a single request within the client main() loop. /// Handle a single request within the client main() loop.