diff --git a/CMakeLists.txt b/CMakeLists.txt index 412585b..b09caa9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,8 +18,8 @@ file(GLOB_RECURSE SOURCES ) file(GLOB_RECURSE HEADERS - "${CMAKE_SOURCE_DIR}/include/vibe/*.h") - + "${CMAKE_SOURCE_DIR}/include/vibe/*.h" +) add_library(vibe STATIC ${SOURCES} ${HEADERS}) install(TARGETS vibe diff --git a/include/vibe/main_process.h b/include/vibe/main_process.h deleted file mode 100644 index c9d20b5..0000000 --- a/include/vibe/main_process.h +++ /dev/null @@ -1,213 +0,0 @@ -// -// Created by scythe on 5/07/23. -// - -#ifndef MAIN_PROCESS_H -#define MAIN_PROCESS_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "util/enums.h" -#include "util/parameter_proccess.h" - -#include "routes.hpp" -#include "util/request.hpp" -#include "util/nterminal.h" - - -constexpr int BUFFER = enums::neo::eSize::BUFFER; -constexpr int SESSION = enums::neo::eSize::SESSION; -constexpr int INIT_MAX_EVENTS = 10; - -namespace workers { -using RoutesMap = std::unordered_map>; - - template - class pMain_t { - int epoll_fd; - unsigned short int next_register; - - std::vector events; - std::shared_ptr routes; - std::shared_ptr connection; - - public: - - explicit pMain_t(const std::shared_ptr &conn, const shared_ptr &_routes) : - - epoll_fd(epoll_create1(0)), - next_register(enums::neo::eSize::DEF_REG), - - events(std::vector(INIT_MAX_EVENTS)), - routes(_routes), - connection(conn) {} - - auto getMainProcess(std::shared_ptr &qProcess){ - return [&]()->void { - // creacion del socket - connection->on(); - const int file_descriptor = connection->getDescription(); - constexpr auto socket_len_error_value = static_cast(-1); - - if(Server::setNonblocking(file_descriptor) == MG_ERROR){ - close(file_descriptor); - } - - if (epoll_fd == -1) { - throw std::range_error(VB_EPOLL_RANGE); - } - - epoll_event event{}; - event.events = EPOLLIN; - event.data.fd = file_descriptor; - - if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, file_descriptor, &event) == VB_NVALUE) { - close(epoll_fd); - throw std::range_error(VB_EPOLL_CTL); - } - - while (static_cast(enums::neo::eStatus::START)){ - try { - qProcess = make_shared(); - - int notice = epoll_wait(epoll_fd, events.data(), INIT_MAX_EVENTS, VB_NVALUE); - if (notice == -1) { - terminal(VB_EPOLL_CERR, strerror(errno)); - break; - } - - for( int i = 0; i < notice; i++) { - if(events[i].data.fd == file_descriptor) { - - sockaddr_in client_addr{}; - socklen_t client_adrr_len = sizeof(client_addr); - int client_file_descriptor = accept(file_descriptor, reinterpret_cast(&client_addr), &client_adrr_len); - if(client_adrr_len == socket_len_error_value) { - continue; - } - Server::setNonblocking(client_file_descriptor); - - event.events = EPOLLIN | EPOLLET; - event.data.fd = client_file_descriptor; - if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_file_descriptor, &event) == VB_NVALUE) { - terminal(VB_EPOLL_CERR, strerror(errno)); - close(client_file_descriptor); - continue; - } - } else { - - // char buffer[DEF_BUFFER_SIZE] = {0}; - std::array buffer{}; - - if (const int bytes = recv(events[i].data.fd, buffer.data(), buffer.size(), VB_OK); bytes == VB_NVALUE) { - if (errno == EWOULDBLOCK) { - continue; - } - terminal(VB_EPOLL_CERR, strerror(errno)); - epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, nullptr); - close(events[i].data.fd); - continue; - } else if(bytes == VB_OK) { - epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, nullptr); - close(events[i].data.fd); - } else { - - shared_ptr base = std::make_shared(); - - base->setPort(connection->getPort()); - base->setSocketId(events[i].data.fd); - base->setResponse(buffer); - base->setEpollEvents(events); - base->setEpollfd(epoll_fd); - base->setNotices(notice); - - ExecuteRoute(base, qProcess, routes); - - } - } - } - } - - catch(const std::exception& e) { - terminal(e.what()); - close(epoll_fd); - if(close(file_descriptor) < VB_OK) - throw std::range_error(VB_MAIN_THREAD); - } - } - }; - - } - - static void ExecuteRoute(const shared_ptr &base,const shared_ptr&qProcess, const shared_ptr &routes) { - - string send_target = ERROR_GET; - - const string socket_response = base->getResponse(); - - if (socket_response.empty()){ - throw std::range_error(VB_SOCKET_FAIL); - } - - auto [type, route] = HTTP_QUERY::route_refactor(socket_response); - - if(const auto itr = routes->find(route + type); itr != routes->end()) { - - if(not timeGuard(itr)) { - - const string parameters = type == GET_TYPE ? - HTTP_QUERY::route_refactor_params_get(socket_response) - : HTTP_QUERY::route_refactor_params(socket_response); - - auto [data, time_key] = itr->second->middlewares.execute(parameters, - HTTP_QUERY::headers_from(socket_response), - itr->second->guardRouteMsg - ); - - if(time_key > VB_OK) { - itr->second->time_key = time_key; - itr->second->time_point = std::chrono::system_clock::now(); - } - send_target = std::move(data); - } else { - send_target = itr->second->guardRouteMsg != nullptr ? - utility_t::guard_route(itr->second->time_key, *itr->second->guardRouteMsg) - : utility_t::guard_route(itr->second->time_key); - } - } - - base->sendResponse(send_target); - - if (close(base->getDescription()) < enums::neo::eReturn::OK) { - throw std::range_error(VB_SOCKET_CLOSE); - } - } - - - - static bool timeGuard(const RoutesMap::const_iterator & itr) { - - if(itr->second->time_key <= 0) - return false; - if(itr->second->time_point == std::chrono::time_point()) - return false; - - const auto now = std::chrono::system_clock::now(); - - const std::chrono::duration distance = now - itr->second->time_point; - return distance.count() < itr->second->time_key; - } - - - }; -} - - -#endif //MAIN_PROCESS_H diff --git a/include/vibe/request/io.h b/include/vibe/request/io.h new file mode 100644 index 0000000..68b47fc --- /dev/null +++ b/include/vibe/request/io.h @@ -0,0 +1,61 @@ +// +// Created by owl on 19/08/24. +// + +#ifndef IO_H +#define IO_H + +#include +#include +#include +#include +#include + +#include "../util/enums.h" +#include "../util/parameter_proccess.h" + +#include "../routes.hpp" +#include "request.hpp" +#include "../util/nterminal.h" +#include "../sockets.h" +#include "../threading/thread_pool.h" + +using std::make_shared, std::vector, std::unique_ptr; + +using RoutesMap = std::unordered_map>; +/* + * RequestIO for Server socket class, if you want implement other Server, you should create other RequestIO for the implementation + */ +class RequestIO { + + private: + shared_ptr> events; + shared_ptr routes; + unique_ptr file_descriptor; + unique_ptr epoll_fd; + shared_ptr connection; + + shared_ptr thread_pool_; + + size_t threads_{4}; + + void Process(int, epoll_event&) const; + void ProcessFileDescriptor(int, int) const; + + public: + + RequestIO(const shared_ptr>&, + const shared_ptr &, + int &, + int &, + const shared_ptr&); + + + void Dispatch(int id, epoll_event &event) const; + void SetThreads(size_t size); + + static bool TimeGuard(const RoutesMap::const_iterator & itr); + static void ExecuteRoute(const shared_ptr &instance, const shared_ptr &routes); +}; + +#endif //IO_H diff --git a/include/vibe/util/parameters.hpp b/include/vibe/request/parameters.hpp similarity index 100% rename from include/vibe/util/parameters.hpp rename to include/vibe/request/parameters.hpp diff --git a/include/vibe/util/request.hpp b/include/vibe/request/request.hpp similarity index 96% rename from include/vibe/util/request.hpp rename to include/vibe/request/request.hpp index 27c4a0a..3adc384 100644 --- a/include/vibe/util/request.hpp +++ b/include/vibe/request/request.hpp @@ -7,7 +7,7 @@ #include #include #include "parameters.hpp" -#include "sysprocess.h" +#include "../util/sysprocess.h" using std::string; using std::vector; diff --git a/include/vibe/request/router_epoll.h b/include/vibe/request/router_epoll.h new file mode 100644 index 0000000..c2f4107 --- /dev/null +++ b/include/vibe/request/router_epoll.h @@ -0,0 +1,84 @@ +// +// Created by scythe on 5/07/23. +// + +#ifndef MAIN_PROCESS_H +#define MAIN_PROCESS_H + +#include +#include +#include +#include +#include + +#include "../util/enums.h" +#include "../util/parameter_proccess.h" + +#include "../routes.hpp" +#include "../util/nterminal.h" +#include "io.h" + +constexpr int BUFFER = enums::neo::eSize::BUFFER; +constexpr int SESSION = enums::neo::eSize::SESSION; +constexpr int INIT_MAX_EVENTS = 10; + +namespace workers { +using RoutesMap = std::unordered_map>; + + template + class RouterEpoll { + + int epoll_fd; + shared_ptr> events; + shared_ptr connection; + shared_ptr request_t; + + public: + + explicit RouterEpoll(const shared_ptr &conn) : + epoll_fd(epoll_create1(0)), + events(make_shared>(INIT_MAX_EVENTS)), + connection(conn) + {} + + auto getMainProcess(const shared_ptr &_routes){ + + connection->on(); + int file_descriptor = connection->getDescription(); + + if(Server::setNonblocking(file_descriptor) == MG_ERROR) + close(file_descriptor); + + if (epoll_fd == -1) + throw std::range_error(VB_EPOLL_RANGE); + + + epoll_event event{}; + event.events = EPOLLIN; + event.data.fd = file_descriptor; + + if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, file_descriptor, &event) == VB_NVALUE) { + close(epoll_fd); + throw std::range_error(VB_EPOLL_CTL); + } + + request_t = make_shared(events, _routes, file_descriptor, epoll_fd, connection); + + while (static_cast(enums::neo::eStatus::START)){ + try { + const int notice = epoll_wait(epoll_fd, events->data(), INIT_MAX_EVENTS, VB_NVALUE); + request_t->Dispatch(notice, event); + } + catch(const std::exception& e) { + terminal(e.what()); + close(epoll_fd); + if(close(file_descriptor) < VB_OK) + throw std::range_error(VB_MAIN_THREAD); + } + } + } + }; +} + + +#endif //MAIN_PROCESS_H diff --git a/include/vibe/routes.hpp b/include/vibe/routes.hpp index c4d34a5..8e2f6df 100644 --- a/include/vibe/routes.hpp +++ b/include/vibe/routes.hpp @@ -11,7 +11,7 @@ #include -#include "util/request.hpp" +#include "request/request.hpp" #include "util/basic_render.h" #include "util/cpp_reader.h" diff --git a/include/vibe/sockets.h b/include/vibe/sockets.h index 5902c7b..6b2c752 100644 --- a/include/vibe/sockets.h +++ b/include/vibe/sockets.h @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -64,10 +65,11 @@ class Engine { virtual ~Engine() = default; - [[maybe_unused]] [[nodiscard]] int + [[maybe_unused]] int setBuffer(int), - setPort(uint16_t), - getPort() const; + setPort(uint16_t); + + [[nodiscard]] int getPort() const; virtual int on() = 0; virtual void getResponseProcessing() = 0; @@ -102,7 +104,7 @@ class Server final : public Engine { [[maybe_unused]] [[nodiscard]] inline int getDescription() const { return *socket_id; } [[maybe_unused]] inline shared_ptr getSocketId() { return socket_id; } - [[maybe_unused]] inline void setSocketId(int const identity) { socket_id.reset(new int(identity)); } + [[maybe_unused]] inline void setSocketId(int const identity) { socket_id = std::make_shared(identity); } void setSessions(int); void sendResponse(const string&) const; diff --git a/include/vibe/threading/thread_pool.h b/include/vibe/threading/thread_pool.h new file mode 100644 index 0000000..d3bef0d --- /dev/null +++ b/include/vibe/threading/thread_pool.h @@ -0,0 +1,45 @@ +#ifndef THREAD_POOL_H +#define THREAD_POOL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../util/enums.h" + + +namespace threading { + + using std::vector, std::mutex, std::condition_variable, std::atomic, std::queue, std::thread; + using std::make_shared, std::shared_ptr, std::packaged_task, std::future; + + + class ThreadPool { + + vector threads_; + size_t size_; + + queue> queue_; + atomic stop_; + + mutex mutex_; + condition_variable condition_; + + + public: + + explicit ThreadPool(size_t threads); + ~ThreadPool(); + + future addTask(std::function task); + + }; + +} + +#endif //THREAD_POOL_H diff --git a/include/vibe/util/parameter_proccess.h b/include/vibe/util/parameter_proccess.h index 18bbc95..88b5439 100644 --- a/include/vibe/util/parameter_proccess.h +++ b/include/vibe/util/parameter_proccess.h @@ -24,7 +24,7 @@ constexpr auto RAW_TARGET = "data="; #include #include -#include "request.hpp" +#include "../request/request.hpp" using std::string; using std::make_shared; diff --git a/include/vibe/util/worker_core.h b/include/vibe/util/worker_core.h deleted file mode 100644 index 9bdc8ee..0000000 --- a/include/vibe/util/worker_core.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// Created by scythe on 15/07/23. -// - -#ifndef VIBE_CORE_WORKER_CORE_H -#define VIBE_CORE_WORKER_CORE_H - -#include "../main_process.h" - -namespace workers { - template - class eWorkers { - public: - eWorkers(); - std::unique_ptr> Main = nullptr; - }; - template - eWorkers