From b022e5d3470d66fc46de5823736843de6bce2e82 Mon Sep 17 00:00:00 2001 From: Dave Page Date: Fri, 4 Oct 2013 18:16:31 +0100 Subject: [PATCH] Have the runtime check in a loop to see if the app server is up before opening the browser window. --- runtime/BrowserWindow.cpp | 7 ++-- runtime/BrowserWindow.h | 2 +- runtime/Server.cpp | 6 +-- runtime/pgAdmin4.cpp | 79 +++++++++++++++++++++++++++++++++++++-- runtime/pgAdmin4.h | 4 ++ 5 files changed, 86 insertions(+), 12 deletions(-) diff --git a/runtime/BrowserWindow.cpp b/runtime/BrowserWindow.cpp index 954d75fc7..4c8be721f 100644 --- a/runtime/BrowserWindow.cpp +++ b/runtime/BrowserWindow.cpp @@ -32,10 +32,9 @@ // Constructor -BrowserWindow::BrowserWindow(quint16 port) +BrowserWindow::BrowserWindow(QString url) { - // Setup the URL the browser will connect to - m_appServerUrl = QString("http://localhost:%1").arg(port); + m_appServerUrl = url; // Setup the UI createActions(); @@ -54,7 +53,7 @@ BrowserWindow::BrowserWindow(quint16 port) // Display the app m_initialLoad = true; m_loadAttempt = 1; - webView->setUrl(QString("http://localhost/:%1").arg(9876)); + webView->setUrl(m_appServerUrl); } diff --git a/runtime/BrowserWindow.h b/runtime/BrowserWindow.h index d04ff4680..eeea7be95 100644 --- a/runtime/BrowserWindow.h +++ b/runtime/BrowserWindow.h @@ -34,7 +34,7 @@ class BrowserWindow : public QMainWindow Q_OBJECT public: - BrowserWindow(quint16 port); + BrowserWindow(QString url); protected: void closeEvent(QCloseEvent *event); diff --git a/runtime/Server.cpp b/runtime/Server.cpp index fece28c58..11d1deaf0 100644 --- a/runtime/Server.cpp +++ b/runtime/Server.cpp @@ -60,7 +60,7 @@ bool Server::Init() if (!QFile::exists(m_appfile)) { - setError("Failed to locate pgAdmin4.py, terminating server thread."); + setError(tr("Failed to locate pgAdmin4.py, terminating server thread.")); return false; } @@ -73,7 +73,7 @@ void Server::run() FILE *cp = fopen(m_appfile.toUtf8().data(), "r"); if (!cp) { - setError("Failed to open the application file: " + m_appfile + ", server thread exiting."); + setError(QString(tr("Failed to open the application file: %1, server thread exiting.")).arg(m_appfile)); return; } @@ -81,7 +81,7 @@ void Server::run() PyRun_SimpleString(QString("PGADMIN_PORT = %1").arg(m_port).toLatin1()); if (PyRun_SimpleFile(cp, m_appfile.toUtf8().data()) != 0) - setError("Failed to launch the application server, server thread exiting."); + setError(tr("Failed to launch the application server, server thread exiting.")); fclose(cp); } diff --git a/runtime/pgAdmin4.cpp b/runtime/pgAdmin4.cpp index 8dd9a627d..b1b988896 100644 --- a/runtime/pgAdmin4.cpp +++ b/runtime/pgAdmin4.cpp @@ -38,7 +38,8 @@ int main(int argc, char * argv[]) QCoreApplication::setOrganizationDomain("pgadmin.org"); QCoreApplication::setApplicationName(PGA_APP_NAME); - // Find an unused port number. + // Find an unused port number. Essentially, we're just reserving one + // here that CherryPy will use when we start up the server. QTcpSocket socket; socket.bind(0, QAbstractSocket::DontShareAddress); quint16 port = socket.localPort(); @@ -50,19 +51,89 @@ int main(int argc, char * argv[]) { qDebug() << server->getError(); - QString error("An error occurred initialising the application server:\n\n" + server->getError()); - QMessageBox::critical(NULL, QString("Fatal Error"), error); + QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError()); + QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error); exit(1); } server->start(); + // Generate the app server URL + QString appServerUrl = QString("http://localhost:%1").arg(port); + + // Now the server should be up, we'll attempt to connect and get a response. + // We'll retry in a loop a few time before aborting if necessary. The browser + // will also retry - that shouldn't (in theory) be necessary, but it won't + // hurt. + int attempt = 0; + while (attempt++ < 10) + { + bool alive = PingServer(QUrl(appServerUrl)); + + if (alive) + { + break; + } + + if (attempt == 10) + { + QString error(QWidget::tr("The application server could not be contacted.")); + QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error); + + exit(1); + } + + sleep(1); + } + // Create & show the main window - BrowserWindow browserWindow(port); + BrowserWindow browserWindow(appServerUrl); browserWindow.show(); // Go! return app.exec(); } +<<<<<<< HEAD +======= +bool PingServer(QUrl url) +{ + QNetworkAccessManager manager; + QEventLoop loop; + QNetworkReply *reply; + QVariant redirectUrl; + + url.setPath("/ping"); + + do + { + reply = manager.get(QNetworkRequest(url)); + + QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); + loop.exec(); + + redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + url = redirectUrl.toUrl(); + + if (!redirectUrl.isNull()) + delete reply; + + } while (!redirectUrl.isNull()); + + if (reply->error() != QNetworkReply::NoError) + { + return false; + } + + QString response = reply->readAll(); + + if (response != "PING") + { + qDebug() << "Failed to connect, server response: " << response; + return false; + } + + return true; +} +>>>>>>> Have the runtime check in a loop to see if the app server is up before diff --git a/runtime/pgAdmin4.h b/runtime/pgAdmin4.h index f7576a157..a6b251ff4 100644 --- a/runtime/pgAdmin4.h +++ b/runtime/pgAdmin4.h @@ -28,4 +28,8 @@ // Application name const QString PGA_APP_NAME = QString("pgAdmin 4"); +// Global function prototypes +int main(int argc, char * argv[]); +bool PingServer(QUrl url); + #endif // PGADMIN4_H