GODT-2071: bridge-gui report error if an orphan bridge is detected.

This commit is contained in:
Xavier Michelon
2022-11-09 17:49:06 +01:00
committed by Romain LE JEUNE
parent 19930f63e2
commit 51d4a9c7ee

View File

@ -42,9 +42,23 @@ namespace
QString const bridgeLock = "bridge-gui.lock"; ///< file name used for the lock file. QString const bridgeLock = "bridge-gui.lock"; ///< file name used for the lock file.
QString const exeName = "bridge" + exeSuffix; ///< The bridge executable file name.* QString const exeName = "bridge" + exeSuffix; ///< The bridge executable file name.*
qint64 const grpcServiceConfigWaitDelayMs = 180000; ///< The wait delay for the gRPC config file in milliseconds. qint64 const grpcServiceConfigWaitDelayMs = 180000; ///< The wait delay for the gRPC config file in milliseconds.
//****************************************************************************************************************************************************
/// According to Qt doc, one per application is OK, but its use should be restricted to a
/// single thread.
/// \return The network access manager for the application.
//****************************************************************************************************************************************************
QNetworkAccessManager& networkManager()
{
static QNetworkAccessManager nam;
return nam;
} }
} // anonymous namespace
//**************************************************************************************************************************************************** //****************************************************************************************************************************************************
/// \return The path of the bridge executable. /// \return The path of the bridge executable.
/// \return A null string if the executable could not be located. /// \return A null string if the executable could not be located.
@ -186,19 +200,42 @@ QUrl getApiUrl()
} }
//****************************************************************************************************************************************************
/// \return The URL for the focus endpoint of the bridge API URL.
//****************************************************************************************************************************************************
QUrl getFocusUrl()
{
QUrl url = getApiUrl();
url.setPath("/focus");
return url;
}
//****************************************************************************************************************************************************
/// \return true if an instance of bridge is already running.
//****************************************************************************************************************************************************
bool isBridgeRunning()
{
QTimer timer;
timer.setSingleShot(true);
QNetworkReply *rep = networkManager().get(QNetworkRequest(getFocusUrl()));
QEventLoop loop;
bool timedOut = false;
QObject::connect(&timer, &QTimer::timeout, [&]() { timedOut = true; loop.quit(); });
QObject::connect(rep, &QNetworkReply::finished, &loop, &QEventLoop::quit);
timer.start(1000); // we time out after 1 second and consider no other instance is running.
loop.exec();
return ((!timedOut) && (rep->error() == QNetworkReply::NetworkError::NoError));
}
//**************************************************************************************************************************************************** //****************************************************************************************************************************************************
/// \brief Use api to bring focus on existing bridge instance. /// \brief Use api to bring focus on existing bridge instance.
//**************************************************************************************************************************************************** //****************************************************************************************************************************************************
void focusOtherInstance() void focusOtherInstance()
{ {
QNetworkAccessManager *manager; QNetworkReply *rep = networkManager().get(QNetworkRequest(getFocusUrl()));
QNetworkRequest request;
manager = new QNetworkAccessManager();
QUrl url = getApiUrl();
url.setPath("/focus");
request.setUrl(url);
QNetworkReply* rep = manager->get(request);
QEventLoop loop; QEventLoop loop;
QObject::connect(rep, &QNetworkReply::finished, &loop, &QEventLoop::quit); QObject::connect(rep, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec(); loop.exec();
@ -220,8 +257,6 @@ void launchBridge(QStringList const &args)
else else
app().log().debug(QString("Bridge executable path: %1").arg(QDir::toNativeSeparators(bridgeExePath))); app().log().debug(QString("Bridge executable path: %1").arg(QDir::toNativeSeparators(bridgeExePath)));
qint64 const pid = qApp->applicationPid(); qint64 const pid = qApp->applicationPid();
QStringList const params = QStringList { "--grpc", "--parent-pid", QString::number(pid) } + args ; QStringList const params = QStringList { "--grpc", "--parent-pid", QString::number(pid) } + args ;
app().log().info(QString("Launching bridge process with command \"%1\" %2").arg(bridgeExePath, params.join(" "))); app().log().info(QString("Launching bridge process with command \"%1\" %2").arg(bridgeExePath, params.join(" ")));
@ -272,8 +307,8 @@ int main(int argc, char *argv[])
{ {
focusOtherInstance(); focusOtherInstance();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
QStringList args; QStringList args;
QString launcher; QString launcher;
bool attach = false; bool attach = false;
@ -287,6 +322,9 @@ int main(int argc, char *argv[])
if (!attach) if (!attach)
{ {
if (isBridgeRunning())
throw Exception("An orphan instance of bridge is already running. Please terminate it and relaunch the application.");
// before launching bridge, we remove any trailing service config file, because we need to make sure we get a newly generated one. // before launching bridge, we remove any trailing service config file, because we need to make sure we get a newly generated one.
GRPCClient::removeServiceConfigFile(); GRPCClient::removeServiceConfigFile();
launchBridge(args); launchBridge(args);