diff --git a/database/mysql/mysql.cpp b/database/mysql/mysql.cpp index 33f2f75..8449dc5 100644 --- a/database/mysql/mysql.cpp +++ b/database/mysql/mysql.cpp @@ -305,6 +305,7 @@ DB::Session DB::MySQL::findSession(const std::string& accessToken) { Statement session(con, selectSession); session.bind(a.data(), MYSQL_TYPE_STRING); + session.execute(); std::vector> result = session.fetchResult(); if (result.empty()) diff --git a/database/mysql/statement.cpp b/database/mysql/statement.cpp index edd90bd..f8edd76 100644 --- a/database/mysql/statement.cpp +++ b/database/mysql/statement.cpp @@ -94,19 +94,19 @@ std::vector> DB::MySQL::Statement::fetchResult() { } break; case MYSQL_TYPE_TINY: line[i] = uint8_t{0}; - bind[i].buffer = &std::any_cast(line[i]); + bind[i].buffer = &std::any_cast(line[i]); break; case MYSQL_TYPE_SHORT: line[i] = uint16_t{0}; - bind[i].buffer = &std::any_cast(line[i]); + bind[i].buffer = &std::any_cast(line[i]); break; case MYSQL_TYPE_LONG: line[i] = uint32_t{0}; - bind[i].buffer = &std::any_cast(line[i]); + bind[i].buffer = &std::any_cast(line[i]); break; case MYSQL_TYPE_LONGLONG: line[i] = uint64_t{0}; - bind[i].buffer = &std::any_cast(line[i]); + bind[i].buffer = &std::any_cast(line[i]); break; default: throw std::runtime_error("Unsupported data fetching statement result " + std::to_string(field->type)); diff --git a/handler/poll.cpp b/handler/poll.cpp index 0ffd138..1aa36d3 100644 --- a/handler/poll.cpp +++ b/handler/poll.cpp @@ -8,8 +8,8 @@ #include "request/redirect.h" #include "database/exceptions.h" -Handler::Poll::Poll (Server* server): - Handler("login", Request::Method::get), +Handler::Poll::Poll (std::weak_ptr server): + Handler("poll", Request::Method::get), server(server) {} @@ -20,9 +20,13 @@ void Handler::Poll::handle (Request& request) { if (access.size() != 32) return error(request, Result::tokenProblem, Response::Status::badRequest); - + + std::shared_ptr srv = server.lock(); + if (!srv) + return error(request, Result::unknownError, Response::Status::internalError); + try { - Session& session = server->getSession(access); + Session& session = srv->getSession(access); throw Redirect(&session); } catch (const Redirect& r) { throw r; diff --git a/handler/poll.h b/handler/poll.h index 580256e..f9c43c8 100644 --- a/handler/poll.h +++ b/handler/poll.h @@ -3,6 +3,8 @@ #pragma once +#include + #include "handler.h" #include "request/request.h" #include "response/response.h" @@ -12,7 +14,7 @@ namespace Handler { class Poll : public Handler { public: - Poll(Server* server); + Poll(std::weak_ptr server); void handle(Request& request) override; enum class Result { @@ -25,7 +27,7 @@ public: static void error(Request& request, Result result, Response::Status status); private: - Server* server; + std::weak_ptr server; }; diff --git a/request/request.cpp b/request/request.cpp index 3ee662f..eedbc72 100644 --- a/request/request.cpp +++ b/request/request.cpp @@ -188,7 +188,7 @@ std::string Request::getServerName() const { return FCGX_GetParam(SERVER_NAME, raw.envp);; } -void Request::printEnvironment(std::ostream& out) { +void Request::printEnvironment(std::ostream& out) const { if (!active()) throw std::runtime_error("An attempt to print environment of a request in a wrong state"); @@ -198,7 +198,7 @@ void Request::printEnvironment(std::ostream& out) { } } -void Request::printEnvironment(nlohmann::json& out) { +void Request::printEnvironment(nlohmann::json& out) const { if (!out.is_object()) return; diff --git a/request/request.h b/request/request.h index dae582f..1cef22c 100644 --- a/request/request.h +++ b/request/request.h @@ -61,8 +61,8 @@ public: std::string getPath() const; std::string getServerName() const; std::string getAuthorizationToken() const; - void printEnvironment(std::ostream& out); - void printEnvironment(nlohmann::json& out); + void printEnvironment(std::ostream& out) const; + void printEnvironment(nlohmann::json& out) const; private: OStream getOutputStream(); diff --git a/server/router.cpp b/server/router.cpp index d64b875..2079bc6 100644 --- a/server/router.cpp +++ b/server/router.cpp @@ -62,19 +62,16 @@ void Router::handleNotFound(std::unique_ptr request) { std::string path = request->getPath(); notFound.setBody(std::string("Path \"") + path + "\" was not found"); notFound.send(); - std::cerr << notFound.statusCode() << '\t' << request->methodName() << '\t' << path << std::endl; } void Router::handleInternalError(const std::exception& exception, std::unique_ptr request) { Response& error = request->createResponse(Response::Status::internalError); error.setBody(std::string(exception.what())); error.send(); - std::cerr << error.statusCode() << '\t' << request->methodName() << '\t' << request->getPath() << std::endl; } void Router::handleMethodNotAllowed(std::unique_ptr request) { Response& error = request->createResponse(Response::Status::methodNotAllowed); error.setBody(std::string("Method not allowed")); error.send(); - std::cerr << error.statusCode() << '\t' << request->methodName() << '\t' << request->getPath() << std::endl; } diff --git a/server/server.cpp b/server/server.cpp index bc258ed..01c4cbb 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -11,6 +11,7 @@ #include "handler/env.h" #include "handler/register.h" #include "handler/login.h" +#include "handler/poll.h" #include "taskmanager/route.h" @@ -20,6 +21,7 @@ constexpr const char* dbPassword = "pica"; constexpr const char* dbName = "pica"; constexpr const char* dbPath = "/run/mysqld/mysqld.sock"; constexpr uint8_t dbConnectionsCount = 4; +constexpr uint32_t pollTimout = 10000; constexpr const char* randomChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; constexpr uint8_t saltSize = 16; @@ -64,31 +66,11 @@ void Server::run(int socketDescriptor) { router->addRoute(std::make_unique()); router->addRoute(std::make_unique(shared_from_this())); router->addRoute(std::make_unique(shared_from_this())); + router->addRoute(std::make_unique(shared_from_this())); taskManager->start(); scheduler->start(); - scheduler->schedule([]() { - std::cout << "5000" << std::endl; - }, TM::Scheduler::Delay(5000)); - scheduler->schedule([]() { - std::cout << "2000" << std::endl; - }, TM::Scheduler::Delay(2000)); - scheduler->schedule([]() { - std::cout << "6000" << std::endl; - }, TM::Scheduler::Delay(6000)); - - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - - scheduler->schedule([]() { - std::cout << "2000 + 500" << std::endl; - }, TM::Scheduler::Delay(2000)); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - scheduler->schedule([]() { - std::cout << "1000 + 600" << std::endl; - }, TM::Scheduler::Delay(1000)); - while (!terminating) { std::unique_ptr request = std::make_unique(); bool result = request->wait(socketDescriptor); @@ -192,7 +174,8 @@ Session& Server::openSession(const std::string& login) { if (sessionId == 0) throw std::runtime_error("Couldn't create session, ran out of attempts"); - std::unique_ptr& session = sessions[accessToken] = std::make_unique(scheduler, sessionId, accessToken, renewToken); + std::unique_ptr& session = sessions[accessToken] + = std::make_unique(scheduler, sessionId, accessToken, renewToken, pollTimout); return *session.get(); } @@ -207,7 +190,8 @@ Session& Server::getSession (const std::string& accessToken) { scheduler, s.id, s.accessToken, - s.renewToken + s.renewToken, + pollTimout ); return *session.get(); } diff --git a/server/session.cpp b/server/session.cpp index 6a1aeda..fe77381 100644 --- a/server/session.cpp +++ b/server/session.cpp @@ -9,14 +9,16 @@ Session::Session( std::weak_ptr scheduler, unsigned int id, const std::string& access, - const std::string& renew + const std::string& renew, + unsigned int timeout ): scheduler(scheduler), id(id), access(access), renew(renew), polling(nullptr), - timeoutId(TM::Scheduler::none) + timeoutId(TM::Scheduler::none), + timeout(timeout) {} Session::~Session () { @@ -37,14 +39,14 @@ std::string Session::getRenewToken() const { void Session::accept(std::unique_ptr request) { std::shared_ptr sch = scheduler.lock(); if (polling) { - Handler::Poll::error(*request.get(), Handler::Poll::Result::replace, Response::Status::ok); if (timeoutId != TM::Scheduler::none) { if (sch) sch->cancel(timeoutId); timeoutId = TM::Scheduler::none; } - //TODO unschedule + Handler::Poll::error(*polling.get(), Handler::Poll::Result::replace, Response::Status::ok); + polling.reset(); } if (!sch) { @@ -52,8 +54,7 @@ void Session::accept(std::unique_ptr request) { Handler::Poll::error(*request.get(), Handler::Poll::Result::unknownError, Response::Status::internalError); return; } - timeoutId = sch->schedule(std::bind(&Session::onTimeout, this), TM::Scheduler::Delay(5000)); - + timeoutId = sch->schedule(std::bind(&Session::onTimeout, this), timeout); polling = std::move(request); } diff --git a/server/session.h b/server/session.h index 7581352..55f84cb 100644 --- a/server/session.h +++ b/server/session.h @@ -14,7 +14,8 @@ public: std::weak_ptr scheduler, unsigned int id, const std::string& access, - const std::string& renew + const std::string& renew, + unsigned int timeout ); Session(const Session&) = delete; Session(Session&& other); @@ -36,4 +37,5 @@ private: std::string renew; std::unique_ptr polling; TM::Record::ID timeoutId; + TM::Scheduler::Delay timeout; };