1
0
forked from blue/pica

task manager, license formatting

This commit is contained in:
Blue 2023-12-30 19:42:11 -03:00
parent fe2fbb9ad0
commit f1a2006b4b
Signed by untrusted user: blue
GPG Key ID: 9B203B252A63EE38
69 changed files with 380 additions and 122 deletions

View File

@ -1,3 +1,6 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-later
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
project(pica project(pica
VERSION 0.0.1 VERSION 0.0.1
@ -54,6 +57,7 @@ add_subdirectory(response)
add_subdirectory(stream) add_subdirectory(stream)
add_subdirectory(database) add_subdirectory(database)
add_subdirectory(utils) add_subdirectory(utils)
add_subdirectory(taskmanager)
configure_file(config.h.in config.h @ONLY) configure_file(config.h.in config.h @ONLY)
configure_file(run.sh.in run.sh @ONLY) configure_file(run.sh.in run.sh @ONLY)

View File

@ -1,3 +1,6 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-later
find_library(Argon2_LIBRARIES argon2) find_library(Argon2_LIBRARIES argon2)
find_path(Argon2_INCLUDE_DIR argon2.h) find_path(Argon2_INCLUDE_DIR argon2.h)

View File

@ -1,3 +1,6 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-later
find_library(FCGI_LIBRARIES fcgi NAMES FCGI libfcgi) find_library(FCGI_LIBRARIES fcgi NAMES FCGI libfcgi)
find_library(FCGI++_LIBRARIES fcgi++ NAMES FCGI++ libfcgi++) find_library(FCGI++_LIBRARIES fcgi++ NAMES FCGI++ libfcgi++)

View File

@ -1,3 +1,6 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-laterlater
find_library(MariaDB_CLIENT_LIBRARIES mysqlclient NAMES mariadbclient) find_library(MariaDB_CLIENT_LIBRARIES mysqlclient NAMES mariadbclient)
find_path(MariaDB_INCLUDE_DIR mysql/mysql.h) find_path(MariaDB_INCLUDE_DIR mysql/mysql.h)

View File

@ -1,3 +1,6 @@
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#pragma once #pragma once
#define FULL_DATA_DIR "@CMAKE_INSTALL_FULL_DATADIR@" #define FULL_DATA_DIR "@CMAKE_INSTALL_FULL_DATADIR@"

View File

@ -1,3 +1,6 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-later
set(HEADERS set(HEADERS
interface.h interface.h
exceptions.h exceptions.h

View File

@ -1,3 +1,6 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-laterater
set(MIGRATIONS migrations) set(MIGRATIONS migrations)
configure_file(m0.sql ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/${MIGRATIONS}/m0.sql COPYONLY) configure_file(m0.sql ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/${MIGRATIONS}/m0.sql COPYONLY)

View File

@ -1,3 +1,6 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-laterr
set(HEADERS set(HEADERS
mysql.h mysql.h
statement.h statement.h

View File

@ -1,3 +1,6 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-later
set(HEADERS set(HEADERS
handler.h handler.h
info.h info.h

View File

@ -6,7 +6,7 @@
#include "server/server.h" #include "server/server.h"
#include "database/exceptions.h" #include "database/exceptions.h"
Handler::Login::Login(Server* server): Handler::Login::Login(std::weak_ptr<Server> server):
Handler("login", Request::Method::post), Handler("login", Request::Method::post),
server(server) server(server)
{} {}
@ -29,9 +29,13 @@ void Handler::Login::handle(Request& request) {
if (password.empty()) if (password.empty())
return error(request, Result::emptyPassword, Response::Status::badRequest); return error(request, Result::emptyPassword, Response::Status::badRequest);
std::shared_ptr<Server> srv = server.lock();
if (!srv)
return error(request, Result::unknownError, Response::Status::internalError);
bool success = false; bool success = false;
try { try {
success = server->validatePassword(login, password); success = srv->validatePassword(login, password);
} catch (const DB::NoLogin& e) { } catch (const DB::NoLogin& e) {
std::cerr << "Exception on logging in:\n\t" << e.what() << std::endl; std::cerr << "Exception on logging in:\n\t" << e.what() << std::endl;
return error(request, Result::wrongCredentials, Response::Status::badRequest); return error(request, Result::wrongCredentials, Response::Status::badRequest);
@ -49,7 +53,7 @@ void Handler::Login::handle(Request& request) {
body["result"] = Result::success; body["result"] = Result::success;
try { try {
Session& session = server->openSession(login); Session& session = srv->openSession(login);
body["accessToken"] = session.getAccessToken(); body["accessToken"] = session.getAccessToken();
body["renewToken"] = session.getRenewToken(); body["renewToken"] = session.getRenewToken();
} catch (const std::exception& e) { } catch (const std::exception& e) {

View File

@ -3,6 +3,8 @@
#pragma once #pragma once
#include <memory>
#include "handler.h" #include "handler.h"
class Server; class Server;
@ -10,7 +12,7 @@ namespace Handler {
class Login : public Handler { class Login : public Handler {
public: public:
Login(Server* server); Login(std::weak_ptr<Server> server);
void handle(Request& request) override; void handle(Request& request) override;
enum class Result { enum class Result {
@ -27,7 +29,7 @@ private:
void error(Request& request, Result result, Response::Status code); void error(Request& request, Result result, Response::Status code);
private: private:
Server* server; std::weak_ptr<Server> server;
}; };
} }

View File

@ -6,7 +6,7 @@
#include "server/server.h" #include "server/server.h"
#include "database/exceptions.h" #include "database/exceptions.h"
Handler::Register::Register(Server* server): Handler::Register::Register(std::weak_ptr<Server> server):
Handler("register", Request::Method::post), Handler("register", Request::Method::post),
server(server) server(server)
{} {}
@ -33,8 +33,12 @@ void Handler::Register::handle(Request& request) {
//TODO password policies checkup //TODO password policies checkup
std::shared_ptr<Server> srv = server.lock();
if (!srv)
return error(request, Result::unknownError, Response::Status::internalError);
try { try {
server->registerAccount(login, password); srv->registerAccount(login, password);
} catch (const DB::DuplicateLogin& e) { } catch (const DB::DuplicateLogin& e) {
std::cerr << "Exception on registration:\n\t" << e.what() << std::endl; std::cerr << "Exception on registration:\n\t" << e.what() << std::endl;
return error(request, Result::loginExists, Response::Status::conflict); return error(request, Result::loginExists, Response::Status::conflict);

View File

@ -3,6 +3,8 @@
#pragma once #pragma once
#include <memory>
#include "handler.h" #include "handler.h"
class Server; class Server;
@ -10,7 +12,7 @@ namespace Handler {
class Register : public Handler { class Register : public Handler {
public: public:
Register(Server* server); Register(std::weak_ptr<Server> server);
void handle(Request& request) override; void handle(Request& request) override;
enum class Result { enum class Result {
@ -29,6 +31,6 @@ private:
void error(Request& request, Result result, Response::Status code); void error(Request& request, Result result, Response::Status code);
private: private:
Server* server; std::weak_ptr<Server> server;
}; };
} }

View File

@ -7,6 +7,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <iostream> #include <iostream>
#include <memory>
#include "config.h" //autogenereted by cmake in the root of bindir #include "config.h" //autogenereted by cmake in the root of bindir
#include "utils/helpers.h" #include "utils/helpers.h"
@ -34,6 +35,6 @@ int main(int argc, char** argv) {
FCGX_Init(); FCGX_Init();
Server server; auto server = std::make_shared<Server>();
server.run(sockfd); server->run(sockfd);
} }

View File

@ -1,3 +1,6 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-later
set(HEADERS set(HEADERS
request.h request.h
redirect.h redirect.h

View File

@ -140,8 +140,8 @@ void Request::responseIsComplete() {
throw std::runtime_error("An attempt to mark the request as complete, but it wasn't responded"); throw std::runtime_error("An attempt to mark the request as complete, but it wasn't responded");
break; break;
case State::responding: case State::responding:
std::cout << responseCode() << '\t' << methodName() << '\t' << path << std::endl;
state = State::responded; state = State::responded;
std::cout << responseCode() << '\t' << methodName() << '\t' << path << std::endl;
break; break;
case State::responded: case State::responded:
throw std::runtime_error("An attempt to mark the request as a complete for the second time"); throw std::runtime_error("An attempt to mark the request as a complete for the second time");

View File

@ -1,3 +1,6 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-later
set(HEADERS set(HEADERS
response.h response.h
) )

View File

@ -1,5 +1,8 @@
#!/bin/bash #!/bin/bash
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-later
start_service() { start_service() {
if systemctl is-active --quiet $1 if systemctl is-active --quiet $1
then then

View File

@ -1,3 +1,6 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-later
set(HEADERS set(HEADERS
server.h server.h
router.h router.h

View File

@ -12,6 +12,8 @@
#include "handler/register.h" #include "handler/register.h"
#include "handler/login.h" #include "handler/login.h"
#include "taskmanager/route.h"
constexpr const char* pepper = "well, not much of a secret, huh?"; constexpr const char* pepper = "well, not much of a secret, huh?";
constexpr const char* dbLogin = "pica"; constexpr const char* dbLogin = "pica";
constexpr const char* dbPassword = "pica"; constexpr const char* dbPassword = "pica";
@ -29,11 +31,13 @@ constexpr uint32_t hashMemoryCost = 65536;
constexpr uint8_t currentDbVesion = 1; constexpr uint8_t currentDbVesion = 1;
Server::Server(): Server::Server():
std::enable_shared_from_this<Server>(),
terminating(false), terminating(false),
requestCount(0), requestCount(0),
serverName(std::nullopt), serverName(std::nullopt),
router(), router(std::make_shared<Router>()),
pool(DB::Pool::create()), pool(DB::Pool::create()),
taskManager(std::make_shared<TM::Manager>()),
sessions() sessions()
{ {
std::cout << "Startig pica..." << std::endl; std::cout << "Startig pica..." << std::endl;
@ -50,16 +54,18 @@ Server::Server():
DB::Resource db = pool->request(); DB::Resource db = pool->request();
db->migrate(currentDbVesion); db->migrate(currentDbVesion);
router.addRoute(std::make_unique<Handler::Info>());
router.addRoute(std::make_unique<Handler::Env>());
router.addRoute(std::make_unique<Handler::Register>(this));
router.addRoute(std::make_unique<Handler::Login>(this));
} }
Server::~Server() {} Server::~Server() {}
void Server::run(int socketDescriptor) { void Server::run(int socketDescriptor) {
router->addRoute(std::make_unique<Handler::Info>());
router->addRoute(std::make_unique<Handler::Env>());
router->addRoute(std::make_unique<Handler::Register>(shared_from_this()));
router->addRoute(std::make_unique<Handler::Login>(shared_from_this()));
taskManager->start();
while (!terminating) { while (!terminating) {
std::unique_ptr<Request> request = std::make_unique<Request>(); std::unique_ptr<Request> request = std::make_unique<Request>();
bool result = request->wait(socketDescriptor); bool result = request->wait(socketDescriptor);
@ -86,7 +92,9 @@ void Server::handleRequest(std::unique_ptr<Request> request) {
} }
request->readPath(serverName.value()); request->readPath(serverName.value());
router.route(std::move(request));
auto route = std::make_unique<TM::Route>(router, std::move(request));
taskManager->schedule(std::move(route));
} }
std::string Server::generateRandomString(std::size_t length) { std::string Server::generateRandomString(std::size_t length) {

View File

@ -25,8 +25,9 @@
#include "database/pool.h" #include "database/pool.h"
#include "utils/helpers.h" #include "utils/helpers.h"
#include "config.h" #include "config.h"
#include "taskmanager/manager.h"
class Server { class Server : public std::enable_shared_from_this<Server> {
public: public:
Server(); Server();
~Server(); ~Server();
@ -48,7 +49,8 @@ private:
bool terminating; bool terminating;
uint64_t requestCount; uint64_t requestCount;
std::optional<std::string> serverName; std::optional<std::string> serverName;
Router router; std::shared_ptr<Router> router;
std::shared_ptr<DB::Pool> pool; std::shared_ptr<DB::Pool> pool;
std::shared_ptr<TM::Manager> taskManager;
Sessions sessions; Sessions sessions;
}; };

View File

@ -1,3 +1,6 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-later
set(HEADERS set(HEADERS
stream.h stream.h
ostream.h ostream.h

View File

@ -0,0 +1,16 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-later
set(HEADERS
manager.h
job.h
route.h
)
set(SOURCES
manager.cpp
job.cpp
route.cpp
)
target_sources(${PROJECT_NAME} PRIVATE ${SOURCES})

9
taskmanager/job.cpp Normal file
View File

@ -0,0 +1,9 @@
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#include "job.h"
TM::Job::Job ()
{}
TM::Job::~Job () {}

19
taskmanager/job.h Normal file
View File

@ -0,0 +1,19 @@
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
namespace TM {
class Job {
public:
Job();
Job(const Job& other) = delete;
Job(Job&& other) = delete;
virtual ~Job();
Job& operator = (const Job& other) = delete;
Job& operator = (Job&& other) = delete;
virtual void execute() = 0;
};
}

69
taskmanager/manager.cpp Normal file
View File

@ -0,0 +1,69 @@
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#include "manager.h"
TM::Manager::Manager ():
terminating(false),
threads(),
queue(),
mtx(),
cond()
{}
TM::Manager::~Manager () {
std::unique_lock lock(mtx);
if (threads.empty())
return;
lock.unlock();
stop();
}
void TM::Manager::start () {
std::lock_guard lock(mtx);
std::size_t amount = std::thread::hardware_concurrency();
for (std::size_t i = 0; i < amount; ++i)
threads.emplace_back(std::thread(&Manager::loop, this));
}
void TM::Manager::stop () {
std::unique_lock lock(mtx);
terminating = true;
lock.unlock();
cond.notify_all();
for (std::thread& thread : threads)
thread.join();
lock.lock();
threads.clear();
terminating = false;
}
void TM::Manager::loop () {
while (true) {
std::unique_lock lock(mtx);
while (!terminating && queue.empty())
cond.wait(lock);
if (terminating)
return;
std::unique_ptr<Job> job = std::move(queue.front());
queue.pop();
lock.unlock();
job->execute();
}
}
void TM::Manager::schedule (std::unique_ptr<Job> job) {
std::unique_lock lock(mtx);
queue.emplace(std::move(job));
lock.unlock();
cond.notify_one();
}

40
taskmanager/manager.h Normal file
View File

@ -0,0 +1,40 @@
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <queue>
#include <vector>
#include <thread>
#include <memory>
#include <mutex>
#include <condition_variable>
#include "job.h"
namespace TM {
class Manager {
public:
Manager();
Manager(const Manager&) = delete;
Manager(Manager&&) = delete;
~Manager();
Manager& operator = (const Manager&) = delete;
Manager& operator = (Manager&&) = delete;
void start();
void stop();
void schedule(std::unique_ptr<Job> job);
private:
void loop();
private:
bool terminating;
std::vector<std::thread> threads;
std::queue<std::unique_ptr<Job>> queue;
std::mutex mtx;
std::condition_variable cond;
};
}

13
taskmanager/route.cpp Normal file
View File

@ -0,0 +1,13 @@
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#include "route.h"
TM::Route::Route (std::shared_ptr<Router> router, std::unique_ptr<Request> request):
router(router),
request(std::move(request))
{}
void TM::Route::execute () {
router->route(std::move(request));
}

23
taskmanager/route.h Normal file
View File

@ -0,0 +1,23 @@
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <memory>
#include "job.h"
#include "server/router.h"
#include "request/request.h"
namespace TM {
class Route : public Job {
public:
Route(std::shared_ptr<Router> router, std::unique_ptr<Request> request);
void execute () override;
private:
std::shared_ptr<Router> router;
std::unique_ptr<Request> request;
};
}

View File

@ -1,3 +1,6 @@
#SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
#SPDX-License-Identifier: GPL-3.0-or-later
set(HEADER set(HEADER
helpers.h helpers.h
formdecode.h formdecode.h