Find a random port number to use for the application server to avoid conflicts

with any other apps that may have already bound to the default port used by CP.
This commit is contained in:
Dave Page 2013-10-04 17:12:10 +01:00
parent a1524f3726
commit 457a842cec
7 changed files with 64 additions and 38 deletions

View File

@ -32,8 +32,12 @@
// Constructor
BrowserWindow::BrowserWindow()
BrowserWindow::BrowserWindow(quint16 port)
{
// Setup the URL the browser will connect to
m_appServerUrl = QString("http://localhost:%1").arg(port);
// Setup the UI
createActions();
createMenus();
@ -48,9 +52,9 @@ BrowserWindow::BrowserWindow()
restoreState(settings.value("windowState").toByteArray());
// Display the app
m_initialload = true;
m_loadattempt = 1;
webView->setUrl(PGA_SERVER_URL);
m_initialLoad = true;
m_loadAttempt = 1;
webView->setUrl(QString("http://localhost/:%1").arg(9876));
}
@ -106,43 +110,38 @@ void BrowserWindow::createMenus()
// Process loading finished signals from the web view.
void BrowserWindow::finishLoading(bool ok)
{
if (m_initialload && !ok)
if (m_initialLoad && !ok)
{
// The load attempt failed. Try again up to 4 times with an
// incremental backoff.
if (m_loadattempt < 5)
if (m_loadAttempt < 5)
{
qDebug() << "Initial load failed. Retrying in" << m_loadattempt << "seconds.";
if (m_loadattempt == 1)
if (m_loadAttempt > 1)
{
webView->setHtml(tr("<p>Connecting...</p>"));
qDebug() << "Initial connection failed. Retrying in" << m_loadAttempt << "seconds.";
webView->setHtml(QString(tr("<p>Failed to connect to the pgAdmin application server. Retrying in %1 seconds, ") +
tr("or click <a href=\"%2\">here</a> to try again now.</p>")).arg(m_loadAttempt).arg(m_appServerUrl));
}
else
{
webView->setHtml(QString(tr("<p>Failed to connect to the pgAdmin application server. Retrying in %1 seconds, ") +
tr("or click <a href=\"%2\">here</a> to try again now.</p>")).arg(m_loadattempt).arg(PGA_SERVER_URL));
webView->setHtml(QString(tr("<p>Connecting to the application server...</p>")));
}
pause(m_loadattempt);
webView->setUrl(PGA_SERVER_URL);
// Even if the server comes up while we're looping, Linux won't
// properly display the HTML data unless we explicitly process events.
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
pause(m_loadAttempt);
webView->setUrl(m_appServerUrl);
m_loadAttempt++;
m_loadattempt++;
return;
}
else
{
qDebug() << "Initial page load failed after multiple attempts. Aborting.";
qDebug() << "Initial connection failed after multiple attempts. Aborting.";
webView->setHtml(QString(tr("<p>Failed to connect to the pgAdmin application server. ") +
tr("Click <a href=\"%1\">here</a> to try again.</p>")).arg(PGA_SERVER_URL));
tr("Click <a href=\"%1\">here</a> to try again.</p>")).arg(m_appServerUrl));
}
}
m_initialload = false;
m_initialLoad = false;
}

View File

@ -34,7 +34,7 @@ class BrowserWindow : public QMainWindow
Q_OBJECT
public:
BrowserWindow();
BrowserWindow(quint16 port);
protected:
void closeEvent(QCloseEvent *event);
@ -47,6 +47,7 @@ private slots:
void about();
private:
QString m_appServerUrl;
QWebView *webView;
QMenu *fileMenu;
QMenu *helpMenu;
@ -54,8 +55,8 @@ private:
QAction *exitAction;
QAction *aboutAction;
bool m_initialload;
int m_loadattempt;
bool m_initialLoad;
int m_loadAttempt;
void createActions();
void createMenus();

View File

@ -22,8 +22,11 @@
// App headers
#include "Server.h"
Server::Server()
Server::Server(quint16 port)
{
// Appserver port
m_port = port;
// Initialise Python
Py_SetProgramName(PGA_APP_NAME.toUtf8().data());
Py_Initialize();
@ -74,6 +77,9 @@ void Server::run()
return;
}
// Set the port number
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.");

View File

@ -23,7 +23,7 @@ class Server : public QThread
Q_OBJECT
public:
Server();
Server(quint16 port);
~Server();
bool Init();
@ -37,6 +37,8 @@ private:
QString m_appfile;
QString m_error;
quint16 m_port;
};
#endif // SERVER_H

View File

@ -38,13 +38,17 @@ int main(int argc, char * argv[])
QCoreApplication::setOrganizationDomain("pgadmin.org");
QCoreApplication::setApplicationName(PGA_APP_NAME);
// Find an unused port number.
QTcpSocket socket;
socket.bind(0, QAbstractSocket::DontShareAddress);
quint16 port = socket.localPort();
// Fire up the webserver
// TODO: Find an unused port number to use
Server *server = new Server();
Server *server = new Server(port);
if (!server->Init())
{
qDebug() << server->getError();
qDebug() << server->getError();
QString error("An error occurred initialising the application server:\n\n" + server->getError());
QMessageBox::critical(NULL, QString("Fatal Error"), error);
@ -55,11 +59,10 @@ int main(int argc, char * argv[])
server->start();
// Create & show the main window
BrowserWindow browserWindow;
BrowserWindow browserWindow(port);
browserWindow.show();
// Go!
return app.exec();
}

View File

@ -28,7 +28,4 @@
// Application name
const QString PGA_APP_NAME = QString("pgAdmin 4");
// Server URL
const QString PGA_SERVER_URL = QString("http://127.0.0.1:8080");
#endif // PGADMIN4_H

View File

@ -7,11 +7,14 @@ includedir = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect
if includedir not in sys.path:
sys.path.insert(0, includedir)
# Do some stuff
# Rock n' roll...
import cherrypy
from time import time,ctime
class HelloWorld(object):
# This is the main application class that we'll run under CherryPy. For now,
# we'll just output some basic HTML so we can see that everything is running.
class pgAdmin4(object):
def index(self):
output = """
Today is <b>%s</b>
@ -21,6 +24,21 @@ Today is <b>%s</b>
<a href="http://www.pgadmin.org/">pgAdmin 4</a>""" % ctime(time())
return output
index.exposed = True
cherrypy.quickstart(HelloWorld())
# Start the web server. The port number should have already been set by the
# runtime if we're running in desktop mode, otherwise we'll just use the
# CherryPy default.
try:
cherrypy.server.socket_port = PGADMIN_PORT
except:
pass
try:
cherrypy.quickstart(pgAdmin4())
except IOError:
print "Unexpected error: ", sys.exc_info()[0]