Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Server provides data to be handled by calling a callback in case if this data is
- [**HTML:**](library/source/help/html.h) Parser module.
- [**JSON:**](library/source/help/json.h) Parser and producer module.
- [**Table:**](library/source/help/table.h) Data structure.
- [**Pthread:**](library/source/help/pthread.hpp) Module to synchronize threads.
- [**Lock:**](library/source/help/lock.inl) Mutexes and atomic locks to manage concurrency.
- [**IO:**](library/source/help/io.inl) Filesystem I/O utilities.
- [**Helper:**](library/source/help/helper.h) Miscellaneous utilities for common tasks.
- [**Meta:**](library/source/help/meta.hpp) Static enum translation, type helpers, and compile-time utilities.
Expand Down
36 changes: 20 additions & 16 deletions apps/manager/source/manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
#include <algorithm>
#include <sys/wait.h>

/*---------------------------------------------------------------------------------
Manager
---------------------------------------------------------------------------------*/

Manager::Manager()
: MSAPI::Protocol::HTTP::IHandler(this)
, MSAPI::Protocol::WebSocket::IHandler(this)
Expand Down Expand Up @@ -254,7 +258,7 @@ void Manager::HandleRunRequest()
return viewValue;
}() };

MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::write> _{ m_hashToInstalledAppDataLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::write> _{ m_hashToInstalledAppDataLock };
appId = MSAPI::Helper::StringHash32Uint(*appValue);
auto it{ m_hashToInstalledAppData.find(appId) };
if (it == m_hashToInstalledAppData.end()) {
Expand Down Expand Up @@ -287,7 +291,7 @@ void Manager::HandleRunRequest()
}

{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_hashToInstalledAppDataLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_hashToInstalledAppDataLock };
if (m_hashToInstalledAppData.empty()) {
LOG_ERROR("No apps registered, manager is going to end its work");
HandlePauseRequest();
Expand All @@ -310,7 +314,7 @@ void Manager::HandlePauseRequest()
m_streamsDistributor.FailActiveEvents("Manager is paused");

{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::write> _{ m_portToCreatedAppLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::write> _{ m_portToCreatedAppLock };
for (const auto& [port, createdAppData] : m_portToCreatedApp) {
if (createdAppData->connection == 0) [[unlikely]] {
LOG_WARNING_NEW("Created app on port {} still did not connect and cannot be deleted", port);
Expand All @@ -323,12 +327,12 @@ void Manager::HandlePauseRequest()
}

{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::write> _{ m_hashToInstalledAppDataLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::write> _{ m_hashToInstalledAppDataLock };
m_hashToInstalledAppData.clear();
}

{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::write> _{ m_tableIdToColumnsLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::write> _{ m_tableIdToColumnsLock };
m_tableIdToColumns.clear();
}

Expand Down Expand Up @@ -371,7 +375,7 @@ void Manager::HandleParameters(const int connection, const std::map<size_t, std:

std::shared_ptr<CreatedAppData> createdAppData;
{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_portToCreatedAppLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_portToCreatedAppLock };
auto createdAppDataIt{ m_portToCreatedApp.find(*port) };
if (createdAppDataIt == m_portToCreatedApp.end()) {
LOG_ERROR("App with port: " + _S(port) + " is not found");
Expand Down Expand Up @@ -457,7 +461,7 @@ void Manager::HandleParameters(const int connection, const std::map<size_t, std:
else if constexpr (std::is_same_v<T, MSAPI::TableData>) {
std::shared_ptr<std::vector<MSAPI::StandardType::Type>> tableColumns;
{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_tableIdToColumnsLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_tableIdToColumnsLock };
const auto it{ m_tableIdToColumns.find(id) };
if (it == m_tableIdToColumns.end()) [[unlikely]] {
LOG_DEBUG("Columns for table with id: " + _S(id) + " are not found");
Expand Down Expand Up @@ -501,7 +505,7 @@ void Manager::HandleMetadata(const int connection, const std::string_view metada
{
std::shared_ptr<CreatedAppData> createdAppData;
{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_portToCreatedAppLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_portToCreatedAppLock };
if (std::ranges::none_of(m_portToCreatedApp, [connection, &createdAppData](const auto& data) {
if (data.second->connection == connection) {
createdAppData = data.second;
Expand Down Expand Up @@ -554,7 +558,7 @@ void Manager::HandleMetadata(const int connection, const std::string_view metada
}

{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_tableIdToColumnsLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_tableIdToColumnsLock };
if (m_tableIdToColumns.find(tableId) != m_tableIdToColumns.end()) {
continue;
}
Expand Down Expand Up @@ -664,7 +668,7 @@ void Manager::HandleMetadata(const int connection, const std::string_view metada
continue;
}

MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::write> _{ m_tableIdToColumnsLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::write> _{ m_tableIdToColumnsLock };
m_tableIdToColumns.emplace(tableId, std::move(columnTypes));
LOG_DEBUG("Columns for table with id: " + _S(tableId) + " are found, connection: " + _S(connection));
}
Expand Down Expand Up @@ -705,7 +709,7 @@ uint16_t Manager::CreateApp(const uint64_t hash, const MSAPI::Json& parameters,
{
std::shared_ptr<InstalledAppData> installedAppData;
{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_hashToInstalledAppDataLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_hashToInstalledAppDataLock };
auto it{ m_hashToInstalledAppData.find(hash) };
if (it == m_hashToInstalledAppData.end()) {
error = std::format("Unknow app type hash {}", hash);
Expand Down Expand Up @@ -832,7 +836,7 @@ uint16_t Manager::CreateApp(const uint64_t hash, const MSAPI::Json& parameters,
LOG_INFO("App: " + installedAppData->type + ", id: " + _S(hash) + " created with pid: " + _S(pid));
auto createdAppData{ std::make_shared<CreatedAppData>(hash, pid, installedAppData) };
{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::write> _{ m_portToCreatedAppLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::write> _{ m_portToCreatedAppLock };
m_portToCreatedApp.emplace(port, createdAppData);
}
const auto serialize{ [&installedAppData, &createdAppData, port, pid](std::string& data) {
Expand Down Expand Up @@ -904,7 +908,7 @@ void Manager::CheckVforkedApps()
}

{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_portToCreatedAppLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_portToCreatedAppLock };
if (std::ranges::none_of(m_portToCreatedApp, [pid, &port, &createdAppData](const auto& data) {
if (data.second->pid == pid) {
port = data.first;
Expand All @@ -930,7 +934,7 @@ void Manager::CheckVforkedApps()
}

{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::write> _{ m_portToCreatedAppLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::write> _{ m_portToCreatedAppLock };
m_portToCreatedApp.erase(port);
m_portGenerator.Erase(port);
}
Expand All @@ -946,7 +950,7 @@ void Manager::CheckVforkedApps()
}

/*---------------------------------------------------------------------------------
CreatedAppData
Manager::InstalledAppData
---------------------------------------------------------------------------------*/

Manager::InstalledAppData::InstalledAppData(const std::string& type, const std::string& bin)
Expand All @@ -958,7 +962,7 @@ Manager::InstalledAppData::InstalledAppData(const std::string& type, const std::
}

/*---------------------------------------------------------------------------------
CreatedAppData
Manager::CreatedAppData
---------------------------------------------------------------------------------*/

Manager::CreatedAppData::CreatedAppData(
Expand Down
42 changes: 21 additions & 21 deletions apps/manager/source/manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#define MSAPI_APP_MANAGER_H

#include "../../../library/source/help/json.h"
#include "../../../library/source/help/pthread.hpp"
#include "../../../library/source/help/lock.inl"
#include "../../../library/source/protocol/http.h"
#include "../../../library/source/protocol/object.h"
#include "../../../library/source/protocol/webSocket.inl"
Expand Down Expand Up @@ -69,18 +69,18 @@
*/
class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Protocol::WebSocket::IHandler {
private:
/**
/**************************
* @brief Synched generator of unique ports.
*/
class PortGenerator {
private:
std::set<uint16_t> m_ports;
MSAPI::Pthread::AtomicLock m_portsLock;
MSAPI::Lock::Atomic m_portsLock;
std::mt19937 m_mersenne;
const int32_t m_limit{ 50000 };

public:
/**
/**************************
* @return Unique port.
*
* @todo Add unit test.
Expand All @@ -90,7 +90,7 @@ class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Pr
uint16_t port;
int32_t counter{};

MSAPI::Pthread::AtomicLock::ExitGuard _{ m_portsLock };
MSAPI::Lock::Atomic::Guard _{ m_portsLock };
m_mersenne.seed(static_cast<uint64_t>(MSAPI::Timer{}.GetNanoseconds()));
do {
port = static_cast<uint16_t>(m_mersenne() % (65535 - 3000) + 3000);
Expand All @@ -103,7 +103,7 @@ class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Pr
return 0;
}

/**
/**************************
* @brief Erase port from range of used.
*
* @param port Port to be erased.
Expand All @@ -112,18 +112,18 @@ class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Pr
*/
FORCE_INLINE void Erase(const uint16_t port) noexcept
{
MSAPI::Pthread::AtomicLock::ExitGuard _{ m_portsLock };
MSAPI::Lock::Atomic::Guard _{ m_portsLock };
m_ports.erase(port);
}

/**
/**************************
* @brief Clear range of used ports.
*
* @todo Add unit test.
*/
FORCE_INLINE void Clear() noexcept
{
MSAPI::Pthread::AtomicLock::ExitGuard _{ m_portsLock };
MSAPI::Lock::Atomic::Guard _{ m_portsLock };
m_ports.clear();
}
};
Expand Down Expand Up @@ -186,11 +186,11 @@ class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Pr
private:
std::string m_webSourcesPath;
std::map<size_t, std::shared_ptr<InstalledAppData>> m_hashToInstalledAppData;
MSAPI::Pthread::AtomicRWLock m_hashToInstalledAppDataLock;
MSAPI::Lock::AtomicRW m_hashToInstalledAppDataLock;
std::map<uint16_t, std::shared_ptr<CreatedAppData>> m_portToCreatedApp;
MSAPI::Pthread::AtomicRWLock m_portToCreatedAppLock;
MSAPI::Lock::AtomicRW m_portToCreatedAppLock;
std::map<size_t, std::shared_ptr<std::vector<MSAPI::StandardType::Type>>> m_tableIdToColumns;
MSAPI::Pthread::AtomicRWLock m_tableIdToColumnsLock;
MSAPI::Lock::AtomicRW m_tableIdToColumnsLock;
MSAPI::Authorization::Base::Module<> m_authorizationModule;
MSAPI::Protocol::WebSocket::Events::SinglesDistributor<MSAPI::Authorization::Base::Module<>> m_singlesDistributor{
m_authorizationModule
Expand Down Expand Up @@ -235,7 +235,7 @@ class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Pr
auto backIt{ std::back_inserter(out) };
std::format_to(backIt, "[");
{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_hashToInstalledAppDataLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_hashToInstalledAppDataLock };
if (!m_hashToInstalledAppData.empty()) {
auto it{ m_hashToInstalledAppData.begin() };
const auto end{ m_hashToInstalledAppData.end() };
Expand Down Expand Up @@ -269,7 +269,7 @@ class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Pr
return MSAPI::Protocol::WebSocket::Events::HandleResult::Fail;
}

MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_hashToInstalledAppDataLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_hashToInstalledAppDataLock };
const auto it{ m_hashToInstalledAppData.find(*appType) };
if (it == m_hashToInstalledAppData.end()) {
out = std::format("Metadata request contains unknown appType: {}", *appType);
Expand Down Expand Up @@ -457,7 +457,7 @@ class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Pr

int32_t connection;
{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_portToCreatedAppLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_portToCreatedAppLock };
const auto it{ m_portToCreatedApp.find(static_cast<uint16_t>(*port)) };
if (it == m_portToCreatedApp.end()) {
out = std::format("App on port {} is not found", *port);
Expand Down Expand Up @@ -488,7 +488,7 @@ class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Pr

int32_t connection;
{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_portToCreatedAppLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_portToCreatedAppLock };
const auto it{ m_portToCreatedApp.find(static_cast<uint16_t>(*port)) };
if (it == m_portToCreatedApp.end()) {
out = std::format("App on port {} is not found", *port);
Expand Down Expand Up @@ -519,7 +519,7 @@ class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Pr

int32_t connection;
{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_portToCreatedAppLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_portToCreatedAppLock };
const auto it{ m_portToCreatedApp.find(static_cast<uint16_t>(*port)) };
if (it == m_portToCreatedApp.end()) {
out = std::format("App on port {} is not found", *port);
Expand Down Expand Up @@ -557,7 +557,7 @@ class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Pr

std::shared_ptr<CreatedAppData> createdAppData;
{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_portToCreatedAppLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_portToCreatedAppLock };
const auto it{ m_portToCreatedApp.find(static_cast<uint16_t>(*port)) };
if (it == m_portToCreatedApp.end()) {
out = std::format("App on port {} is not found", *port);
Expand Down Expand Up @@ -685,7 +685,7 @@ class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Pr

std::shared_ptr<std::vector<MSAPI::StandardType::Type>> columns;
{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_tableIdToColumnsLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_tableIdToColumnsLock };
const auto it{ m_tableIdToColumns.find(key) };
if (it == m_tableIdToColumns.end()) [[unlikely]] {
LOG_ERROR_NEW("Columns for table with id: {} are not found, app with port: {}", key, *port);
Expand Down Expand Up @@ -822,7 +822,7 @@ class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Pr
auto backIt{ std::back_inserter(out) };
std::format_to(backIt, "{{\"created\":[");
{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_portToCreatedAppLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_portToCreatedAppLock };
if (!m_portToCreatedApp.empty()) {
auto it{ m_portToCreatedApp.begin() };
const auto end{ m_portToCreatedApp.end() };
Expand Down Expand Up @@ -852,7 +852,7 @@ class Manager : public MSAPI::Server, MSAPI::Protocol::HTTP::IHandler, MSAPI::Pr

int32_t connection;
{
MSAPI::Pthread::AtomicRWLock::ExitGuard<MSAPI::Pthread::read> _{ m_portToCreatedAppLock };
MSAPI::Lock::AtomicRW::Guard<MSAPI::Lock::read> _{ m_portToCreatedAppLock };
const auto createdAppDataIt{ m_portToCreatedApp.find(static_cast<uint16_t>(*port)) };
if (createdAppDataIt == m_portToCreatedApp.end()) {
out = std::format("App on port {} does not exist", *port);
Expand Down
8 changes: 4 additions & 4 deletions apps/manager/web/js/help/dynamic.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
* Required Notice: MSAPI, copyright © 2021–2026 Maksim Andreevich Leonov, maks.angels@mail.ru
*/

/**
/**************************
* @brief Helpers to add interface dynamic.
*/
class Dynamic {

/**
/**************************
* @brief Add clicking to data-form-item='button' by pressing enter in any data-form-item='input' inside provided
* node.
*/
Expand Down Expand Up @@ -50,7 +50,7 @@ class Dynamic {
});
}

/**
/**************************
* @brief Clear value for all data-form-item='input' inside provided node.
*/
static ClearForm(node)
Expand All @@ -64,7 +64,7 @@ class Dynamic {
inputs.forEach(element => { element.value = ""; });
}

/**
/**************************
* @brief Add data-trigger-[toggle|remove|add]='id1,id2' action to each mentioned id and invoke with "active" class
* to each data-trigger-id='id' inside provided node.
*/
Expand Down
2 changes: 1 addition & 1 deletion apps/manager/web/js/help/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ class Helper {
*/
static FloatEqual(first, second, epsilon = 1e-10) { return Math.abs(first - second) < epsilon; }

/**
/**************************
* @return Unsigned 32 bit hash for provided string.
*/
static StringHash32Uint(str)
Expand Down
2 changes: 1 addition & 1 deletion apps/manager/web/js/test/serverSimulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const { WebSocketServer } = require('ws');
const Helper = require("../help/helper");
const WebSocketStream = require("../core/webSocketHandler").WebSocketStream;

/**
/**************************
* @brief Server's behavior simulator.
*/
class ServerSimulator {
Expand Down
2 changes: 1 addition & 1 deletion apps/manager/web/js/test/testRunner.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ global.document.dispatchEvent(event);

const Helper = require("../help/helper");

/**
/**************************
* @brief Test execution controller, assertions result tracker.
*/
class TestRunner {
Expand Down
Loading
Loading