forked from Silverfish/proton-bridge
GODT-2071: bridge-gui report error if an orphan bridge is detected.
This commit is contained in:
committed by
Romain LE JEUNE
parent
19930f63e2
commit
51d4a9c7ee
@ -32,19 +32,33 @@ using namespace bridgepp;
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
/// \brief The file extension for the bridge executable file.
|
/// \brief The file extension for the bridge executable file.
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
QString const exeSuffix = ".exe";
|
QString const exeSuffix = ".exe";
|
||||||
#else
|
#else
|
||||||
QString const exeSuffix;
|
QString const exeSuffix;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user