web interface
Jean-Paul Calderone
exarkun at divmod.com
Wed Nov 9 14:50:03 EST 2005
On Wed, 9 Nov 2005 19:08:28 +0000, Tom Anderson <twic at urchin.earth.li> wrote:
>On Mon, 7 Nov 2005, Ajar wrote:
>
>> I have a stand alone application which does some scientific
>> computations. I want to provide a web interface for this app. The app is
>> computationally intensive and may take long time for running. Can
>> someone suggest me a starting point for me? (like pointers to the issues
>> involved in this,
>
>You're probably best off starting a new process or thread for the
>long-running task, and having the web interface return to the user right
>after starting it; you can then provide a second page on the web interface
>where the user can poll for completion of the task, and get the results if
>it's finished. You can simulate the feel of a desktop application to some
>extent by having the output of the starter page redirect the user to the
>poller page, and having the poller page refresh itself periodically.
>
>What you really want is a 'push' mechanism, by which the web app can
>notify the browser when the task is done, but, despite what everyone was
>saying back in '97, we don't really have anything like that.
Yea, there's no way something like this will work:
# push.tac
from zope.interface import Interface, implements
from twisted.internet import defer, reactor
from twisted.application import service, internet
from nevow import appserver, loaders, tags, rend, athena
class ICalculator(Interface):
def add(x, y):
"""
Add x and y. Return a Deferred that fires with the result.
"""
class Adder(object):
implements(ICalculator)
def add(self, x, y):
# Go off and talk to a database or something, I don't know. We'll
# pretend something interesting is happening here, but actually all
# we do is wait a while and then return x + y.
d = defer.Deferred()
reactor.callLater(5, d.callback, x + y)
return d
class LongTaskPage(athena.LivePage):
docFactory = loaders.stan(tags.html[
tags.head[
tags.directive('liveglue'),
tags.title['Mystical Adding Machine of the Future'],
tags.script(type="text/javascript")["""
/* onSubmit handler for the form on the page: ask the server
* to add two numbers together. When the server sends the
* result, stick it into the page.
*/
function onAdd(x, y) {
var d = server.callRemote('add', x, y);
var resultNode = document.getElementById('result-node');
d.addCallback(function(result) {
resultNode.innerHTML = String(result);
});
d.addErrback(function(err) {
var s = "Uh oh, something went wrong: " + err + ".";
resultNode.innerHTML = s
});
resultNode.innerHTML = "Thinking...";
return false;
}""",
],
],
tags.body[
tags.form(onsubmit="return onAdd(this.x.value, this.y.value);")[
tags.input(type="text", name="x"),
"+",
tags.input(type="text", name="y"),
"=",
tags.span(id="result-node")[
tags.input(type="submit"),
],
],
],
])
class Root(rend.Page):
docFactory = loaders.stan(tags.html[
tags.head[
tags.meta(**{"http-equiv": "refresh", "content": "0;calc"})]])
def child_calc(self, ctx):
return LongTaskPage(ICalculator, Adder())
application = service.Application("Push Mechanism, like back in '97")
webserver = internet.TCPServer(8080, appserver.NevowSite(Root()))
webserver.setServiceParent(application)
# eof
Right? But maybe you can explain why, for those of us who aren't enlightened.
Jean-Paul
More information about the Python-list
mailing list