partially migrate to IndexedTimer
migrate to PIP 3.21 fix server restartings
This commit is contained in:
+1
-1
@@ -11,7 +11,7 @@ if("${SHS_QT_VERSION}" STREQUAL "")
|
|||||||
set(SHS_QT_VERSION 5 CACHE STRING "Qt version")
|
set(SHS_QT_VERSION 5 CACHE STRING "Qt version")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(PIP 3.15 REQUIRED)
|
find_package(PIP 3.21 REQUIRED)
|
||||||
find_package(QAD 2.8.4 REQUIRED)
|
find_package(QAD 2.8.4 REQUIRED)
|
||||||
qad_find_qt(Qt${SHS_QT_VERSION} Core Gui Widgets)
|
qad_find_qt(Qt${SHS_QT_VERSION} Core Gui Widgets)
|
||||||
set(TARGET_SUFFIX_Qt${SHS_QT_VERSION} "")
|
set(TARGET_SUFFIX_Qt${SHS_QT_VERSION} "")
|
||||||
|
|||||||
@@ -3,13 +3,14 @@
|
|||||||
#include "SH_network_types.h"
|
#include "SH_network_types.h"
|
||||||
#include "SH_packages.h"
|
#include "SH_packages.h"
|
||||||
#include "ccm_SHS_shared.h"
|
#include "ccm_SHS_shared.h"
|
||||||
#include "piqt.h"
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
#include <QCryptographicHash>
|
#include <QCryptographicHash>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QMetaObject>
|
#include <QMetaObject>
|
||||||
#include <piethernet.h>
|
#include <piethernet.h>
|
||||||
|
#include <piliterals_time.h>
|
||||||
|
#include <piqt.h>
|
||||||
|
|
||||||
|
|
||||||
ServerClient::ServerClient(ServerCore * s, SHNetworkTypes::ChannelType c): PIThread(), server(s), channel_type(c) {
|
ServerClient::ServerClient(ServerCore * s, SHNetworkTypes::ChannelType c): PIThread(), server(s), channel_type(c) {
|
||||||
@@ -44,10 +45,13 @@ void ServerClient::destroy() {
|
|||||||
PIThread::stop();
|
PIThread::stop();
|
||||||
// piCout << "~ServerClient stop";
|
// piCout << "~ServerClient stop";
|
||||||
if (device) device->stop();
|
if (device) device->stop();
|
||||||
if (!PIThread::waitForFinish(10000)) PIThread::terminate();
|
if (!PIThread::waitForFinish(5_s)) PIThread::terminate();
|
||||||
if (device) {
|
if (device) {
|
||||||
device->stopAndWait(10000);
|
device->stopAndWait(5_s);
|
||||||
if (device->isThreadedRead()) piCout << "[ServerClient::destroy]" << device << "can`t stop ...";
|
if (device->isThreadedRead()) {
|
||||||
|
piCout << "[ServerClient::destroy]" << device << "can`t stop ...";
|
||||||
|
device->terminateThreadedRead();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// piCout << "~ServerClient stop done";
|
// piCout << "~ServerClient stop done";
|
||||||
piDeleteSafety(tcp);
|
piDeleteSafety(tcp);
|
||||||
@@ -208,6 +212,7 @@ void ServerClient::recGraphicsRequest(PIStringList gl) {
|
|||||||
|
|
||||||
|
|
||||||
void ServerClient::packetRec(PIByteArray data) {
|
void ServerClient::packetRec(PIByteArray data) {
|
||||||
|
if (closing) return;
|
||||||
// piCout << "packetRec" << data.toHex() << "...";
|
// piCout << "packetRec" << data.toHex() << "...";
|
||||||
if (diag) diag->received(data.size_s());
|
if (diag) diag->received(data.size_s());
|
||||||
// piCout << "packetRec" << data.toHex();
|
// piCout << "packetRec" << data.toHex();
|
||||||
|
|||||||
+314
-290
@@ -1,22 +1,33 @@
|
|||||||
#include "server_core.h"
|
#include "server_core.h"
|
||||||
#include "piqt.h"
|
|
||||||
#include "SH_packages.h"
|
|
||||||
#include "SH_network_types.h"
|
#include "SH_network_types.h"
|
||||||
|
#include "SH_packages.h"
|
||||||
#include "SH_plugins_manager.h"
|
#include "SH_plugins_manager.h"
|
||||||
#include <QDebug>
|
|
||||||
#include <QMetaEnum>
|
|
||||||
#include <QCryptographicHash>
|
|
||||||
#include <QResource>
|
|
||||||
#include <qad_locations.h>
|
|
||||||
#include <piethernet.h>
|
|
||||||
#include "ccm_SHS_shared.h"
|
#include "ccm_SHS_shared.h"
|
||||||
|
|
||||||
//const double keepAliveInterval_s = 2.;
|
#include <QCryptographicHash>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QMetaEnum>
|
||||||
|
#include <QResource>
|
||||||
|
#include <piethernet.h>
|
||||||
|
#include <piliterals_time.h>
|
||||||
|
#include <piqt.h>
|
||||||
|
#include <qad_locations.h>
|
||||||
|
|
||||||
|
// const double keepAliveInterval_s = 2.;
|
||||||
|
|
||||||
|
|
||||||
|
enum TimerRole {
|
||||||
|
trSaveState,
|
||||||
|
trAdmin,
|
||||||
|
trServerSync,
|
||||||
|
trClients
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
ServerCore::ServerCore(bool reservation): QObject(), SHMulticast(), eth_tcp(PIEthernet::TCP_Server) {
|
ServerCore::ServerCore(bool reservation): QObject(), SHMulticast(), eth_tcp(PIEthernet::TCP_Server) {
|
||||||
PACKAGES;
|
PACKAGES;
|
||||||
file_ui_state = QAD::userPath(QAD::ltCache, "ui_state" );
|
file_ui_state = QAD::userPath(QAD::ltCache, "ui_state");
|
||||||
file_ui_state_new = QAD::userPath(QAD::ltCache, "ui_state_new");
|
file_ui_state_new = QAD::userPath(QAD::ltCache, "ui_state_new");
|
||||||
with_reservation = reservation;
|
with_reservation = reservation;
|
||||||
auto il = PIEthernet::interfaces();
|
auto il = PIEthernet::interfaces();
|
||||||
@@ -27,17 +38,27 @@ ServerCore::ServerCore(bool reservation): QObject(), SHMulticast(), eth_tcp(PIEt
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
seed = generateID();//PINetworkAddress(my_ip, 0).ip();
|
seed = generateID(); // PINetworkAddress(my_ip, 0).ip();
|
||||||
addressesChanged();
|
addressesChanged();
|
||||||
piCoutObj << PICoutManipulators::Hex << seed << PINetworkAddress(seed, 0);
|
piCoutObj << PICoutManipulators::Hex << seed << PINetworkAddress(seed, 0);
|
||||||
connect(&engine, SIGNAL(variableHistoryAdded(QString,QPair<QDateTime,double>)), this, SLOT(variableHistoryAdded(QString,QPair<QDateTime,double>)), Qt::DirectConnection);
|
connect(&engine,
|
||||||
|
SIGNAL(variableHistoryAdded(QString, QPair<QDateTime, double>)),
|
||||||
|
this,
|
||||||
|
SLOT(variableHistoryAdded(QString, QPair<QDateTime, double>)),
|
||||||
|
Qt::DirectConnection);
|
||||||
connect(&engine, SIGNAL(debug(QString)), this, SLOT(scriptDebug(QString)), Qt::DirectConnection);
|
connect(&engine, SIGNAL(debug(QString)), this, SLOT(scriptDebug(QString)), Qt::DirectConnection);
|
||||||
CONNECTU(ð_tcp, newConnection, this, newTCPConnection);
|
CONNECTU(ð_tcp, newConnection, this, newTCPConnection);
|
||||||
CONNECTU(&cloud_server, newConnection, this, newCloudConnection);
|
CONNECTU(&cloud_server, newConnection, this, newCloudConnection);
|
||||||
|
bindIndexedTimer(trSaveState, [this] { saveUIState(); });
|
||||||
|
bindIndexedTimer(trAdmin, [this] { sendAdminData(); });
|
||||||
|
bindIndexedTimer(trServerSync, [this] { syncServers(); });
|
||||||
|
bindIndexedTimer(trClients, [this] { procClients(); });
|
||||||
|
delete_clients_thread.start([this] { deleteOldClients(); }, 2_Hz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ServerCore::~ServerCore() {
|
ServerCore::~ServerCore() {
|
||||||
|
piCoutObj << "~ServerCore";
|
||||||
cloud_server.close();
|
cloud_server.close();
|
||||||
cloud_server.stop();
|
cloud_server.stop();
|
||||||
engine.remove();
|
engine.remove();
|
||||||
@@ -45,25 +66,29 @@ ServerCore::~ServerCore() {
|
|||||||
PIByteArray sba = SHNetworkTypes::makeHeader(SHNetworkTypes::ServerRemove);
|
PIByteArray sba = SHNetworkTypes::makeHeader(SHNetworkTypes::ServerRemove);
|
||||||
sba << seed;
|
sba << seed;
|
||||||
piCoutObj << "send ServerRemove seed =" << seed;
|
piCoutObj << "send ServerRemove seed =" << seed;
|
||||||
send(sba);
|
|
||||||
killTimer(timer_save_state);
|
|
||||||
killTimer(timer_admin);
|
|
||||||
killTimer(timer_sync);
|
|
||||||
killTimer(timer);
|
|
||||||
stopRead();
|
stopRead();
|
||||||
PIVector<ServerClient * > rl = remotes.values();
|
send(sba);
|
||||||
|
stopIndexedTimer(trSaveState);
|
||||||
|
stopIndexedTimer(trAdmin);
|
||||||
|
stopIndexedTimer(trServerSync);
|
||||||
|
stopIndexedTimer(trClients);
|
||||||
|
delete_clients_thread.stopAndWait();
|
||||||
|
deleteOldClients();
|
||||||
|
PIVector<ServerClient *> rl = remotes.values();
|
||||||
for (ServerClient * r: rl)
|
for (ServerClient * r: rl)
|
||||||
if (r) {
|
if (r) {
|
||||||
|
piCoutObj << "delete" << (uintptr_t)r << "...";
|
||||||
r->destroy();
|
r->destroy();
|
||||||
|
delete r->device;
|
||||||
delete r;
|
delete r;
|
||||||
|
piCoutObj << "delete" << (uintptr_t)r << "done";
|
||||||
}
|
}
|
||||||
remotes.clear();
|
remotes.clear();
|
||||||
eth_tcp.stop();
|
eth_tcp.stop();
|
||||||
for (auto * c: eth_tcp.clients())
|
for (auto * c: eth_tcp.clients())
|
||||||
c->stop();
|
c->stop();
|
||||||
piDeleteSafety(form);
|
piDeleteSafety(form);
|
||||||
if (bqr_content.data())
|
if (bqr_content.data()) QResource::unregisterResource((uchar *)bqr_content.data());
|
||||||
QResource::unregisterResource((uchar*)bqr_content.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -78,8 +103,8 @@ void ServerCore::startEth() {
|
|||||||
cloud_server.startThreadedRead();
|
cloud_server.startThreadedRead();
|
||||||
log(QString("Connect to cloud %1@%2").arg(sa.server, PI2QString(cloud_server.serverName())));
|
log(QString("Connect to cloud %1@%2").arg(sa.server, PI2QString(cloud_server.serverName())));
|
||||||
}
|
}
|
||||||
timer_sync = startTimer(100);
|
startIndexedTimer(trServerSync, 10_Hz);
|
||||||
timer_admin = startTimer(1000);
|
startIndexedTimer(trAdmin, 1_Hz);
|
||||||
SHMulticast::startRead();
|
SHMulticast::startRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,8 +127,8 @@ void ServerCore::loadRCC(const QString & p) {
|
|||||||
bqr_content = Q2PIByteArray(f.readAll());
|
bqr_content = Q2PIByteArray(f.readAll());
|
||||||
rcc_hash = bqr_content.hash();
|
rcc_hash = bqr_content.hash();
|
||||||
f.close();
|
f.close();
|
||||||
if(bqr_content.isEmpty()) return;
|
if (bqr_content.isEmpty()) return;
|
||||||
if (!QResource::registerResource((uchar*)bqr_content.data())) {
|
if (!QResource::registerResource((uchar *)bqr_content.data())) {
|
||||||
log("Can`t open resource \"" + QFileInfo(f).absoluteFilePath() + "\"!", SHServer::LogWarning);
|
log("Can`t open resource \"" + QFileInfo(f).absoluteFilePath() + "\"!", SHServer::LogWarning);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -150,11 +175,11 @@ void ServerCore::loadQS(const QString & p) {
|
|||||||
}
|
}
|
||||||
log("Loaded script \"" + QFileInfo(f).absoluteFilePath() + "\"", SHServer::LogSuccess);
|
log("Loaded script \"" + QFileInfo(f).absoluteFilePath() + "\"", SHServer::LogSuccess);
|
||||||
script_dir = QFileInfo(f).absoluteDir();
|
script_dir = QFileInfo(f).absoluteDir();
|
||||||
//script = QString::fromUtf8(f.readAll());
|
// script = QString::fromUtf8(f.readAll());
|
||||||
file_script = f.fileName();
|
file_script = f.fileName();
|
||||||
QObject::connect(&engine, SIGNAL(error(int,QString,QString,QString)), this, SLOT(scriptError(int,QString,QString,QString)));
|
QObject::connect(&engine, SIGNAL(error(int, QString, QString, QString)), this, SLOT(scriptError(int, QString, QString, QString)));
|
||||||
QObject::connect(&engine, SIGNAL(log(QString,int)), this, SLOT(scriptLog(QString,int)));
|
QObject::connect(&engine, SIGNAL(log(QString, int)), this, SLOT(scriptLog(QString, int)));
|
||||||
QObject::connect(&engine, SIGNAL(message(QString,int)), this, SLOT(scriptMessage(QString,int)));
|
QObject::connect(&engine, SIGNAL(message(QString, int)), this, SLOT(scriptMessage(QString, int)));
|
||||||
QObject::connect(&engine, SIGNAL(logIO(QString)), this, SLOT(IOLog(QString)));
|
QObject::connect(&engine, SIGNAL(logIO(QString)), this, SLOT(IOLog(QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +196,7 @@ void ServerCore::loadDAT(const QString & p) {
|
|||||||
}
|
}
|
||||||
log("Loaded database \"" + QFileInfo(f).absoluteFilePath() + "\"", SHServer::LogSuccess);
|
log("Loaded database \"" + QFileInfo(f).absoluteFilePath() + "\"", SHServer::LogSuccess);
|
||||||
RUNTIME->setServerData(loadFromFile<SHS::ServerData>(p));
|
RUNTIME->setServerData(loadFromFile<SHS::ServerData>(p));
|
||||||
server_key_ = Q2PIString(RUNTIME->server_data.project.propertyValueByName("key" ).toString());
|
server_key_ = Q2PIString(RUNTIME->server_data.project.propertyValueByName("key").toString());
|
||||||
server_name_ = Q2PIString(RUNTIME->server_data.project.propertyValueByName("name").toString());
|
server_name_ = Q2PIString(RUNTIME->server_data.project.propertyValueByName("name").toString());
|
||||||
piCout << "key" << server_key_;
|
piCout << "key" << server_key_;
|
||||||
loadedDAT();
|
loadedDAT();
|
||||||
@@ -186,7 +211,7 @@ void ServerCore::loadCM(const QString & p) {
|
|||||||
}
|
}
|
||||||
log("Loaded connection \"" + QFileInfo(f).absoluteFilePath() + "\"", SHServer::LogSuccess);
|
log("Loaded connection \"" + QFileInfo(f).absoluteFilePath() + "\"", SHServer::LogSuccess);
|
||||||
RUNTIME->connection.loadFromCMFile(p);
|
RUNTIME->connection.loadFromCMFile(p);
|
||||||
connect(&RUNTIME->connection, SIGNAL(qDataReceivedEvent(QString,QByteArray)), this, SLOT(connDataReceivedEvent(QString,QByteArray)));
|
connect(&RUNTIME->connection, SIGNAL(qDataReceivedEvent(QString, QByteArray)), this, SLOT(connDataReceivedEvent(QString, QByteArray)));
|
||||||
loadedCM();
|
loadedCM();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,8 +250,7 @@ void ServerCore::loadBAF(const PIString & p) {
|
|||||||
if (!cmp.isEmpty()) loadCM(cmp);
|
if (!cmp.isEmpty()) loadCM(cmp);
|
||||||
if (!dbp.isEmpty()) loadDAT(dbp);
|
if (!dbp.isEmpty()) loadDAT(dbp);
|
||||||
RUNTIME->server_data.setRootPath(QDir::tempPath());
|
RUNTIME->server_data.setRootPath(QDir::tempPath());
|
||||||
if (!varp.isEmpty())
|
if (!varp.isEmpty()) loadVAR(varp);
|
||||||
loadVAR(varp);
|
|
||||||
if (!sdpp.isEmpty())
|
if (!sdpp.isEmpty())
|
||||||
loadProject(sdpp);
|
loadProject(sdpp);
|
||||||
else if (qspl.size() == 1) {
|
else if (qspl.size() == 1) {
|
||||||
@@ -259,221 +283,9 @@ void ServerCore::loadProject(const QString & p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ServerCore::timerEvent(QTimerEvent * e) {
|
|
||||||
if (e->timerId() == timer_save_state) {
|
|
||||||
saveUIState();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (e->timerId() == timer_sync) {
|
|
||||||
if (with_reservation) {
|
|
||||||
smutex.lock();
|
|
||||||
if (server_state > ServerCore::ssSync) {
|
|
||||||
for (int i = 0; i < servers.size_s(); ++i) {
|
|
||||||
servers[i].missed++;
|
|
||||||
if (servers[i].missed > 10) {
|
|
||||||
piCoutObj << "remove by timeout" << servers[i].seed;
|
|
||||||
if (servers[i].seed == seed_main)
|
|
||||||
selectNewMain();
|
|
||||||
servers.remove(i);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
smutex.unlock();
|
|
||||||
if (sync_skip > 0) {
|
|
||||||
sync_skip--;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (server_state) {
|
|
||||||
case ServerCore::ssStart: {
|
|
||||||
PIByteArray sba = SHNetworkTypes::makeHeader(SHNetworkTypes::ServerNew);
|
|
||||||
sba << seed;
|
|
||||||
piCoutObj << "send ServerNew seed =" << seed << ", ip =" << my_ip;
|
|
||||||
send(sba);
|
|
||||||
selectNewMain();
|
|
||||||
} break;
|
|
||||||
case ServerCore::ssSync:
|
|
||||||
if (seed_main == 0) {
|
|
||||||
int mseed = seed;
|
|
||||||
int mi = -1;
|
|
||||||
smutex.lock();
|
|
||||||
for (int i = 0; i < servers.size_s(); ++i) {
|
|
||||||
if (mseed > servers[i].seed) {
|
|
||||||
mseed = servers[i].seed;
|
|
||||||
mi = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
smutex.unlock();
|
|
||||||
seed_main = mseed;
|
|
||||||
main_ip = PINetworkAddress(mseed, 0).ipString();
|
|
||||||
if (mi < 0)
|
|
||||||
startAsMain();
|
|
||||||
else
|
|
||||||
startAsReserve();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ServerCore::ssWorkReserve:
|
|
||||||
main_missed++;
|
|
||||||
if (main_missed > 10) {
|
|
||||||
main_missed = 0;
|
|
||||||
selectNewMain();
|
|
||||||
}
|
|
||||||
case ServerCore::ssWorkMain:
|
|
||||||
{
|
|
||||||
PIByteArray sba = SHNetworkTypes::makeHeader(SHNetworkTypes::ServerPing);
|
|
||||||
sba << seed;
|
|
||||||
//piCoutObj << "send ServerPing seed =" << seed;
|
|
||||||
send(sba);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else startAsMain();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (e->timerId() == timer_admin) {
|
|
||||||
|
|
||||||
lmutex.lock();
|
|
||||||
PacketServerLog pck_log, pck_log_hist;
|
|
||||||
pck_log.entries = std::move(admin_log);
|
|
||||||
admin_log.clear();
|
|
||||||
auto mq = std::move(message_queue);
|
|
||||||
message_queue.clear();
|
|
||||||
lmutex.unlock();
|
|
||||||
|
|
||||||
rmutex.lock();
|
|
||||||
state_dynamic.clients.clear();
|
|
||||||
PIVector<ServerClient * > rl = remotes.values();
|
|
||||||
for (ServerClient * r: rl) {
|
|
||||||
if (!r) continue;
|
|
||||||
r->updateInfo();
|
|
||||||
state_dynamic.clients << r->info;
|
|
||||||
}
|
|
||||||
state_dynamic.devices.clear();
|
|
||||||
PIVector<PIIODevice * > devs = RUNTIME->connection.boundedDevices();
|
|
||||||
for (PIIODevice * d: devs) {
|
|
||||||
if (!d) continue;
|
|
||||||
ServerDeviceInfo di;
|
|
||||||
di.classname = QLatin1String(d->className());
|
|
||||||
di.path = PI2QString(d->path());
|
|
||||||
di.mode = d->mode();
|
|
||||||
PIDiagnostics * diag = RUNTIME->connection.diagnostic(d);
|
|
||||||
if (diag) {
|
|
||||||
di.sended_bytes = diag->state().sended_bytes;
|
|
||||||
di.received_bytes = diag->state().received_bytes;
|
|
||||||
di.send_speed = PI2QString(diag->sendSpeed());
|
|
||||||
di.receive_speed = PI2QString(diag->receiveSpeed());
|
|
||||||
}
|
|
||||||
state_dynamic.devices << di;
|
|
||||||
}
|
|
||||||
for (auto & v: state_dynamic.variables) {
|
|
||||||
auto val = engine.getVariableValue(v.name);
|
|
||||||
v.changed = val.first;
|
|
||||||
v.value = val.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIByteArray msg_state;
|
|
||||||
msg_state = SHNetworkTypes::makeHeader(SHNetworkTypes::AdminDynamicState);
|
|
||||||
msg_state << state_dynamic;
|
|
||||||
|
|
||||||
for (ServerClient * r: rl) {
|
|
||||||
if (!r) continue;
|
|
||||||
|
|
||||||
if (r->info.role == SHServer::RoleMessages) {
|
|
||||||
for (const auto & m: mq) {
|
|
||||||
PIByteArray ba = SHNetworkTypes::makeHeader(SHNetworkTypes::Message);
|
|
||||||
ba << m;
|
|
||||||
r->queueSend(ba);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->info.role == SHServer::RoleAdmin) {
|
|
||||||
if (!r->log_sended) {
|
|
||||||
r->log_sended = true;
|
|
||||||
pck_log_hist.entries = admin_log_history;
|
|
||||||
PIByteArray msg = SHNetworkTypes::makeHeader(SHNetworkTypes::AdminLog);
|
|
||||||
msg << pck_log_hist;
|
|
||||||
r->queueSend(msg);
|
|
||||||
}
|
|
||||||
if (!msg_state.isEmpty())
|
|
||||||
r->queueSend(msg_state);
|
|
||||||
if (!pck_log.entries.isEmpty() || !r->admin_io_log.isEmpty()) {
|
|
||||||
PacketServerLog pckt;
|
|
||||||
pckt.entries << pck_log.entries << r->admin_io_log;
|
|
||||||
pckt.entries.sort([](const LogEntry & t0, const LogEntry & t1){return t0.time < t1.time;});
|
|
||||||
r->admin_io_log.clear();
|
|
||||||
PIByteArray msg = SHNetworkTypes::makeHeader(SHNetworkTypes::AdminLog);
|
|
||||||
msg << pckt;
|
|
||||||
r->queueSend(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rmutex.unlock();
|
|
||||||
|
|
||||||
for (const auto & e: pck_log.entries) {
|
|
||||||
admin_log_cur_size += e.text.size();
|
|
||||||
admin_log_history << e;
|
|
||||||
while (admin_log_cur_size > admin_log_max_size)
|
|
||||||
admin_log_cur_size -= admin_log_history.take_front().text.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
rmutex.lock();
|
|
||||||
|
|
||||||
sync.buildDiffForRoles();
|
|
||||||
|
|
||||||
PIVector<ServerClient * > rl = remotes.values(), to_remove;
|
|
||||||
for (ServerClient * r: rl) {
|
|
||||||
bool disconn = !r->isConnected();
|
|
||||||
if (r) {if (r->tcp->wasError()) disconn = true;}
|
|
||||||
if (disconn) {
|
|
||||||
log("Client " + PI2QString(r->device->path()) + " disconnected", SHServer::LogInfo);
|
|
||||||
//piCout << "disconn ...";
|
|
||||||
r->close();
|
|
||||||
//piCout << "disconn close";
|
|
||||||
if (df_client == r) {
|
|
||||||
df_client = 0;
|
|
||||||
df_device.clear();
|
|
||||||
engine.connection()->setInactive(false);
|
|
||||||
}
|
|
||||||
to_remove << r;
|
|
||||||
//piCout << "disconn done";
|
|
||||||
}
|
|
||||||
r->maybeCallQueuedEvents();
|
|
||||||
r->updateInfo();
|
|
||||||
if (!r->tcp || !r->active || (r->info.role != SHServer::RoleGui)) continue;
|
|
||||||
PIByteArray diff;
|
|
||||||
if (r->role_changed) {
|
|
||||||
diff = Q2PIByteArray(sync.buildTransitionDiff(r->user_role, r->new_user_role));
|
|
||||||
//qDebug() << "send transitional diff" << r->user_role << "->" << r->new_user_role << diff.size();
|
|
||||||
r->newRoleDone();
|
|
||||||
if (!diff.isEmpty()) {
|
|
||||||
diff.insert(0, SHNetworkTypes::makeHeader(SHNetworkTypes::GuiSyncDiff));
|
|
||||||
r->queueSend(diff);
|
|
||||||
}
|
|
||||||
diff.clear();
|
|
||||||
}
|
|
||||||
diff = sync.diffForRole(r->user_role);
|
|
||||||
if (!diff.isEmpty()) {
|
|
||||||
diff.insert(0, SHNetworkTypes::makeHeader(SHNetworkTypes::GuiSyncDiff));
|
|
||||||
r->queueSend(diff);
|
|
||||||
}
|
|
||||||
//piCout << "diff role" << r->user_role << diff.size();
|
|
||||||
}
|
|
||||||
for (ServerClient * r: to_remove) {
|
|
||||||
remotes.remove(r->device);
|
|
||||||
r->destroy();
|
|
||||||
delete r->device;
|
|
||||||
delete r;
|
|
||||||
}
|
|
||||||
rmutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool ServerCore::hasServer(const PIString & ip) const {
|
bool ServerCore::hasServer(const PIString & ip) const {
|
||||||
for (const auto & s: servers)
|
for (const auto & s: servers)
|
||||||
if (s.ip == ip)
|
if (s.ip == ip) return true;
|
||||||
return true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,10 +316,8 @@ void ServerCore::startAsMain() {
|
|||||||
if (server_state == ServerCore::ssWorkMain) return;
|
if (server_state == ServerCore::ssWorkMain) return;
|
||||||
piCoutObj << "startAsMain";
|
piCoutObj << "startAsMain";
|
||||||
server_state = ServerCore::ssWorkMain;
|
server_state = ServerCore::ssWorkMain;
|
||||||
if (timer > 0) killTimer(timer);
|
startIndexedTimer(trSaveState, 10_s);
|
||||||
timer = startTimer(100);
|
startIndexedTimer(trClients, 10_Hz);
|
||||||
if (timer_save_state > 0) killTimer(timer_save_state);
|
|
||||||
timer_save_state = startTimer(10000);
|
|
||||||
sync_skip = 0;
|
sync_skip = 0;
|
||||||
start();
|
start();
|
||||||
engine.setDir(script_dir);
|
engine.setDir(script_dir);
|
||||||
@@ -531,8 +341,7 @@ void ServerCore::startAsReserve() {
|
|||||||
if (server_state == ServerCore::ssWorkReserve) return;
|
if (server_state == ServerCore::ssWorkReserve) return;
|
||||||
piCoutObj << "startAsReserve";
|
piCoutObj << "startAsReserve";
|
||||||
server_state = ServerCore::ssWorkReserve;
|
server_state = ServerCore::ssWorkReserve;
|
||||||
if (timer > 0) killTimer(timer);
|
stopIndexedTimer(trClients);
|
||||||
timer = 0;
|
|
||||||
sync_skip = 0;
|
sync_skip = 0;
|
||||||
start();
|
start();
|
||||||
startedAsReserve();
|
startedAsReserve();
|
||||||
@@ -566,8 +375,7 @@ void ServerCore::restoreUIState() {
|
|||||||
QFile f(file_ui_state);
|
QFile f(file_ui_state);
|
||||||
if (!f.open(QIODevice::ReadOnly)) {
|
if (!f.open(QIODevice::ReadOnly)) {
|
||||||
f.setFileName(file_ui_state_new);
|
f.setFileName(file_ui_state_new);
|
||||||
if (!f.open(QIODevice::ReadOnly))
|
if (!f.open(QIODevice::ReadOnly)) return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (f.size() < 8) return;
|
if (f.size() < 8) return;
|
||||||
QDataStream s(&f);
|
QDataStream s(&f);
|
||||||
@@ -644,9 +452,230 @@ void ServerCore::gatherFixedState() {
|
|||||||
PIString server = Q2PIString(RUNTIME->server_data.project.propertyValueByName("cloud_address").toString()) + "@";
|
PIString server = Q2PIString(RUNTIME->server_data.project.propertyValueByName("cloud_address").toString()) + "@";
|
||||||
server += getThisCloudName();
|
server += getThisCloudName();
|
||||||
state_fixed.cloud_address = PI2QString(server);
|
state_fixed.cloud_address = PI2QString(server);
|
||||||
state_fixed.cloud_href = QString("https://") + SHServerURL + "/pult/?address=" + QString(QUrl::toPercentEncoding(PI2QString(server + getThisCloudName())));
|
state_fixed.cloud_href = QString("https://") + SHServerURL +
|
||||||
|
"/pult/?address=" + QString(QUrl::toPercentEncoding(PI2QString(server + getThisCloudName())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ServerCore::sendAdminData() {
|
||||||
|
lmutex.lock();
|
||||||
|
PacketServerLog pck_log, pck_log_hist;
|
||||||
|
pck_log.entries = std::move(admin_log);
|
||||||
|
admin_log.clear();
|
||||||
|
auto mq = std::move(message_queue);
|
||||||
|
message_queue.clear();
|
||||||
|
lmutex.unlock();
|
||||||
|
|
||||||
|
rmutex.lock();
|
||||||
|
state_dynamic.clients.clear();
|
||||||
|
PIVector<ServerClient *> rl = remotes.values();
|
||||||
|
for (ServerClient * r: rl) {
|
||||||
|
if (!r) continue;
|
||||||
|
r->updateInfo();
|
||||||
|
state_dynamic.clients << r->info;
|
||||||
|
}
|
||||||
|
state_dynamic.devices.clear();
|
||||||
|
PIVector<PIIODevice *> devs = RUNTIME->connection.boundedDevices();
|
||||||
|
for (PIIODevice * d: devs) {
|
||||||
|
if (!d) continue;
|
||||||
|
ServerDeviceInfo di;
|
||||||
|
di.classname = QLatin1String(d->className());
|
||||||
|
di.path = PI2QString(d->path());
|
||||||
|
di.mode = d->mode();
|
||||||
|
PIDiagnostics * diag = RUNTIME->connection.diagnostic(d);
|
||||||
|
if (diag) {
|
||||||
|
di.sended_bytes = diag->state().sended_bytes;
|
||||||
|
di.received_bytes = diag->state().received_bytes;
|
||||||
|
di.send_speed = PI2QString(diag->sendSpeed());
|
||||||
|
di.receive_speed = PI2QString(diag->receiveSpeed());
|
||||||
|
}
|
||||||
|
state_dynamic.devices << di;
|
||||||
|
}
|
||||||
|
for (auto & v: state_dynamic.variables) {
|
||||||
|
auto val = engine.getVariableValue(v.name);
|
||||||
|
v.changed = val.first;
|
||||||
|
v.value = val.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PIByteArray msg_state;
|
||||||
|
msg_state = SHNetworkTypes::makeHeader(SHNetworkTypes::AdminDynamicState);
|
||||||
|
msg_state << state_dynamic;
|
||||||
|
|
||||||
|
for (ServerClient * r: rl) {
|
||||||
|
if (!r) continue;
|
||||||
|
|
||||||
|
if (r->info.role == SHServer::RoleMessages) {
|
||||||
|
for (const auto & m: mq) {
|
||||||
|
PIByteArray ba = SHNetworkTypes::makeHeader(SHNetworkTypes::Message);
|
||||||
|
ba << m;
|
||||||
|
r->queueSend(ba);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->info.role == SHServer::RoleAdmin) {
|
||||||
|
if (!r->log_sended) {
|
||||||
|
r->log_sended = true;
|
||||||
|
pck_log_hist.entries = admin_log_history;
|
||||||
|
PIByteArray msg = SHNetworkTypes::makeHeader(SHNetworkTypes::AdminLog);
|
||||||
|
msg << pck_log_hist;
|
||||||
|
r->queueSend(msg);
|
||||||
|
}
|
||||||
|
if (!msg_state.isEmpty()) r->queueSend(msg_state);
|
||||||
|
if (!pck_log.entries.isEmpty() || !r->admin_io_log.isEmpty()) {
|
||||||
|
PacketServerLog pckt;
|
||||||
|
pckt.entries << pck_log.entries << r->admin_io_log;
|
||||||
|
pckt.entries.sort([](const LogEntry & t0, const LogEntry & t1) { return t0.time < t1.time; });
|
||||||
|
r->admin_io_log.clear();
|
||||||
|
PIByteArray msg = SHNetworkTypes::makeHeader(SHNetworkTypes::AdminLog);
|
||||||
|
msg << pckt;
|
||||||
|
r->queueSend(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rmutex.unlock();
|
||||||
|
|
||||||
|
for (const auto & e: pck_log.entries) {
|
||||||
|
admin_log_cur_size += e.text.size();
|
||||||
|
admin_log_history << e;
|
||||||
|
while (admin_log_cur_size > admin_log_max_size)
|
||||||
|
admin_log_cur_size -= admin_log_history.take_front().text.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ServerCore::syncServers() {
|
||||||
|
if (with_reservation) {
|
||||||
|
smutex.lock();
|
||||||
|
if (server_state > ServerCore::ssSync) {
|
||||||
|
for (int i = 0; i < servers.size_s(); ++i) {
|
||||||
|
servers[i].missed++;
|
||||||
|
if (servers[i].missed > 10) {
|
||||||
|
piCoutObj << "remove by timeout" << servers[i].seed;
|
||||||
|
if (servers[i].seed == seed_main) selectNewMain();
|
||||||
|
servers.remove(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
smutex.unlock();
|
||||||
|
if (sync_skip > 0) {
|
||||||
|
sync_skip--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (server_state) {
|
||||||
|
case ServerCore::ssStart: {
|
||||||
|
PIByteArray sba = SHNetworkTypes::makeHeader(SHNetworkTypes::ServerNew);
|
||||||
|
sba << seed;
|
||||||
|
piCoutObj << "send ServerNew seed =" << seed << ", ip =" << my_ip;
|
||||||
|
send(sba);
|
||||||
|
selectNewMain();
|
||||||
|
} break;
|
||||||
|
case ServerCore::ssSync:
|
||||||
|
if (seed_main == 0) {
|
||||||
|
int mseed = seed;
|
||||||
|
int mi = -1;
|
||||||
|
smutex.lock();
|
||||||
|
for (int i = 0; i < servers.size_s(); ++i) {
|
||||||
|
if (mseed > servers[i].seed) {
|
||||||
|
mseed = servers[i].seed;
|
||||||
|
mi = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
smutex.unlock();
|
||||||
|
seed_main = mseed;
|
||||||
|
main_ip = PINetworkAddress(mseed, 0).ipString();
|
||||||
|
if (mi < 0)
|
||||||
|
startAsMain();
|
||||||
|
else
|
||||||
|
startAsReserve();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ServerCore::ssWorkReserve:
|
||||||
|
main_missed++;
|
||||||
|
if (main_missed > 10) {
|
||||||
|
main_missed = 0;
|
||||||
|
selectNewMain();
|
||||||
|
}
|
||||||
|
case ServerCore::ssWorkMain: {
|
||||||
|
PIByteArray sba = SHNetworkTypes::makeHeader(SHNetworkTypes::ServerPing);
|
||||||
|
sba << seed;
|
||||||
|
// piCoutObj << "send ServerPing seed =" << seed;
|
||||||
|
send(sba);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
startAsMain();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ServerCore::procClients() {
|
||||||
|
PIMutexLocker ml(rmutex);
|
||||||
|
|
||||||
|
sync.buildDiffForRoles();
|
||||||
|
|
||||||
|
PIVector<ServerClient *> rl = remotes.values(), to_remove;
|
||||||
|
for (ServerClient * r: rl) {
|
||||||
|
bool disconn = !r->isConnected();
|
||||||
|
if (r) {
|
||||||
|
if (r->tcp->wasError()) disconn = true;
|
||||||
|
}
|
||||||
|
if (disconn) {
|
||||||
|
log("Client " + PI2QString(r->device->path()) + " disconnected", SHServer::LogInfo);
|
||||||
|
// piCout << "disconn ...";
|
||||||
|
r->close();
|
||||||
|
// piCout << "disconn close";
|
||||||
|
if (df_client == r) {
|
||||||
|
df_client = 0;
|
||||||
|
df_device.clear();
|
||||||
|
engine.connection()->setInactive(false);
|
||||||
|
}
|
||||||
|
to_remove << r;
|
||||||
|
// piCout << "disconn done";
|
||||||
|
}
|
||||||
|
r->maybeCallQueuedEvents();
|
||||||
|
r->updateInfo();
|
||||||
|
if (!r->tcp || !r->active || (r->info.role != SHServer::RoleGui)) continue;
|
||||||
|
PIByteArray diff;
|
||||||
|
if (r->role_changed) {
|
||||||
|
diff = Q2PIByteArray(sync.buildTransitionDiff(r->user_role, r->new_user_role));
|
||||||
|
// qDebug() << "send transitional diff" << r->user_role << "->" << r->new_user_role << diff.size();
|
||||||
|
r->newRoleDone();
|
||||||
|
if (!diff.isEmpty()) {
|
||||||
|
diff.insert(0, SHNetworkTypes::makeHeader(SHNetworkTypes::GuiSyncDiff));
|
||||||
|
r->queueSend(diff);
|
||||||
|
}
|
||||||
|
diff.clear();
|
||||||
|
}
|
||||||
|
diff = sync.diffForRole(r->user_role);
|
||||||
|
if (!diff.isEmpty()) {
|
||||||
|
diff.insert(0, SHNetworkTypes::makeHeader(SHNetworkTypes::GuiSyncDiff));
|
||||||
|
r->queueSend(diff);
|
||||||
|
}
|
||||||
|
// piCout << "diff role" << r->user_role << diff.size();
|
||||||
|
}
|
||||||
|
for (ServerClient * r: to_remove) {
|
||||||
|
remotes.remove(r->device);
|
||||||
|
r->close();
|
||||||
|
rcq_mutex.lock();
|
||||||
|
delete_clients_queue.enqueue(r);
|
||||||
|
rcq_mutex.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ServerCore::deleteOldClients() {
|
||||||
|
rcq_mutex.lock();
|
||||||
|
auto del_queue = delete_clients_queue;
|
||||||
|
delete_clients_queue.clear();
|
||||||
|
rcq_mutex.unlock();
|
||||||
|
for (auto * r: del_queue) {
|
||||||
|
piCoutObj << "delete" << (uintptr_t)r << "...";
|
||||||
|
r->destroy();
|
||||||
|
delete r->device;
|
||||||
|
delete r;
|
||||||
|
piCoutObj << "delete" << (uintptr_t)r << "done";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -668,14 +697,14 @@ void ServerCore::connDataReceivedEvent(QString from, QByteArray data) {
|
|||||||
|
|
||||||
|
|
||||||
void ServerCore::variableHistoryAdded(QString vname, QPair<QDateTime, double> value) {
|
void ServerCore::variableHistoryAdded(QString vname, QPair<QDateTime, double> value) {
|
||||||
//qDebug() << "history add" << vname;
|
// qDebug() << "history add" << vname;
|
||||||
SHS::PacketGraphicData gd(vname);
|
SHS::PacketGraphicData gd(vname);
|
||||||
ullong time = value.first.toMSecsSinceEpoch();
|
ullong time = value.first.toMSecsSinceEpoch();
|
||||||
gd.data << PIPair<ullong, double>(time, value.second);
|
gd.data << PIPair<ullong, double>(time, value.second);
|
||||||
PIByteArray ba = SHNetworkTypes::makeHeader(SHNetworkTypes::GraphicData);
|
PIByteArray ba = SHNetworkTypes::makeHeader(SHNetworkTypes::GraphicData);
|
||||||
ba << gd;
|
ba << gd;
|
||||||
PIMutexLocker _ml(rmutex);
|
PIMutexLocker _ml(rmutex);
|
||||||
PIVector<ServerClient * > rl = remotes.values();
|
PIVector<ServerClient *> rl = remotes.values();
|
||||||
for (auto * r: rl)
|
for (auto * r: rl)
|
||||||
if (r->tcp && r->active && r->info.role == SHServer::RoleGraphics) {
|
if (r->tcp && r->active && r->info.role == SHServer::RoleGraphics) {
|
||||||
if (r->graphics.contains(vname)) {
|
if (r->graphics.contains(vname)) {
|
||||||
@@ -687,14 +716,14 @@ void ServerCore::variableHistoryAdded(QString vname, QPair<QDateTime, double> va
|
|||||||
|
|
||||||
|
|
||||||
void ServerCore::receivedSH(PIByteArray data, uint rec_id) {
|
void ServerCore::receivedSH(PIByteArray data, uint rec_id) {
|
||||||
//piCout << "received" << data;
|
// piCout << "received" << data;
|
||||||
PacketHeader hdr = SHNetworkTypes::takeHeader(data);
|
PacketHeader hdr = SHNetworkTypes::takeHeader(data);
|
||||||
if (hdr.type < 0) return;
|
if (hdr.type < 0) return;
|
||||||
//piCout << "received type" << hdr.type << rec_id << data.size();
|
// piCout << "received type" << hdr.type << rec_id << data.size();
|
||||||
int _seed;
|
int _seed;
|
||||||
PIString _ip;
|
PIString _ip;
|
||||||
PIByteArray ba;
|
PIByteArray ba;
|
||||||
//piCout << "received" << type;
|
// piCout << "received" << type;
|
||||||
if (with_reservation) {
|
if (with_reservation) {
|
||||||
switch ((SHNetworkTypes::MulticastType)hdr.type) {
|
switch ((SHNetworkTypes::MulticastType)hdr.type) {
|
||||||
case SHNetworkTypes::ServerNew:
|
case SHNetworkTypes::ServerNew:
|
||||||
@@ -729,8 +758,7 @@ void ServerCore::receivedSH(PIByteArray data, uint rec_id) {
|
|||||||
smutex.lock();
|
smutex.lock();
|
||||||
for (int i = 0; i < servers.size_s(); ++i)
|
for (int i = 0; i < servers.size_s(); ++i)
|
||||||
if (servers[i].seed == _seed) {
|
if (servers[i].seed == _seed) {
|
||||||
if (seed_main == _seed)
|
if (seed_main == _seed) selectNewMain();
|
||||||
selectNewMain();
|
|
||||||
servers.remove(i);
|
servers.remove(i);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
@@ -745,23 +773,21 @@ void ServerCore::receivedSH(PIByteArray data, uint rec_id) {
|
|||||||
break;
|
break;
|
||||||
case SHNetworkTypes::ServerPing:
|
case SHNetworkTypes::ServerPing:
|
||||||
data >> _seed;
|
data >> _seed;
|
||||||
if (seed_main == _seed)
|
if (seed_main == _seed) main_missed = 0;
|
||||||
main_missed = 0;
|
|
||||||
smutex.lock();
|
smutex.lock();
|
||||||
for (int i = 0; i < servers.size_s(); ++i)
|
for (int i = 0; i < servers.size_s(); ++i)
|
||||||
if (servers[i].seed == _seed)
|
if (servers[i].seed == _seed) servers[i].missed = 0;
|
||||||
servers[i].missed = 0;
|
|
||||||
smutex.unlock();
|
smutex.unlock();
|
||||||
//seed_main = _seed;
|
// seed_main = _seed;
|
||||||
//piCoutObj << "recv ServerPing seed =" << _seed;
|
// piCoutObj << "recv ServerPing seed =" << _seed;
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (server_state != ServerCore::ssWorkMain) return;
|
if (server_state != ServerCore::ssWorkMain) return;
|
||||||
//piCout << "received type" << type << rec_id << data.size();
|
// piCout << "received type" << type << rec_id << data.size();
|
||||||
if (hdr.type == SHNetworkTypes::Request) {
|
if (hdr.type == SHNetworkTypes::Request) {
|
||||||
//PIMutexLocker locker(mcast_mutex);
|
// PIMutexLocker locker(mcast_mutex);
|
||||||
PIStringList addresses;
|
PIStringList addresses;
|
||||||
data >> addresses;
|
data >> addresses;
|
||||||
PIString addr;
|
PIString addr;
|
||||||
@@ -772,10 +798,9 @@ void ServerCore::receivedSH(PIByteArray data, uint rec_id) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!addr.isEmpty())
|
if (!addr.isEmpty()) break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
//piCout << "return address" << addr;
|
// piCout << "return address" << addr;
|
||||||
PacketServerInfo info;
|
PacketServerInfo info;
|
||||||
info.identify = PacketIdentification::makeLocal(0, SHS_NETWORK_VERSION, SHS_UISYNC_VERSION);
|
info.identify = PacketIdentification::makeLocal(0, SHS_NETWORK_VERSION, SHS_UISYNC_VERSION);
|
||||||
info.identify.hashes.hash_ui = ui_hash;
|
info.identify.hashes.hash_ui = ui_hash;
|
||||||
@@ -799,36 +824,36 @@ void ServerCore::addressesChanged() {
|
|||||||
|
|
||||||
|
|
||||||
void ServerCore::newTCPConnection(PIEthernet * client) {
|
void ServerCore::newTCPConnection(PIEthernet * client) {
|
||||||
//piCout << "newConnection" << client;
|
// piCout << "newConnection" << client;
|
||||||
log("Client connected from " + PI2QString(client->path()) + " (TCP)", SHServer::LogInfo);
|
log("Client connected from " + PI2QString(client->path()) + " (TCP)", SHServer::LogInfo);
|
||||||
client->setDebug(false);
|
client->setDebug(false);
|
||||||
client->setReadTimeout(60000.);
|
client->setReadTimeout(60000.);
|
||||||
client->setWriteTimeout(60000.);
|
client->setWriteTimeout(60000.);
|
||||||
client->setParameter(PIEthernet::DisonnectOnTimeout, false);
|
client->setParameter(PIEthernet::DisonnectOnTimeout, false);
|
||||||
ServerClient * r = new ServerClient(this, SHNetworkTypes::TCP);
|
ServerClient * r = new ServerClient(this, SHNetworkTypes::TCP);
|
||||||
//CONNECTU(r, packetReceived, this, packetReceived)
|
// CONNECTU(r, packetReceived, this, packetReceived)
|
||||||
r->init(client);
|
r->init(client);
|
||||||
//piCout << "newConnection lock ...";
|
// piCout << "newConnection lock ...";
|
||||||
rmutex.lock();
|
rmutex.lock();
|
||||||
remotes[client] = r;
|
remotes[client] = r;
|
||||||
rmutex.unlock();
|
rmutex.unlock();
|
||||||
client->startThreadedRead();
|
client->startThreadedRead();
|
||||||
//piCout << "newConnection lock done";
|
// piCout << "newConnection lock done";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ServerCore::newCloudConnection(PICloudServer::Client * client) {
|
void ServerCore::newCloudConnection(PICloudServer::Client * client) {
|
||||||
piCout << "newCloudConnection" << client;
|
piCout << "newCloudConnection" << client;
|
||||||
log("Client connected from " + PI2QString(client->path()) + " (Cloud)", SHServer::LogInfo);
|
log("Client connected from " + PI2QString(client->path()) + " (Cloud)", SHServer::LogInfo);
|
||||||
//client->setDebug(false);
|
// client->setDebug(false);
|
||||||
ServerClient * r = new ServerClient(this, SHNetworkTypes::Cloud);
|
ServerClient * r = new ServerClient(this, SHNetworkTypes::Cloud);
|
||||||
//CONNECTU(r, packetReceived, this, packetReceived)
|
// CONNECTU(r, packetReceived, this, packetReceived)
|
||||||
r->init(client);
|
r->init(client);
|
||||||
//piCout << "newConnection lock ...";
|
// piCout << "newConnection lock ...";
|
||||||
rmutex.lock();
|
rmutex.lock();
|
||||||
remotes[client] = r;
|
remotes[client] = r;
|
||||||
rmutex.unlock();
|
rmutex.unlock();
|
||||||
//piCout << "newConnection lock done";
|
// piCout << "newConnection lock done";
|
||||||
client->startThreadedRead();
|
client->startThreadedRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -879,13 +904,13 @@ void ServerCore::receivedIdentification(ServerClient * r, PIByteArray data) {
|
|||||||
sendInitialAdminData(r);
|
sendInitialAdminData(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
//piCoutObj << "my" << ui_hash << rcc_hash;
|
// piCoutObj << "my" << ui_hash << rcc_hash;
|
||||||
//piCoutObj << "cl" << p.hashes.hash_ui << p.hashes.hash_rcc;
|
// piCoutObj << "cl" << p.hashes.hash_ui << p.hashes.hash_rcc;
|
||||||
r->upload_ui = (p.hashes.hash_ui != ui_hash);
|
r->upload_ui = (p.hashes.hash_ui != ui_hash);
|
||||||
r->upload_rcc = (p.hashes.hash_rcc != rcc_hash);
|
r->upload_rcc = (p.hashes.hash_rcc != rcc_hash);
|
||||||
r->tcp->setCheckHeader(true);
|
r->tcp->setCheckHeader(true);
|
||||||
r->tcp->setID(r->id);
|
r->tcp->setID(r->id);
|
||||||
//qDebug() << "ident" << int(r->info.OS_type) << r->info.OS_arch << r->info.OS_version;
|
// qDebug() << "ident" << int(r->info.OS_type) << r->info.OS_arch << r->info.OS_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -908,11 +933,10 @@ void ServerCore::receivedKey(ServerClient * r, PIByteArray data) {
|
|||||||
piCout << "received key" << key;
|
piCout << "received key" << key;
|
||||||
r->tcp->send(ba);
|
r->tcp->send(ba);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
|
||||||
if (r->upload_rcc) {
|
if (r->upload_rcc) {
|
||||||
ba = SHNetworkTypes::makeHeader(SHNetworkTypes::GuiSyncRCC);
|
ba = SHNetworkTypes::makeHeader(SHNetworkTypes::GuiSyncRCC);
|
||||||
ba.append(bqr_content);
|
ba.append(bqr_content);
|
||||||
//qDebug() << "send rcc" << int(SHNetworkTypes::GuiSyncRCC) << bqr_content.size();
|
// qDebug() << "send rcc" << int(SHNetworkTypes::GuiSyncRCC) << bqr_content.size();
|
||||||
} else {
|
} else {
|
||||||
ba = SHNetworkTypes::makeHeader(SHNetworkTypes::GuiRestoreRCC);
|
ba = SHNetworkTypes::makeHeader(SHNetworkTypes::GuiRestoreRCC);
|
||||||
}
|
}
|
||||||
@@ -924,11 +948,11 @@ void ServerCore::receivedKey(ServerClient * r, PIByteArray data) {
|
|||||||
} else {
|
} else {
|
||||||
ba = SHNetworkTypes::makeHeader(SHNetworkTypes::GuiRestoreUI);
|
ba = SHNetworkTypes::makeHeader(SHNetworkTypes::GuiRestoreUI);
|
||||||
}
|
}
|
||||||
//qDebug() << "send ui" << int(SHNetworkTypes::GuiSyncUI) << ba.size();
|
// qDebug() << "send ui" << int(SHNetworkTypes::GuiSyncUI) << ba.size();
|
||||||
r->queueSend(ba);
|
r->queueSend(ba);
|
||||||
|
|
||||||
ba = Q2PIByteArray(sync.buildFullDiffForRole(r->user_role));
|
ba = Q2PIByteArray(sync.buildFullDiffForRole(r->user_role));
|
||||||
//qDebug() << "send init diff" << r->user_role << ba.size();
|
// qDebug() << "send init diff" << r->user_role << ba.size();
|
||||||
if (!ba.isEmpty()) {
|
if (!ba.isEmpty()) {
|
||||||
PIByteArray hdr = SHNetworkTypes::makeHeader(SHNetworkTypes::GuiSyncDiff);
|
PIByteArray hdr = SHNetworkTypes::makeHeader(SHNetworkTypes::GuiSyncDiff);
|
||||||
ba.insert(0, hdr);
|
ba.insert(0, hdr);
|
||||||
@@ -938,14 +962,14 @@ void ServerCore::receivedKey(ServerClient * r, PIByteArray data) {
|
|||||||
ba = SHNetworkTypes::makeHeader(SHNetworkTypes::ConnectingDone);
|
ba = SHNetworkTypes::makeHeader(SHNetworkTypes::ConnectingDone);
|
||||||
r->queueSend(ba);
|
r->queueSend(ba);
|
||||||
|
|
||||||
//r->active = true;
|
// r->active = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ServerCore::sendToAll(const PIByteArray & data, SHServer::ClientRole role, bool no_check) {
|
void ServerCore::sendToAll(const PIByteArray & data, SHServer::ClientRole role, bool no_check) {
|
||||||
PIMutexLocker _ml(rmutex);
|
PIMutexLocker _ml(rmutex);
|
||||||
PIVector<ServerClient * > rl = remotes.values();
|
PIVector<ServerClient *> rl = remotes.values();
|
||||||
for (ServerClient * r: rl) {
|
for (ServerClient * r: rl) {
|
||||||
qDebug() << r << r->tcp << r->active << r->info.role;
|
qDebug() << r << r->tcp << r->active << r->info.role;
|
||||||
if (!r->tcp || r->info.role != role) continue;
|
if (!r->tcp || r->info.role != role) continue;
|
||||||
@@ -1040,7 +1064,7 @@ void ServerCore::IOLog(QString text) {
|
|||||||
e.text = text;
|
e.text = text;
|
||||||
e.type = SHServer::LogIO;
|
e.type = SHServer::LogIO;
|
||||||
rmutex.lock();
|
rmutex.lock();
|
||||||
PIVector<ServerClient * > rl = remotes.values();
|
PIVector<ServerClient *> rl = remotes.values();
|
||||||
for (ServerClient * r: rl) {
|
for (ServerClient * r: rl) {
|
||||||
if (!r) continue;
|
if (!r) continue;
|
||||||
if ((r->info.role != SHServer::RoleAdmin) || !r->admin_log_io) continue;
|
if ((r->info.role != SHServer::RoleAdmin) || !r->admin_log_io) continue;
|
||||||
|
|||||||
+39
-24
@@ -1,49 +1,54 @@
|
|||||||
#ifndef SERVER_CORE_H
|
#ifndef SERVER_CORE_H
|
||||||
#define SERVER_CORE_H
|
#define SERVER_CORE_H
|
||||||
|
|
||||||
|
#include "SH_assembly.h"
|
||||||
|
#include "SH_ui_loader.h"
|
||||||
|
#include "SH_ui_sync.h"
|
||||||
|
#include "script_engine.h"
|
||||||
|
#include "server_client.h"
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <picli.h>
|
#include <picli.h>
|
||||||
#include <picloudserver.h>
|
#include <picloudserver.h>
|
||||||
#include <piliterals_bytes.h>
|
#include <piliterals_bytes.h>
|
||||||
#include "script_engine.h"
|
#include <qad_timers.h>
|
||||||
#include "server_client.h"
|
|
||||||
#include "SH_assembly.h"
|
|
||||||
#include "SH_ui_loader.h"
|
|
||||||
#include "SH_ui_sync.h"
|
|
||||||
|
|
||||||
class Server;
|
class Server;
|
||||||
class ServerClient;
|
class ServerClient;
|
||||||
class ServerStarter;
|
class ServerStarter;
|
||||||
|
|
||||||
class ServerCore: public QObject, public SHMulticast {
|
class ServerCore
|
||||||
|
: public QObject
|
||||||
|
, public SHMulticast
|
||||||
|
, public IndexedTimer<> {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
PIOBJECT_SUBCLASS(ServerCore, SHMulticast)
|
PIOBJECT_SUBCLASS(ServerCore, SHMulticast)
|
||||||
friend class Server;
|
friend class Server;
|
||||||
friend class ServerClient;
|
friend class ServerClient;
|
||||||
friend class ServerStarter;
|
friend class ServerStarter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ServerCore(bool reservation = false);
|
ServerCore(bool reservation = false);
|
||||||
~ServerCore();
|
~ServerCore();
|
||||||
|
|
||||||
void loadRCC(const QString & p);
|
void loadRCC(const QString & p);
|
||||||
void loadUI (const QString & p);
|
void loadUI(const QString & p);
|
||||||
void loadQS (const QString & p);
|
void loadQS(const QString & p);
|
||||||
void loadDAT(const QString & p);
|
void loadDAT(const QString & p);
|
||||||
void loadCM (const QString & p);
|
void loadCM(const QString & p);
|
||||||
void loadVAR(const QString & p);
|
void loadVAR(const QString & p);
|
||||||
void loadBAF(const PIString & p);
|
void loadBAF(const PIString & p);
|
||||||
void loadProject(const QString & p);
|
void loadProject(const QString & p);
|
||||||
void startEth();
|
void startEth();
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
bool isPluginsLoaded() const {return plugins_ok;}
|
bool isPluginsLoaded() const { return plugins_ok; }
|
||||||
|
|
||||||
SHSScriptEngine engine;
|
SHSScriptEngine engine;
|
||||||
PIByteArray admin_password;
|
PIByteArray admin_password;
|
||||||
uint admin_log_max_size = 65_KiB;
|
uint admin_log_max_size = 65_KiB;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void timerEvent(QTimerEvent *) override;
|
|
||||||
void receivedSH(PIByteArray data, uint rec_id) override;
|
void receivedSH(PIByteArray data, uint rec_id) override;
|
||||||
void addressesChanged() override;
|
void addressesChanged() override;
|
||||||
void sendToAll(const PIByteArray & data, SHServer::ClientRole role, bool no_check = false);
|
void sendToAll(const PIByteArray & data, SHServer::ClientRole role, bool no_check = false);
|
||||||
@@ -64,11 +69,20 @@ private:
|
|||||||
void updatePlugins(const QStringList & names, ServerClient * r);
|
void updatePlugins(const QStringList & names, ServerClient * r);
|
||||||
void gatherVariables();
|
void gatherVariables();
|
||||||
void gatherFixedState();
|
void gatherFixedState();
|
||||||
|
void sendAdminData();
|
||||||
|
void syncServers();
|
||||||
|
void procClients();
|
||||||
|
void deleteOldClients();
|
||||||
PacketParameterList adminParameters() const;
|
PacketParameterList adminParameters() const;
|
||||||
EVENT_HANDLER1(void, newTCPConnection, PIEthernet * , client);
|
EVENT_HANDLER1(void, newTCPConnection, PIEthernet *, client);
|
||||||
EVENT_HANDLER1(void, newCloudConnection, PICloudServer::Client * , client);
|
EVENT_HANDLER1(void, newCloudConnection, PICloudServer::Client *, client);
|
||||||
|
|
||||||
enum ServerState {ssStart, ssSync, ssWorkMain, ssWorkReserve};
|
enum ServerState {
|
||||||
|
ssStart,
|
||||||
|
ssSync,
|
||||||
|
ssWorkMain,
|
||||||
|
ssWorkReserve
|
||||||
|
};
|
||||||
|
|
||||||
struct ServerSync {
|
struct ServerSync {
|
||||||
int seed;
|
int seed;
|
||||||
@@ -90,15 +104,17 @@ private:
|
|||||||
SHAssembly ass;
|
SHAssembly ass;
|
||||||
PIEthernet eth_tcp;
|
PIEthernet eth_tcp;
|
||||||
PICloudServer cloud_server;
|
PICloudServer cloud_server;
|
||||||
PIMutex rmutex, lmutex, smutex;
|
PIMutex rmutex, lmutex, smutex, rcq_mutex;
|
||||||
QQueue<LogEntry> log_queue;
|
QQueue<LogEntry> log_queue;
|
||||||
|
PIThread delete_clients_thread;
|
||||||
PIDeque<LogEntry> admin_log, admin_log_history;
|
PIDeque<LogEntry> admin_log, admin_log_history;
|
||||||
QQueue<PacketMessage> message_queue;
|
QQueue<PacketMessage> message_queue;
|
||||||
PIVector<PIEthernet*> eth_mcast;
|
PIVector<PIEthernet *> eth_mcast;
|
||||||
PIByteArray ui_content, bqr_content;
|
PIByteArray ui_content, bqr_content;
|
||||||
PacketServerDynamicState state_dynamic;
|
PacketServerDynamicState state_dynamic;
|
||||||
PacketServerFixedState state_fixed;
|
PacketServerFixedState state_fixed;
|
||||||
PIMap<PIIODevice * , ServerClient * > remotes;
|
PIMap<PIIODevice *, ServerClient *> remotes;
|
||||||
|
PIQueue<ServerClient *> delete_clients_queue;
|
||||||
QDir script_dir;
|
QDir script_dir;
|
||||||
QString lqs_err_msg, script, file_ui_state, file_ui_state_new, file_script;
|
QString lqs_err_msg, script, file_ui_state, file_ui_state_new, file_script;
|
||||||
QList<SHS::ScriptVariable> vars;
|
QList<SHS::ScriptVariable> vars;
|
||||||
@@ -110,30 +126,29 @@ private:
|
|||||||
SHSUiLoader ui_loader;
|
SHSUiLoader ui_loader;
|
||||||
uint ui_hash = 0, rcc_hash = 0;
|
uint ui_hash = 0, rcc_hash = 0;
|
||||||
uint admin_log_cur_size = 0;
|
uint admin_log_cur_size = 0;
|
||||||
int timer = 0, timer_sync = 0, timer_admin = 0, timer_save_state = 0, lqs_err_line = -1, sync_skip = 0, main_missed = 0;
|
int timer = 0, lqs_err_line = -1, sync_skip = 0, main_missed = 0;
|
||||||
int seed = 0 , seed_main = 0;
|
int seed = 0, seed_main = 0;
|
||||||
bool with_reservation = false, plugins_ok = false;
|
bool with_reservation = false, plugins_ok = false;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void connDataReceivedEvent(QString from, QByteArray data);
|
void connDataReceivedEvent(QString from, QByteArray data);
|
||||||
void variableHistoryAdded(QString vname, QPair<QDateTime, double> value);
|
void variableHistoryAdded(QString vname, QPair<QDateTime, double> value);
|
||||||
void scriptError(int line, QString file, QString message, QString stack);
|
void scriptError(int line, QString file, QString message, QString stack);
|
||||||
void scriptLog(QString text, int type) {log(text, (SHServer::LogEntryType)type);}
|
void scriptLog(QString text, int type) { log(text, (SHServer::LogEntryType)type); }
|
||||||
void scriptDebug(QString text);
|
void scriptDebug(QString text);
|
||||||
void scriptMessage(QString text, int type) {message(text, type);}
|
void scriptMessage(QString text, int type) { message(text, type); }
|
||||||
void IOLog(QString text);
|
void IOLog(QString text);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void restart(QString baf_path);
|
void restart(QString baf_path);
|
||||||
void loadedUI ();
|
void loadedUI();
|
||||||
void loadedDAT();
|
void loadedDAT();
|
||||||
void loadedCM ();
|
void loadedCM();
|
||||||
void loadedVAR();
|
void loadedVAR();
|
||||||
void startedAsMain();
|
void startedAsMain();
|
||||||
void startedAsReserve();
|
void startedAsReserve();
|
||||||
void zeroFailure();
|
void zeroFailure();
|
||||||
void updatePluginsRequest(QStringList);
|
void updatePluginsRequest(QStringList);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SERVER_CORE_H
|
#endif // SERVER_CORE_H
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#include "server_starter.h"
|
#include "server_starter.h"
|
||||||
|
|
||||||
#include "SH_base.h"
|
#include "SH_base.h"
|
||||||
#include "SH_plugins_manager.h"
|
#include "SH_plugins_manager.h"
|
||||||
#include <qad_locations.h>
|
|
||||||
|
|
||||||
|
#include <qad_locations.h>
|
||||||
|
|
||||||
|
|
||||||
ServerStarter::ServerStarter(): QObject() {
|
ServerStarter::ServerStarter(): QObject() {
|
||||||
@@ -13,8 +14,7 @@ ServerStarter::ServerStarter(): QObject() {
|
|||||||
if (QFile::exists(confpath)) {
|
if (QFile::exists(confpath)) {
|
||||||
QPIConfig conf(confpath, QIODevice::ReadOnly);
|
QPIConfig conf(confpath, QIODevice::ReadOnly);
|
||||||
QString baf = conf.getValue("baf_path", "").toString().trimmed();
|
QString baf = conf.getValue("baf_path", "").toString().trimmed();
|
||||||
if (!baf.isEmpty())
|
if (!baf.isEmpty()) baf_path = baf;
|
||||||
baf_path = baf;
|
|
||||||
max_failures = conf.getValue("max_failures", max_failures).toInt();
|
max_failures = conf.getValue("max_failures", max_failures).toInt();
|
||||||
log_add_time = conf.getValue("log_add_time", log_add_time).toBool();
|
log_add_time = conf.getValue("log_add_time", log_add_time).toBool();
|
||||||
log_add_dev = conf.getValue("log_add_dev", log_add_dev).toBool();
|
log_add_dev = conf.getValue("log_add_dev", log_add_dev).toBool();
|
||||||
@@ -27,17 +27,17 @@ ServerStarter::ServerStarter(): QObject() {
|
|||||||
admin_password = passwordHash("");
|
admin_password = passwordHash("");
|
||||||
else
|
else
|
||||||
admin_password = PIByteArray::fromHex(Q2PIString(ph));
|
admin_password = PIByteArray::fromHex(Q2PIString(ph));
|
||||||
//piCout << "last admin_passwd" << admin_passwd.toHex();
|
// piCout << "last admin_passwd" << admin_passwd.toHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ServerStarter::~ServerStarter() {
|
ServerStarter::~ServerStarter() {
|
||||||
destroy();
|
// destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ServerStarter::writePassword(const PIByteArray & ph) {
|
void ServerStarter::writePassword(const PIByteArray & ph) {
|
||||||
//piCout << " set admin_passwd" << ph.toHex();
|
// piCout << " set admin_passwd" << ph.toHex();
|
||||||
QPIConfig conf(confpath, QIODevice::ReadWrite);
|
QPIConfig conf(confpath, QIODevice::ReadWrite);
|
||||||
conf.setValue("admin_passwd", PI2QString(ph.toHex()));
|
conf.setValue("admin_passwd", PI2QString(ph.toHex()));
|
||||||
}
|
}
|
||||||
@@ -50,8 +50,7 @@ void ServerStarter::init() {
|
|||||||
server->core.admin_log_max_size = piRound(max_log_kb * 1024);
|
server->core.admin_log_max_size = piRound(max_log_kb * 1024);
|
||||||
server->core.admin_password = admin_password;
|
server->core.admin_password = admin_password;
|
||||||
connect(server, SIGNAL(restartRequest()), this, SLOT(restart()));
|
connect(server, SIGNAL(restartRequest()), this, SLOT(restart()));
|
||||||
if (no_graphics)
|
if (no_graphics) server->disableGraphics();
|
||||||
server->disableGraphics();
|
|
||||||
server->core.engine.connection()->setLogAddTime(log_add_time);
|
server->core.engine.connection()->setLogAddTime(log_add_time);
|
||||||
server->core.engine.connection()->setLogAddDevice(log_add_dev);
|
server->core.engine.connection()->setLogAddDevice(log_add_dev);
|
||||||
server->core.engine.connection()->setLogIO(log_io);
|
server->core.engine.connection()->setLogIO(log_io);
|
||||||
@@ -75,8 +74,7 @@ void ServerStarter::start() {
|
|||||||
RUNTIME->connection.start();
|
RUNTIME->connection.start();
|
||||||
}
|
}
|
||||||
server->core.startEth();
|
server->core.startEth();
|
||||||
if (!no_graphics)
|
if (!no_graphics) server->show();
|
||||||
server->show();
|
|
||||||
QTimer::singleShot(10000, &(server->core), SIGNAL(zeroFailure()));
|
QTimer::singleShot(10000, &(server->core), SIGNAL(zeroFailure()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,8 +88,7 @@ bool ServerStarter::checkFailure() {
|
|||||||
}
|
}
|
||||||
int fails = 0;
|
int fails = 0;
|
||||||
QTextStream s(&f);
|
QTextStream s(&f);
|
||||||
if (f.size() >= 1)
|
if (f.size() >= 1) s >> fails;
|
||||||
s >> fails;
|
|
||||||
if (fails >= max_failures) {
|
if (fails >= max_failures) {
|
||||||
qDebug() << "[ServerStarter] Error: too many failures, standby ...";
|
qDebug() << "[ServerStarter] Error: too many failures, standby ...";
|
||||||
return true;
|
return true;
|
||||||
@@ -104,7 +101,8 @@ bool ServerStarter::checkFailure() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define CHECK_CONF(e) if (!conf.isEntryExists(#e)) s << #e << " = " << e << "\n";
|
#define CHECK_CONF(e) \
|
||||||
|
if (!conf.isEntryExists(#e)) s << #e << " = " << e << "\n";
|
||||||
|
|
||||||
void ServerStarter::checkConfig() {
|
void ServerStarter::checkConfig() {
|
||||||
QPIConfig conf(confpath, QIODevice::ReadOnly);
|
QPIConfig conf(confpath, QIODevice::ReadOnly);
|
||||||
@@ -117,13 +115,13 @@ void ServerStarter::checkConfig() {
|
|||||||
f.seek(f.size());
|
f.seek(f.size());
|
||||||
QTextStream s(&f);
|
QTextStream s(&f);
|
||||||
auto baf_path = src_baf_path;
|
auto baf_path = src_baf_path;
|
||||||
CHECK_CONF(baf_path );
|
CHECK_CONF(baf_path);
|
||||||
CHECK_CONF(max_failures);
|
CHECK_CONF(max_failures);
|
||||||
CHECK_CONF(log_add_time);
|
CHECK_CONF(log_add_time);
|
||||||
CHECK_CONF(log_add_dev );
|
CHECK_CONF(log_add_dev);
|
||||||
CHECK_CONF(log_io );
|
CHECK_CONF(log_io);
|
||||||
CHECK_CONF(reservation );
|
CHECK_CONF(reservation);
|
||||||
CHECK_CONF(max_log_kb );
|
CHECK_CONF(max_log_kb);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef CHECK_CONF
|
#undef CHECK_CONF
|
||||||
@@ -150,13 +148,17 @@ void ServerStarter::updatePlugins(QStringList names) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RUNTIME->plugins_manager->updateInfo();
|
RUNTIME->plugins_manager->updateInfo();
|
||||||
qDebug() << "[ServerStarter::updatePlugins]" << "Got info from server, shutdown server ...";
|
qDebug() << "[ServerStarter::updatePlugins]"
|
||||||
|
<< "Got info from server, shutdown server ...";
|
||||||
destroy();
|
destroy();
|
||||||
qDebug() << "[ServerStarter::updatePlugins]" << "Update plugins ...";
|
qDebug() << "[ServerStarter::updatePlugins]"
|
||||||
|
<< "Update plugins ...";
|
||||||
RUNTIME->plugins_manager->update(names);
|
RUNTIME->plugins_manager->update(names);
|
||||||
qDebug() << "[ServerStarter::updatePlugins]" << "Update done, start server ...";
|
qDebug() << "[ServerStarter::updatePlugins]"
|
||||||
|
<< "Update done, start server ...";
|
||||||
restart({});
|
restart({});
|
||||||
qDebug() << "[ServerStarter::updatePlugins]" << "Restarted";
|
qDebug() << "[ServerStarter::updatePlugins]"
|
||||||
|
<< "Restarted";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user