fix(GODT-2389): close bridge on exception and add max termination wait time.

This commit is contained in:
Xavier Michelon
2023-02-22 19:39:24 +01:00
parent 89112baf96
commit 265af2d299
3 changed files with 12 additions and 10 deletions

View File

@ -117,8 +117,9 @@ QQmlComponent *createRootQmlComponent(QQmlApplicationEngine &engine) {
rootComponent->loadUrl(QUrl(qrcQmlDir + "/Bridge.qml")); rootComponent->loadUrl(QUrl(qrcQmlDir + "/Bridge.qml"));
if (rootComponent->status() != QQmlComponent::Status::Ready) { if (rootComponent->status() != QQmlComponent::Status::Ready) {
app().log().error(rootComponent->errorString()); QString const &err =rootComponent->errorString();
throw Exception("Could not load QML component"); app().log().error(err);
throw Exception("Could not load QML component", err);
} }
return rootComponent; return rootComponent;
} }
@ -255,12 +256,8 @@ void closeBridgeApp() {
app().grpc().quit(); // this will cause the grpc service and the bridge app to close. app().grpc().quit(); // this will cause the grpc service and the bridge app to close.
UPOverseer &overseer = app().bridgeOverseer(); UPOverseer &overseer = app().bridgeOverseer();
if (!overseer) { // The app was run in 'attach' mode and attached to an existing instance of Bridge. We're not monitoring it. if (overseer) { // A null overseer means the app was run in 'attach' mode. We're not monitoring it.
return; overseer->wait(Overseer::maxTerminationWaitTimeMs);
}
while (!overseer->isFinished()) {
QThread::msleep(20);
} }
} }
@ -387,7 +384,7 @@ int main(int argc, char *argv[]) {
QObject::disconnect(connection); QObject::disconnect(connection);
app().grpc().stopEventStreamReader(); app().grpc().stopEventStreamReader();
if (!app().backend().waitForEventStreamReaderToFinish(5000)) { if (!app().backend().waitForEventStreamReaderToFinish(Overseer::maxTerminationWaitTimeMs)) {
log.warn("Event stream reader took too long to finish."); log.warn("Event stream reader took too long to finish.");
} }
@ -413,6 +410,7 @@ int main(int argc, char *argv[]) {
errStream << "reportID: " << QByteArray(uuid.bytes, 16).toHex() << " Captured exception :" << e.qwhat() << "\n"; errStream << "reportID: " << QByteArray(uuid.bytes, 16).toHex() << " Captured exception :" << e.qwhat() << "\n";
if (hasDetails) if (hasDetails)
errStream << "\nDetails:\n" << e.details() << "\n"; errStream << "\nDetails:\n" << e.details() << "\n";
closeBridgeApp();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }

View File

@ -84,7 +84,8 @@ void Overseer::releaseWorker() {
if (thread_) { if (thread_) {
if (!thread_->isFinished()) { if (!thread_->isFinished()) {
thread_->quit(); thread_->quit();
thread_->wait(); if (!thread_->wait(maxTerminationWaitTimeMs))
thread_->terminate();
} }
thread_->deleteLater(); thread_->deleteLater();
thread_ = nullptr; thread_ = nullptr;

View File

@ -46,6 +46,9 @@ public slots:
void startWorker(bool autorelease) const; ///< Run the worker. void startWorker(bool autorelease) const; ///< Run the worker.
void releaseWorker(); ///< Delete the worker and its thread. void releaseWorker(); ///< Delete the worker and its thread.
public: // static data members
static qint64 const maxTerminationWaitTimeMs { 10000 }; ///< The maximum wait time for the termination of a thread
public: // data members. public: // data members.
QThread *thread_ { nullptr }; ///< The thread. QThread *thread_ { nullptr }; ///< The thread.
Worker *worker_ { nullptr }; ///< The worker. Worker *worker_ { nullptr }; ///< The worker.