Have the runtime check in a loop to see if the app server is up before

opening the browser window.
This commit is contained in:
Dave Page 2013-10-04 18:16:31 +01:00
parent e120c43663
commit b022e5d347
5 changed files with 86 additions and 12 deletions

View File

@ -32,10 +32,9 @@
// Constructor // Constructor
BrowserWindow::BrowserWindow(quint16 port) BrowserWindow::BrowserWindow(QString url)
{ {
// Setup the URL the browser will connect to m_appServerUrl = url;
m_appServerUrl = QString("http://localhost:%1").arg(port);
// Setup the UI // Setup the UI
createActions(); createActions();
@ -54,7 +53,7 @@ BrowserWindow::BrowserWindow(quint16 port)
// Display the app // Display the app
m_initialLoad = true; m_initialLoad = true;
m_loadAttempt = 1; m_loadAttempt = 1;
webView->setUrl(QString("http://localhost/:%1").arg(9876)); webView->setUrl(m_appServerUrl);
} }

View File

@ -34,7 +34,7 @@ class BrowserWindow : public QMainWindow
Q_OBJECT Q_OBJECT
public: public:
BrowserWindow(quint16 port); BrowserWindow(QString url);
protected: protected:
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);

View File

@ -60,7 +60,7 @@ bool Server::Init()
if (!QFile::exists(m_appfile)) 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; return false;
} }
@ -73,7 +73,7 @@ void Server::run()
FILE *cp = fopen(m_appfile.toUtf8().data(), "r"); FILE *cp = fopen(m_appfile.toUtf8().data(), "r");
if (!cp) 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; return;
} }
@ -81,7 +81,7 @@ void Server::run()
PyRun_SimpleString(QString("PGADMIN_PORT = %1").arg(m_port).toLatin1()); PyRun_SimpleString(QString("PGADMIN_PORT = %1").arg(m_port).toLatin1());
if (PyRun_SimpleFile(cp, m_appfile.toUtf8().data()) != 0) 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); fclose(cp);
} }

View File

@ -38,7 +38,8 @@ int main(int argc, char * argv[])
QCoreApplication::setOrganizationDomain("pgadmin.org"); QCoreApplication::setOrganizationDomain("pgadmin.org");
QCoreApplication::setApplicationName(PGA_APP_NAME); 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; QTcpSocket socket;
socket.bind(0, QAbstractSocket::DontShareAddress); socket.bind(0, QAbstractSocket::DontShareAddress);
quint16 port = socket.localPort(); quint16 port = socket.localPort();
@ -50,19 +51,89 @@ int main(int argc, char * argv[])
{ {
qDebug() << server->getError(); qDebug() << server->getError();
QString error("An error occurred initialising the application server:\n\n" + server->getError()); QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
QMessageBox::critical(NULL, QString("Fatal Error"), error); QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
exit(1); exit(1);
} }
server->start(); 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 // Create & show the main window
BrowserWindow browserWindow(port); BrowserWindow browserWindow(appServerUrl);
browserWindow.show(); browserWindow.show();
// Go! // Go!
return app.exec(); 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

View File

@ -28,4 +28,8 @@
// Application name // Application name
const QString PGA_APP_NAME = QString("pgAdmin 4"); const QString PGA_APP_NAME = QString("pgAdmin 4");
// Global function prototypes
int main(int argc, char * argv[]);
bool PingServer(QUrl url);
#endif // PGADMIN4_H #endif // PGADMIN4_H