Skip to content

Commit

Permalink
Fix thread manager (#128)
Browse files Browse the repository at this point in the history
* Update connection.cpp

* Update serverless.cpp

* Update instance.cpp

* Update internal.hpp

* Update instance.cpp

* Update internal.hpp

* Update connection.cpp

* Update serverless.cpp

* Update connection.cpp
  • Loading branch information
maddsua authored Feb 4, 2024
1 parent be05b93 commit aeebd69
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 162 deletions.
75 changes: 15 additions & 60 deletions core/server/handlers/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,79 +6,34 @@ using namespace Lambda::Server;
using namespace Lambda::Server::Handlers;

void Handlers::connectionHandler(
Network::TCP::Connection&& conn,
Network::TCP::Connection& conn,
const ServeOptions& config,
const ConnectionCallback& handlerCallback
) noexcept {
) {

auto createLogTimeStamp = [&]() {
if (config.loglevel.timestamps) {
return Date().toHRTString() + ' ';
}
return std::string();
};

const auto& conninfo = conn.info();
std::optional<std::string> handlerError;

if (config.loglevel.connections) fprintf(stdout,
"%s%s:%i connected on %i\n",
createLogTimeStamp().c_str(),
conninfo.remoteAddr.hostname.c_str(),
conninfo.remoteAddr.port,
conninfo.hostPort
);
auto connctx = IncomingConnection(conn, config);

try {

auto connctx = IncomingConnection(conn, config);

try {

handlerCallback(connctx);

} catch(const std::exception& e) {
handlerError = e.what();
} catch(...) {
handlerError = "unhandled exception";
}

if (handlerError.has_value()) {

if (config.loglevel.requests) fprintf(stderr,
"%s%s crashed: %s\n",
createLogTimeStamp().c_str(),
"tcp handler",
handlerError.value().c_str()
);

auto errorResponse = Pages::renderErrorPage(500, handlerError.value(), config.errorResponseType);
connctx.respond(errorResponse);
}
handlerCallback(connctx);

} catch(const std::exception& e) {

if (config.loglevel.requests) fprintf(stderr,
"%s[Service] Connection to %s terminated: %s\n",
createLogTimeStamp().c_str(),
conninfo.remoteAddr.hostname.c_str(),
e.what()
);

handlerError = e.what();
} catch(...) {
handlerError = "unhandled exception";
}

if (handlerError.has_value()) {

if (config.loglevel.requests) fprintf(stderr,
"%s[Service] Connection to %s terminated (unknown error)\n",
createLogTimeStamp().c_str(),
conninfo.remoteAddr.hostname.c_str()
"%s crashed: %s\n",
"tcp handler",
handlerError.value().c_str()
);
}

if (config.loglevel.connections) fprintf(stdout,
"%s%s:%i disconnected from %i\n",
createLogTimeStamp().c_str(),
conninfo.remoteAddr.hostname.c_str(),
conninfo.remoteAddr.port,
conninfo.hostPort
);
auto errorResponse = Pages::renderErrorPage(500, handlerError.value(), config.errorResponseType);
connctx.respond(errorResponse);
}
}
113 changes: 34 additions & 79 deletions core/server/handlers/serverless.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,105 +20,60 @@ using namespace Lambda::Server;
using namespace Lambda::Server::Handlers;

void Handlers::serverlessHandler(
Network::TCP::Connection&& conn,
Network::TCP::Connection& conn,
const ServeOptions& config,
const ServerlessCallback& handlerCallback
) noexcept {
) {

const auto& conninfo = conn.info();

auto createLogTimeStamp = [&]() {
if (config.loglevel.timestamps) {
return Date().toHRTString() + ' ';
}
return std::string();
};

if (config.loglevel.connections) fprintf(stdout,
"%s%s:%i connected on %i\n",
createLogTimeStamp().c_str(),
conninfo.remoteAddr.hostname.c_str(),
conninfo.remoteAddr.port,
conninfo.hostPort
);

try {

auto connctx = IncomingConnection(conn, config);
while (auto nextOpt = connctx.nextRequest()){

if (!nextOpt.has_value()) break;

auto& next = nextOpt.value();
auto requestID = Crypto::ShortID().toString();

HTTP::Response response;
std::optional<std::string> handlerError;
auto connctx = IncomingConnection(conn, config);
while (auto nextOpt = connctx.nextRequest()){

try {
if (!nextOpt.has_value()) break;

response = handlerCallback(next, {
requestID,
conninfo,
Console(requestID, config.loglevel.timestamps)
});
auto& next = nextOpt.value();
auto requestID = Crypto::ShortID().toString();

} catch(const std::exception& e) {
handlerError = e.what();
} catch(...) {
handlerError = "unhandled exception";
}
HTTP::Response response;
std::optional<std::string> handlerError;

if (handlerError.has_value()) {
try {

response = Pages::renderErrorPage(500, handlerError.value(), config.errorResponseType);
response = handlerCallback(next, {
requestID,
conninfo,
Console(requestID, config.loglevel.timestamps)
});

if (config.loglevel.requests) fprintf(stderr,
"%s%s crashed: %s\n",
createLogTimeStamp().c_str(),
requestID.c_str(),
handlerError.value().c_str()
);
}
} catch(const std::exception& e) {
handlerError = e.what();
} catch(...) {
handlerError = "unhandled exception";
}

response.headers.set("x-request-id", requestID);
if (handlerError.has_value()) {

connctx.respond(response);
response = Pages::renderErrorPage(500, handlerError.value(), config.errorResponseType);

if (config.loglevel.requests) fprintf(stdout,
"%s[%s] (%s) %s %s --> %i\n",
createLogTimeStamp().c_str(),
if (config.loglevel.requests) fprintf(stderr,
"%s crashed: %s\n",
requestID.c_str(),
conninfo.remoteAddr.hostname.c_str(),
static_cast<std::string>(next.method).c_str(),
next.url.pathname.c_str(),
response.status.code()
handlerError.value().c_str()
);
}

} catch(const std::exception& e) {

if (config.loglevel.requests) fprintf(stderr,
"%s[Service] Connection to %s terminated: %s\n",
createLogTimeStamp().c_str(),
conninfo.remoteAddr.hostname.c_str(),
e.what()
);
response.headers.set("x-request-id", requestID);

} catch(...) {
connctx.respond(response);

if (config.loglevel.requests) fprintf(stderr,
"%s[Service] Connection to %s terminated (unknown error)\n",
createLogTimeStamp().c_str(),
conninfo.remoteAddr.hostname.c_str()
if (config.loglevel.requests) fprintf(stdout,
"[%s] (%s) %s %s --> %i\n",
requestID.c_str(),
conninfo.remoteAddr.hostname.c_str(),
static_cast<std::string>(next.method).c_str(),
next.url.pathname.c_str(),
response.status.code()
);
}

if (config.loglevel.connections) fprintf(stdout,
"%s%s:%i disconnected from %i\n",
createLogTimeStamp().c_str(),
conninfo.remoteAddr.hostname.c_str(),
conninfo.remoteAddr.port,
conninfo.hostPort
);
}
82 changes: 61 additions & 21 deletions core/server/instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,67 @@ void ServerInstance::start() {
auto nextConn = this->listener.acceptConnection();
if (!nextConn.has_value()) break;

switch (this->handlerType) {

case HandlerType::Serverless: {
auto connectionWorker = std::thread(serverlessHandler,
std::move(nextConn.value()),
std::ref(this->config),
std::ref(this->httpHandler));
connectionWorker.detach();
} break;

case HandlerType::Connection: {
auto connectionWorker = std::thread(connectionHandler,
std::move(nextConn.value()),
std::ref(this->config),
std::ref(this->tcpHandler));
connectionWorker.detach();
} break;

default:
throw std::runtime_error("ServerInstance cannot invode an undefined handlerCallback");
}
std::thread([&](Lambda::Network::TCP::Connection&& conn) {

const auto& conninfo = conn.info();

if (this->config.loglevel.connections) {
fprintf(stdout,
"%s:%i connected on %i\n",
conninfo.remoteAddr.hostname.c_str(),
conninfo.remoteAddr.port,
conninfo.hostPort
);
}

try {

switch (this->handlerType) {

case HandlerType::Serverless: {
serverlessHandler(conn, this->config, this->httpHandler);
} break;

case HandlerType::Connection: {
connectionHandler(conn, this->config, this->tcpHandler);
} break;

default: {
this->terminated = true;
throw std::runtime_error("connection handler undefined");
} break;
}

} catch(const std::exception& e) {

if (config.loglevel.connections || config.loglevel.requests) {
fprintf(stderr,
"[Service] Connection to %s terminated: %s\n",
conninfo.remoteAddr.hostname.c_str(),
e.what()
);
}

} catch(...) {

if (config.loglevel.connections || config.loglevel.requests) {
fprintf(stderr,
"[Service] Connection to %s terminated (unknown error)\n",
conninfo.remoteAddr.hostname.c_str()
);
}
}

if (config.loglevel.connections) {
fprintf(stdout,
"%s:%i disconnected from %i\n",
conninfo.remoteAddr.hostname.c_str(),
conninfo.remoteAddr.port,
conninfo.hostPort
);
}

}, std::move(nextConn.value())).detach();
}
});

Expand Down
4 changes: 2 additions & 2 deletions core/server/internal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
namespace Lambda::Server {

namespace Handlers {
void serverlessHandler(Network::TCP::Connection&& conn, const ServeOptions& config, const ServerlessCallback& handlerCallback) noexcept;
void connectionHandler(Network::TCP::Connection&& conn, const ServeOptions& config, const ConnectionCallback& handlerCallback) noexcept;
void serverlessHandler(Network::TCP::Connection& conn, const ServeOptions& config, const ServerlessCallback& handlerCallback);
void connectionHandler(Network::TCP::Connection& conn, const ServeOptions& config, const ConnectionCallback& handlerCallback);
};

namespace HTTPTransport {
Expand Down

0 comments on commit aeebd69

Please sign in to comment.