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

@ -32,19 +32,33 @@ using namespace bridgepp;
namespace
{
/// \brief The file extension for the bridge executable file.
/// \brief The file extension for the bridge executable file.
#ifdef Q_OS_WIN32
QString const exeSuffix = ".exe";
#else
QString const exeSuffix;
#endif
QString const bridgeLock = "bridge-gui.lock"; ///< file name used for the lock file.
QString const exeName = "bridge" + exeSuffix; ///< The bridge executable file name.*
qint64 const grpcServiceConfigWaitDelayMs = 180000; ///< The wait delay for the gRPC config file in milliseconds.
QString const bridgeLock = "bridge-gui.lock"; ///< file name used for the lock file.
QString const exeName = "bridge" + exeSuffix; ///< The bridge executable file name.*
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 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.
//****************************************************************************************************************************************************
void focusOtherInstance()
{
QNetworkAccessManager *manager;
QNetworkRequest request;
manager = new QNetworkAccessManager();
QUrl url = getApiUrl();
url.setPath("/focus");
request.setUrl(url);
QNetworkReply* rep = manager->get(request);
QNetworkReply *rep = networkManager().get(QNetworkRequest(getFocusUrl()));
QEventLoop loop;
QObject::connect(rep, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
@ -220,8 +257,6 @@ void launchBridge(QStringList const &args)
else
app().log().debug(QString("Bridge executable path: %1").arg(QDir::toNativeSeparators(bridgeExePath)));
qint64 const pid = qApp->applicationPid();
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(" ")));
@ -272,8 +307,8 @@ int main(int argc, char *argv[])
{
focusOtherInstance();
return EXIT_FAILURE;
}
QStringList args;
QString launcher;
bool attach = false;
@ -287,6 +322,9 @@ int main(int argc, char *argv[])
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.
GRPCClient::removeServiceConfigFile();
launchBridge(args);