feat(ipc): Stop bad version existing Core process
This commit is contained in:
parent
e9868123df
commit
10027ecc1c
11 changed files with 85 additions and 18 deletions
|
|
@ -132,6 +132,9 @@ int main(int argc, char **argv)
|
|||
QApplication::setApplicationName(QStringLiteral("%1 Core").arg(kAppName));
|
||||
|
||||
const auto ipcServer = new deskflow::core::ipc::CoreIpcServer(&app); // NOSONAR - Qt managed
|
||||
QObject::connect(
|
||||
ipcServer, &deskflow::core::ipc::IpcServer::stopProcessRequested, coreApp, &App::quit, Qt::DirectConnection
|
||||
);
|
||||
ipcServer->listen();
|
||||
|
||||
QThread coreThread;
|
||||
|
|
|
|||
|
|
@ -168,6 +168,12 @@ void App::handleScreenError() const
|
|||
getEvents()->addEvent(Event(EventTypes::Quit));
|
||||
}
|
||||
|
||||
void App::quit()
|
||||
{
|
||||
LOG_INFO("quitting");
|
||||
getEvents()->addEvent(Event(EventTypes::Quit));
|
||||
}
|
||||
|
||||
void App::runEventsLoop(const void *)
|
||||
{
|
||||
int exitCode = m_events->loop();
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ public:
|
|||
}
|
||||
|
||||
void run(QThread &coreThread);
|
||||
void quit();
|
||||
void setupFileLogging();
|
||||
void loggingFilterWarning() const;
|
||||
void initApp() override;
|
||||
|
|
|
|||
|
|
@ -29,8 +29,14 @@ CoreIpcServer &CoreIpcServer::instance()
|
|||
|
||||
void CoreIpcServer::processCommand(QLocalSocket *clientSocket, const QString &command, const QStringList &parts)
|
||||
{
|
||||
Q_UNUSED(clientSocket)
|
||||
Q_UNUSED(parts)
|
||||
if (command == QStringLiteral("stop")) {
|
||||
LOG_DEBUG("core ipc server got stop message");
|
||||
writeToClientSocket(clientSocket, QStringLiteral("ok"));
|
||||
broadcastCommand(QStringLiteral("bye"));
|
||||
Q_EMIT stopProcessRequested();
|
||||
return;
|
||||
}
|
||||
LOG_WARN("core ipc server got unknown command: %s", command.toUtf8().constData());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -125,13 +125,12 @@ void IpcServer::processMessage(QLocalSocket *clientSocket, const QString &messag
|
|||
LOG_DEBUG("%s ipc server got hello message (version: %s)", m_typeName.constData(), versionId.toUtf8().constData());
|
||||
|
||||
if (clientVersion != versionId) {
|
||||
LOG_ERR(
|
||||
LOG_WARN(
|
||||
"%s ipc client version mismatch (client: %s, server: %s)", m_typeName.constData(),
|
||||
clientVersion.toUtf8().constData(), versionId.toUtf8().constData()
|
||||
);
|
||||
writeToClientSocket(clientSocket, QStringLiteral("error=version mismatch, expected: %1").arg(versionId));
|
||||
writeToClientSocket(clientSocket, QStringLiteral("versionMismatch=%1").arg(versionId));
|
||||
clientSocket->flush();
|
||||
clientSocket->disconnectFromServer();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -144,6 +144,33 @@ void CoreProcess::daemonIpcClientConnected()
|
|||
m_daemonIpcClient->requestLogPath();
|
||||
}
|
||||
|
||||
void CoreProcess::checkExistingProcess()
|
||||
{
|
||||
qInfo("checking existing core");
|
||||
|
||||
auto *client = new ipc::CoreIpcClient(this);
|
||||
connect(client, &ipc::CoreIpcClient::connected, this, [client] {
|
||||
qInfo("existing core has matching version, leaving it running");
|
||||
client->deleteLater();
|
||||
});
|
||||
connect(client, &ipc::CoreIpcClient::versionMismatch, this, [client] {
|
||||
qInfo("existing core has mismatched version, asking it to stop");
|
||||
client->sendStop();
|
||||
});
|
||||
connect(client, &ipc::CoreIpcClient::serverShutdown, this, [this, client] {
|
||||
qInfo("existing core stopped successfully");
|
||||
client->deleteLater();
|
||||
setProcessState(ProcessState::RetryPending);
|
||||
m_retryTimer.setSingleShot(true);
|
||||
m_retryTimer.start(kRetryDelay);
|
||||
});
|
||||
connect(client, &ipc::CoreIpcClient::connectionFailed, this, [client] {
|
||||
qCritical("could not contact existing core");
|
||||
client->deleteLater();
|
||||
});
|
||||
client->connectToServer();
|
||||
}
|
||||
|
||||
void CoreProcess::onProcessFinished(int exitCode, QProcess::ExitStatus)
|
||||
{
|
||||
using enum ProcessState;
|
||||
|
|
@ -155,9 +182,10 @@ void CoreProcess::onProcessFinished(int exitCode, QProcess::ExitStatus)
|
|||
|
||||
if (exitCode != s_exitSuccess) {
|
||||
setProcessState(Stopped);
|
||||
if (exitCode == s_exitDuplicate)
|
||||
qWarning("desktop process is already running");
|
||||
else
|
||||
if (exitCode == s_exitDuplicate) {
|
||||
checkExistingProcess();
|
||||
return;
|
||||
}
|
||||
qWarning("desktop process exited with code: %d", exitCode);
|
||||
return;
|
||||
}
|
||||
|
|
@ -399,10 +427,15 @@ void CoreProcess::start(std::optional<ProcessMode> processModeOption)
|
|||
|
||||
m_coreIpcClient = new ipc::CoreIpcClient(this);
|
||||
connect(m_coreIpcClient, &ipc::CoreIpcClient::commandReceived, this, &CoreProcess::onCoreIpcMessageReceived);
|
||||
connect(m_coreIpcClient, &ipc::CoreIpcClient::connected, this, [] { qInfo("connected to core ipc server"); });
|
||||
connect(m_coreIpcClient, &ipc::CoreIpcClient::connected, this, [] {
|
||||
qDebug("connected to core ipc server");
|
||||
});
|
||||
connect(m_coreIpcClient, &ipc::CoreIpcClient::connectionFailed, this, [] {
|
||||
qWarning("failed to establish core ipc connection");
|
||||
});
|
||||
connect(m_coreIpcClient, &ipc::CoreIpcClient::serverShutdown, this, [] {
|
||||
qDebug("core ipc server shut down cleanly");
|
||||
});
|
||||
|
||||
m_coreIpcClient->connectToServer();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ private:
|
|||
void handleLogLines(const QString &text);
|
||||
QString correctedAddress(const QString &address) const;
|
||||
void setupDaemonLogTail(const QString &logPath);
|
||||
void checkExistingProcess();
|
||||
static QString makeQuotedArgs(const QString &app, const QStringList &args);
|
||||
static QString processModeToString(const Settings::ProcessMode mode);
|
||||
static QString processStateToString(const CoreProcess::ProcessState state);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@ CoreIpcClient::CoreIpcClient(QObject *parent) : IpcClient(parent, kCoreIpcName,
|
|||
// do nothing
|
||||
}
|
||||
|
||||
void CoreIpcClient::sendStop()
|
||||
{
|
||||
sendMessage(QStringLiteral("stop"));
|
||||
}
|
||||
|
||||
void CoreIpcClient::processCommand(const QString &command, const QStringList &parts)
|
||||
{
|
||||
const auto args = parts.size() >= 2 ? parts.at(1) : QString();
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ class CoreIpcClient : public IpcClient
|
|||
public:
|
||||
explicit CoreIpcClient(QObject *parent = nullptr);
|
||||
|
||||
void sendStop();
|
||||
|
||||
Q_SIGNALS:
|
||||
void commandReceived(const QString &command, const QString &args);
|
||||
|
||||
|
|
|
|||
|
|
@ -151,6 +151,13 @@ void IpcClient::handleReadyRead()
|
|||
continue;
|
||||
}
|
||||
|
||||
if (parts.at(0) == QStringLiteral("bye")) {
|
||||
qDebug().noquote() << QStringLiteral("%1 ipc server is shutting down").arg(m_typeName);
|
||||
disconnectFromServer();
|
||||
Q_EMIT serverShutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
processCommand(parts.at(0), parts);
|
||||
}
|
||||
|
||||
|
|
@ -169,6 +176,17 @@ void IpcClient::handleHandshakeMessage(const QStringList &parts)
|
|||
return;
|
||||
}
|
||||
|
||||
const auto versionId = QStringLiteral("%1+%2").arg(kVersion, kVersionGitSha);
|
||||
|
||||
if (parts.at(0) == QStringLiteral("versionMismatch")) {
|
||||
const auto serverVersion = parts.size() >= 2 ? parts.at(1) : QStringLiteral("unknown");
|
||||
qWarning().noquote(
|
||||
) << QStringLiteral("%1 ipc version mismatch (client: %2, server: %3)").arg(m_typeName, versionId, serverVersion);
|
||||
m_state = State::Connected;
|
||||
Q_EMIT versionMismatch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (parts.at(0) != QStringLiteral("hello")) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -180,15 +198,6 @@ void IpcClient::handleHandshakeMessage(const QStringList &parts)
|
|||
return;
|
||||
}
|
||||
|
||||
const auto versionId = QStringLiteral("%1+%2").arg(kVersion, kVersionGitSha);
|
||||
if (const auto serverVersion = parts.at(1); serverVersion != versionId) {
|
||||
qCritical().noquote(
|
||||
) << QStringLiteral("%1 ipc version mismatch (client: %2 , server: %3)").arg(m_typeName, versionId, serverVersion);
|
||||
disconnectFromServer();
|
||||
Q_EMIT connectionFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
m_state = State::Connected;
|
||||
qDebug().noquote() << QStringLiteral("%1 ipc client connected").arg(m_typeName);
|
||||
Q_EMIT connected();
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ public:
|
|||
Q_SIGNALS:
|
||||
void connected();
|
||||
void connectionFailed();
|
||||
void serverShutdown();
|
||||
void versionMismatch();
|
||||
|
||||
private Q_SLOTS:
|
||||
void handleDisconnected();
|
||||
|
|
|
|||
Loading…
Reference in a new issue