2025-03-07 22:15:36 +01:00

155 lines
3.2 KiB
C++

#include <seafire/server/session.hxx>
#include <seafire/server/diagnostics.hxx>
#include <seafire/server/supervisor.hxx>
#include <seafire/server/transaction.hxx>
#include <seafire/common/io/error.hxx>
#include <asio.hpp>
namespace seafire::server
{
session_t::
~session_t() noexcept
{
trace() << "~session_t()...";
}
supervisor_t&
session_t::
owner()
{
return owner_;
}
session_t::stats_t
session_t::
stats() const
{
return stats_;
}
void
session_t::
start()
{
trace() << "start()...";
init_transaction();
}
void
session_t::
stop()
{
// fixme: should we really ignore the error code at this point?
//
std::error_code ignored_ec;
stream_->close(ignored_ec);
}
session_t::
session_t(common::diagnostics_t& diagnostics,
error_handler_t& error_handler,
supervisor_t& owner,
std::unique_ptr<common::io::stream_t> stream,
request_handler_t& handler)
: diagnostics_{diagnostics},
error_handler_{error_handler},
owner_{owner},
stream_{std::move(stream)},
handler_{handler},
connection_{*stream_, 1024*1024} // FIXME: magic number.
{
trace() << "session()...";
}
void
session_t::
init_transaction()
{
trace() << "init_transaction()";
auto self = shared_from_this();
auto bound = [this, self](std::error_code const& ec,
transaction_t::result_t result)
{
on_tx_complete(ec, result == transaction_t::result_t::complete_closed);
};
// fixme: This will potentially destroy the previous transaction.
// Should we detect this and throw? Shouldn't ever happen...
//
current_tx_ = make_transaction(diagnostics_,
std::chrono::seconds{0},
error_handler_,
connection_,
handler_,
bound);
current_tx_->start();
}
void
session_t::
on_tx_complete(std::error_code const& ec, bool close)
{
trace() << "on_tx_complete()...";
auto self = shared_from_this();
current_tx_.reset();
if (!ec) {
if (close) {
trace() << "on_tx_complete(): close requested...";
// Initiate a graceful close of this session/connection.
//
init_close();
}
else {
trace() << "on_tx_complete(): keep-alive requested...";
// We're apparently not done, initiate a new transaction.
//
init_transaction();
}
}
else {
trace() << "on_tx_complete(): error: " << ec;
// If an error occurred, we just remove ourself from the
// supervisor which will eventually close the connection
// when we are destroyed.
//
owner().remove(self);
}
}
void
session_t::
init_close()
{
auto self = shared_from_this();
auto bound = [this, self]()
{
owner().remove(self);
};
stream_->async_graceful_close(bound);
}
common::diagnostics_t::proxy_t
session_t::
trace()
{
return diagnostics_ << session_category();
}
} // namespace seafire::server