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.
pull/3/head
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]