GODT-1837: Fix restart.

GOTD-1837: added wait flag.
GODT-1837: strip --wait flag from launcher command-line.
GODT-1837: hide main window before restart.
This commit is contained in:
Xavier Michelon
2022-08-30 11:56:13 +02:00
parent 2780dc6a67
commit 8bb2a399cc
15 changed files with 237 additions and 67 deletions

View File

@ -31,8 +31,8 @@ using namespace bridgepp;
EventStreamReader::EventStreamReader(QObject *parent)
: Worker(parent)
{
connect(this, &EventStreamReader::started, [&]() { app().log().debug("EventStreamReader started"); });
connect(this, &EventStreamReader::finished, [&]() { app().log().debug("EventStreamReader finished"); });
connect(this, &EventStreamReader::started, this, &EventStreamReader::onStarted);
connect(this, &EventStreamReader::finished, this, &EventStreamReader::onFinished);
connect(this, &EventStreamReader::error, &app().log(), &Log::error);
}
@ -57,3 +57,27 @@ void EventStreamReader::run()
emit error(e.qwhat());
}
}
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void EventStreamReader::onStarted() const
{
app().log().debug("EventStreamReader started");
}
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void EventStreamReader::onFinished() const
{
app().log().debug("EventStreamReader finished");
if (!app().bridgeMonitor())
{
// no bridge monitor means we are in a debug environment, running in attached mode. Event stream has terminated, so bridge is shutting
// down. Because we're in attached mode, bridge-gui will not get notified that bridge is going down, so we shutdown manually here.
qApp->exit(EXIT_SUCCESS);
}
}

View File

@ -39,6 +39,8 @@ public: // member functions
public slots:
void run() override; ///< Run the reader.
void onStarted() const; ///< Slot for the 'started' signal.
void onFinished() const; ///< Slot for the 'finished' signal.
signals:
void eventReceived(QString eventString); ///< signal for events.

View File

@ -229,6 +229,10 @@ void QMLBackend::restart()
app().grpc().quit();
}
//****************************************************************************************************************************************************
/// \param[in] launcher The path to the launcher.
//****************************************************************************************************************************************************
void QMLBackend::forceLauncher(QString launcher)
{
app().grpc().forceLauncher(launcher);
@ -270,8 +274,9 @@ void QMLBackend::changeColorScheme(QString const &scheme)
//****************************************************************************************************************************************************
void QMLBackend::toggleUseSSLforSMTP(bool makeItActive)
{
if (app().grpc().setUseSSLForSMTP(makeItActive).ok())
emit useSSLforSMTPChanged(makeItActive);
// if call succeed, app will restart. No need to emit a value change signal, because it will trigger a read-back via gRPC that will fail.
emit hideMainWindow();
app().grpc().setUseSSLForSMTP(makeItActive);
}
@ -281,11 +286,21 @@ void QMLBackend::toggleUseSSLforSMTP(bool makeItActive)
//****************************************************************************************************************************************************
void QMLBackend::changePorts(int imapPort, int smtpPort)
{
if (app().grpc().changePorts(imapPort, smtpPort).ok())
{
emit portIMAPChanged(imapPort);
emit portSMTPChanged(smtpPort);
}
// if call succeed, app will restart. No need to emit a value change signal, because it will trigger a read-back via gRPC that will fail.
emit hideMainWindow();
app().grpc().changePorts(imapPort, smtpPort);
}
//****************************************************************************************************************************************************
/// \param[in] enable Is cache enabled?
/// \param[in] path The path of the cache.
//****************************************************************************************************************************************************
void QMLBackend::changeLocalCache(bool enable, QUrl const &path)
{
// if call succeed, app will restart. No need to emit a value change signal, because it will trigger a read-back via gRPC that will fail.
emit hideMainWindow();
app().grpc().changeLocalCache(enable, path);
}
@ -353,3 +368,5 @@ void QMLBackend::onResetFinished()
emit resetFinished();
this->restart();
}

View File

@ -143,7 +143,7 @@ public slots: // slot for signals received from QML -> To be forwarded to Bridge
void toggleAutostart(bool active); // _ func(makeItActive bool) `slot:"toggleAutostart"`
void toggleBeta(bool active); // _ func(makeItActive bool) `slot:"toggleBeta"`
void changeColorScheme(QString const &scheme); // _ func(string) `slot:"changeColorScheme"`
void changeLocalCache(bool enable, QUrl const& path) { app().grpc().changeLocalCache(enable, path); } // _ func(enableDiskCache bool, diskCachePath core.QUrl) `slot:"changeLocalCache"`
void changeLocalCache(bool enable, QUrl const& path); // _ func(enableDiskCache bool, diskCachePath core.QUrl) `slot:"changeLocalCache"`
void login(QString const& username, QString const& password) { app().grpc().login(username, password);} // _ func(username, password string) `slot:"login"`
void login2FA(QString const& username, QString const& code) { app().grpc().login2FA(username, code);} // _ func(username, code string) `slot:"login2FA"`
void login2Password(QString const& username, QString const& password) { app().grpc().login2Passwords(username, password);} // _ func(username, password string) `slot:"login2Password"`
@ -211,6 +211,7 @@ signals: // Signals received from the Go backend, to be forwarded to QML
void bugReportSendSuccess(); // _ func() `signal:"bugReportSendSuccess"`
void bugReportSendError(); // _ func() `signal:"bugReportSendError"`
void showMainWindow(); // _ func() `signal:showMainWindow`
void hideMainWindow();
private: // member functions
void retrieveUserList(); ///< Retrieve the list of users via gRPC.

View File

@ -224,12 +224,14 @@ void closeBridgeApp()
//****************************************************************************************************************************************************
int main(int argc, char *argv[])
{
// The application instance is needed to display system message boxes. As we may have to do it in the exception handler,
// application instance is create outside the try/catch clause.
if (QSysInfo::productType() != "windows")
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
QApplication guiApp(argc, argv);
try
{
if (QSysInfo::productType() != "windows")
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
QApplication guiApp(argc, argv);
initQtApplication();
Log &log = initLog();
@ -302,6 +304,7 @@ int main(int argc, char *argv[])
}
catch (Exception const &e)
{
QMessageBox::critical(nullptr, "Error", e.qwhat());
QTextStream(stderr) << e.qwhat() << "\n";
return EXIT_FAILURE;
}

View File

@ -59,6 +59,10 @@ QtObject {
mainWindow.showAndRise()
}
function onColorSchemeNameChanged(scheme) { root.setColorScheme() }
function onHideMainWindow() {
mainWindow.hide();
}
}
}

View File

@ -288,7 +288,9 @@ grpc::Status GRPCClient::reportBug(QString const &description, QString const &ad
//****************************************************************************************************************************************************
grpc::Status GRPCClient::useSSLForSMTP(bool &outUseSSL)
{
return this->logGRPCCallStatus(this->getBool(&Bridge::Stub::UseSslForSmtp, outUseSSL), __FUNCTION__);
Status status = this->getBool(&Bridge::Stub::UseSslForSmtp, outUseSSL);
return this->logGRPCCallStatus(status, __FUNCTION__);
}
@ -363,7 +365,8 @@ grpc::Status GRPCClient::setIsDoHEnabled(bool enabled)
grpc::Status GRPCClient::quit()
{
grpc::ClientContext ctx;
return this->logGRPCCallStatus(stub_->Quit(&ctx, empty, &empty), __FUNCTION__);
// quitting will shut down the gRPC service, to we may get an 'Unavailable' response for the call
return this->logGRPCCallStatus(stub_->Quit(&ctx, empty, &empty), __FUNCTION__, { StatusCode::UNAVAILABLE });
}
@ -373,7 +376,8 @@ grpc::Status GRPCClient::quit()
grpc::Status GRPCClient::restart()
{
grpc::ClientContext ctx;
return this->logGRPCCallStatus(stub_->Restart(&ctx, empty, &empty), __FUNCTION__);
// restarting will shut down the gRPC service, to we may get an 'Unavailable' response for the call
return this->logGRPCCallStatus(stub_->Restart(&ctx, empty, &empty), __FUNCTION__, { StatusCode::UNAVAILABLE });
}
@ -882,11 +886,11 @@ void GRPCClient::logError(QString const &message)
/// \param[in] status The status
/// \param[in] callName The call name.
//****************************************************************************************************************************************************
grpc::Status GRPCClient::logGRPCCallStatus(Status const &status, QString const &callName)
grpc::Status GRPCClient::logGRPCCallStatus(Status const &status, QString const &callName, QList<grpc::StatusCode> allowedErrors)
{
if (log_)
{
if (status.ok())
if (status.ok() || allowedErrors.contains(status.error_code()))
log_->debug(QString("%1()").arg(callName));
else
log_->error(QString("%1() FAILED").arg(callName));

View File

@ -201,7 +201,7 @@ private slots:
private:
void logDebug(QString const &message); ///< Log an event.
void logError(QString const &message); ///< Log an event.
grpc::Status logGRPCCallStatus(grpc::Status const &status, QString const &callName); ///< Log the status of a gRPC code.
grpc::Status logGRPCCallStatus(grpc::Status const &status, QString const &callName, QList<grpc::StatusCode> allowedErrors = {}); ///< Log the status of a gRPC code.
grpc::Status simpleMethod(SimpleMethod method); ///< perform a gRPC call to a bool setter.
grpc::Status setBool(BoolSetter setter, bool value); ///< perform a gRPC call to a bool setter.
grpc::Status getBool(BoolGetter getter, bool &outValue); ///< perform a gRPC call to a bool getter.