сделал кеширование статистики и настроек терминала
This commit is contained in:
parent
fae7a2ffc8
commit
a833c0f68a
@ -98,6 +98,7 @@ public:
|
||||
ServerResources(const ServerResources&) = delete;
|
||||
|
||||
ServerResources(): sf(std::make_unique<http::resource::StaticFileFactory>()), api(std::make_unique<api_driver::ApiDriver>()) {
|
||||
api->startDaemon();
|
||||
auth.users.emplace_back(std::make_shared<http::auth::User>("admin"));
|
||||
|
||||
sf->registerFile(INDEX_HTML, mime_types::text_html, false);
|
||||
|
@ -1,19 +1,187 @@
|
||||
#include "terminal_api_driver.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "terminal_api/ControlProtoCInterface.h"
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <shared_mutex>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include "../dependencies/control_system/common/protocol_commands.h"
|
||||
|
||||
|
||||
/**
|
||||
* Этот демон нужен для того, чтобы получать статистику из API, а так же корректно сохранять настройки
|
||||
*/
|
||||
class api_driver::TerminalApiDaemon {
|
||||
private:
|
||||
TSID sid;
|
||||
boost::thread daemon;
|
||||
|
||||
void updateStatistics() {
|
||||
modulator_state modulator{};
|
||||
CP_GetModulatorState(sid, modulator);
|
||||
|
||||
demodulator_state demodulator{};
|
||||
CP_GetDemodulatorState(sid, demodulator);
|
||||
|
||||
device_state device{};
|
||||
CP_GetDeviceState(sid, device);
|
||||
|
||||
{
|
||||
std::lock_guard lock(this->stateMutex);
|
||||
this->modState = modulator;
|
||||
this->demodState = demodulator;
|
||||
this->devState = device;
|
||||
}
|
||||
}
|
||||
|
||||
void updateSettings() {
|
||||
modulator_settings mod{};
|
||||
CP_GetModulatorSettings(sid, mod);
|
||||
// uint32_t modulatorModcod;
|
||||
// CP_GetModulatorParams(sid, "modcod", &modulatorModcod);
|
||||
demodulator_settings demod{};
|
||||
CP_GetDemodulatorSettings(sid, demod);
|
||||
ACM_parameters_serv_ acm{};
|
||||
CP_GetAcmParams(sid, &acm);
|
||||
DPDI_parmeters dpdi{};
|
||||
CP_GetDpdiParams(sid, &dpdi);
|
||||
buc_lnb_settings bucLnb{};
|
||||
CP_GetBUC_LNB_settings(sid, bucLnb);
|
||||
|
||||
{
|
||||
std::lock_guard lock(this->settingsMutex);
|
||||
this->modSettings = mod;
|
||||
this->demodSettings = demod;
|
||||
this->acmSettings = acm;
|
||||
this->dpdiSettings = dpdi;
|
||||
this->bucLnbSettings = bucLnb;
|
||||
}
|
||||
}
|
||||
|
||||
void run() {
|
||||
// это демон, который в бесконечном цикле опрашивает API
|
||||
|
||||
struct IntervalUpdate_t {
|
||||
int64_t lastUpdate;
|
||||
int64_t periodMs;
|
||||
|
||||
bool checkNeedUpdate(int64_t now) {
|
||||
// тут нет смысла спать меньше чем на 20мс, поэтому можно разрешить чтение на некоторое время раньше
|
||||
return now - lastUpdate >= (periodMs - 20);
|
||||
}
|
||||
|
||||
int64_t getNextUpdate(int64_t now) {
|
||||
if (checkNeedUpdate(now)) {
|
||||
return 0;
|
||||
}
|
||||
auto next = now - lastUpdate;
|
||||
return next < 0 ? 0 : next;
|
||||
}
|
||||
};
|
||||
|
||||
IntervalUpdate_t statUpdate{.lastUpdate = 0, .periodMs = CACHE_STATISTICS_UPDATE_MS};
|
||||
IntervalUpdate_t settingsUpdate{.lastUpdate = 0, .periodMs = CACHE_SETTINGS_UPDATE_MS};
|
||||
|
||||
while (true) {
|
||||
auto now = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
if (statUpdate.checkNeedUpdate(now)) {
|
||||
statUpdate.lastUpdate = now;
|
||||
try {
|
||||
updateStatistics();
|
||||
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::updateStatistics(): success update!";
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::updateStatistics(): " << e.what();
|
||||
}
|
||||
now = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
}
|
||||
if (settingsUpdate.checkNeedUpdate(now)) {
|
||||
settingsUpdate.lastUpdate = now;
|
||||
try {
|
||||
updateSettings();
|
||||
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::updateSettings(): success update!";
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::updateSettings(): " << e.what();
|
||||
}
|
||||
now = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
}
|
||||
|
||||
auto sleepTime = statUpdate.getNextUpdate(now);
|
||||
sleepTime = std::min(sleepTime, settingsUpdate.getNextUpdate(now));
|
||||
if (sleepTime > 0) {
|
||||
boost::this_thread::sleep_for(boost::chrono::duration(boost::chrono::milliseconds(sleepTime)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_mutex stateMutex;
|
||||
modulator_state modState{};
|
||||
demodulator_state demodState{};
|
||||
device_state devState{};
|
||||
|
||||
std::shared_mutex settingsMutex;
|
||||
modulator_settings modSettings{};
|
||||
demodulator_settings demodSettings{};
|
||||
ACM_parameters_serv_ acmSettings{};
|
||||
DPDI_parmeters dpdiSettings{};
|
||||
buc_lnb_settings bucLnbSettings{};
|
||||
|
||||
public:
|
||||
explicit TerminalApiDaemon(TSID sid): sid(sid), daemon([this]() { this->run(); }) {}
|
||||
|
||||
/**
|
||||
* Получение статистики, копирует текущие значения в структуры, переданные по указателю. Если передан пустой указатель, копирования не произойдет.
|
||||
* @param mod статистика модулятра
|
||||
* @param demod статистика демодулятора
|
||||
* @param dev статистика устройства (температуры)
|
||||
*/
|
||||
void getStatistics(modulator_state* mod, demodulator_state* demod, device_state* dev) {
|
||||
if (mod != nullptr || demod != nullptr || dev != nullptr) {
|
||||
std::shared_lock lock(this->stateMutex);
|
||||
if (mod) { *mod = this->modState; }
|
||||
if (demod) { *demod = this->demodState; }
|
||||
if (dev) { *dev = this->devState; }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение настроек, копирует текущие значения в структуры, переданные по указателю. Если передан пустой указатель, копирования не произойдет.
|
||||
*/
|
||||
void getSettings(modulator_settings* mod, demodulator_settings* demod, ACM_parameters_serv_* acm, DPDI_parmeters* dpdi, buc_lnb_settings* bucLnb) {
|
||||
if (mod || demod || acm || dpdi || bucLnb) {
|
||||
std::shared_lock lock(this->settingsMutex);
|
||||
if (mod) { *mod = this->modSettings; }
|
||||
if (demod) { *demod = this->demodSettings; }
|
||||
if (acm) { *acm = this->acmSettings; }
|
||||
if (dpdi) { *dpdi = this->dpdiSettings; }
|
||||
if (bucLnb) { *bucLnb = this->bucLnbSettings; }
|
||||
}
|
||||
}
|
||||
|
||||
~TerminalApiDaemon() {
|
||||
try {
|
||||
daemon.interrupt();
|
||||
daemon.try_join_for(boost::chrono::seconds(2));
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "api_driver::~TerminalApiDaemon(): " << e.what();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
api_driver::ApiDriver::ApiDriver() {
|
||||
CP_Login("admin", "pass", &sid, &access);
|
||||
CP_GetDmaDebug(sid, "status_init", &deviceInitState);
|
||||
}
|
||||
|
||||
void api_driver::ApiDriver::startDaemon() {
|
||||
if (daemon == nullptr) {
|
||||
daemon = std::make_unique<TerminalApiDaemon>(this->sid);
|
||||
BOOST_LOG_TRIVIAL(info) << "api_driver::ApiDriver::startDaemon(): API daemon succes started!";
|
||||
}
|
||||
}
|
||||
|
||||
static const char* boolAsStr(bool value) {
|
||||
return value ? "true" : "false";
|
||||
}
|
||||
@ -28,12 +196,6 @@ static std::string buildEscapedString(const std::string& source) {
|
||||
return "\"" + str + "\"";
|
||||
}
|
||||
|
||||
static bool DriverCP_GetCinC(TSID sid) {
|
||||
modulator_settings s{};
|
||||
CP_GetModulatorSettings(sid, s);
|
||||
return s.is_cinc;
|
||||
}
|
||||
|
||||
void writeDouble(std::ostream& out, double value, int prec = 2) {
|
||||
if (std::isnan(value) || std::isinf(value)) {
|
||||
out << "\"nan\"";
|
||||
@ -55,19 +217,18 @@ std::tuple<uint8_t, uint8_t> translateCoordinates(double abs) {
|
||||
|
||||
|
||||
std::string api_driver::ApiDriver::loadTerminalState() const {
|
||||
if (daemon == nullptr) {
|
||||
return R"({"error": "api daemon not started!"})";
|
||||
}
|
||||
std::stringstream result;
|
||||
|
||||
result << "{\n\"initState\":" << buildEscapedString(this->deviceInitState);
|
||||
|
||||
modulator_state modulator{};
|
||||
CP_GetModulatorState(sid, modulator);
|
||||
|
||||
demodulator_state demodulator{};
|
||||
CP_GetDemodulatorState(sid, demodulator);
|
||||
|
||||
device_state device{};
|
||||
CP_GetDeviceState(sid, device);
|
||||
|
||||
const bool isCinC = DriverCP_GetCinC(sid);
|
||||
daemon->getStatistics(&modulator, &demodulator, &device);
|
||||
const bool isCinC = this->getIsCinC();
|
||||
|
||||
result << ",\"isCinC\":" << boolAsStr(isCinC);
|
||||
|
||||
@ -166,19 +327,23 @@ void api_driver::ApiDriver::resetPacketStatistics() const {
|
||||
}
|
||||
|
||||
std::string api_driver::ApiDriver::loadSettings() const {
|
||||
modulator_settings modSettings{};
|
||||
CP_GetModulatorSettings(sid, modSettings);
|
||||
uint32_t modulatorModcod;
|
||||
CP_GetModulatorParams(sid, "modcod", &modulatorModcod);
|
||||
if (daemon == nullptr) {
|
||||
return R"({"error": "api daemon not started!"})";
|
||||
}
|
||||
|
||||
modulator_settings modSettings{};
|
||||
demodulator_settings demodSettings{};
|
||||
CP_GetDemodulatorSettings(sid, demodSettings);
|
||||
ACM_parameters_serv_ acmSettings{};
|
||||
CP_GetAcmParams(sid, &acmSettings);
|
||||
DPDI_parmeters dpdiSettings{};
|
||||
CP_GetDpdiParams(sid, &dpdiSettings);
|
||||
buc_lnb_settings bucLnb{};
|
||||
CP_GetBUC_LNB_settings(sid, bucLnb);
|
||||
daemon->getSettings(&modSettings, &demodSettings, &acmSettings, &dpdiSettings, &bucLnb);
|
||||
|
||||
uint32_t modulatorModcod;
|
||||
{
|
||||
modulator_state ms{};
|
||||
daemon->getStatistics(&ms, nullptr, nullptr);
|
||||
modulatorModcod = ms.modcod;
|
||||
}
|
||||
|
||||
std::stringstream result;
|
||||
result << "{\n\"general.isCinC\":" << boolAsStr(modSettings.is_cinc);
|
||||
@ -244,3 +409,9 @@ std::string api_driver::ApiDriver::loadSettings() const {
|
||||
}
|
||||
|
||||
api_driver::ApiDriver::~ApiDriver() = default;
|
||||
|
||||
bool api_driver::ApiDriver::getIsCinC() const {
|
||||
modulator_settings s{};
|
||||
daemon->getSettings(&s, nullptr, nullptr, nullptr, nullptr);
|
||||
return s.is_cinc;
|
||||
}
|
||||
|
@ -1,11 +1,18 @@
|
||||
#ifndef TERMINAL_API_DRIVER_H
|
||||
#define TERMINAL_API_DRIVER_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <terminal_api/ControlProtoCInterface.h>
|
||||
|
||||
|
||||
namespace api_driver {
|
||||
|
||||
constexpr int CACHE_STATISTICS_UPDATE_MS = 500;
|
||||
constexpr int CACHE_SETTINGS_UPDATE_MS = 5000;
|
||||
|
||||
class TerminalApiDaemon;
|
||||
|
||||
/**
|
||||
* Это ApiDriver. Все ответы он будет возвращать в виде json.
|
||||
*/
|
||||
@ -13,6 +20,11 @@ namespace api_driver {
|
||||
public:
|
||||
explicit ApiDriver();
|
||||
|
||||
/**
|
||||
* Запуск демона
|
||||
*/
|
||||
void startDaemon();
|
||||
|
||||
/**
|
||||
* Запросить общее состояние терминала
|
||||
* @return {"txState":false,"rxState":false,"rx.sym_sync_lock":false,"rx.freq_search_lock":false,"rx.afc_lock":false,"rx.pkt_sync":false}
|
||||
@ -33,6 +45,9 @@ namespace api_driver {
|
||||
unsigned int access{0};
|
||||
|
||||
std::string deviceInitState;
|
||||
std::unique_ptr<TerminalApiDaemon> daemon;
|
||||
|
||||
bool getIsCinC() const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
<div :class="{ value_bad: initState !== 'Успешная инициализация системы' }">{{ initState }}</div>
|
||||
<div id="content">
|
||||
<div class="tabs-body-item tabs-item-flex-container" v-show="activeTab === 'monitoring'">
|
||||
<div>
|
||||
<div class="settings-set-container">
|
||||
<h2>Статистика приема</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
@ -59,7 +59,7 @@
|
||||
</table>
|
||||
<button @click="resetPacketsStatistics()"> Сброс статистики </button>
|
||||
</div>
|
||||
<div>
|
||||
<div class="settings-set-container">
|
||||
<h2>Статистика передачи</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
@ -73,7 +73,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div v-if="isCinC === true">
|
||||
<div class="settings-set-container" v-if="isCinC === true">
|
||||
<h2>Статистика режима CinC</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
@ -85,7 +85,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
<div class="settings-set-container">
|
||||
<h2>Состояние устройства</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
|
Loading…
x
Reference in New Issue
Block a user