[Twisted-Python] RE: Write into a persistent connection before stopping

Jean-Paul Calderone exarkun at divmod.com
Mon Jan 26 10:22:45 EST 2009


On Mon, 26 Jan 2009 16:12:57 +0100, "Boeuf, Jean-Francois" <jean-francois.boeuf at eads.com> wrote:
>Hi,
>
>As i didn't get any answer to my problem i writed a little test code to
>reproduce it (I can't divulgate the production code, and then it would be to
>much complicated to expose the matter). You can just run it using twistd -y
>test.py and then connect to the 8080 tcp port with a browser. As we can see
>in the browser the connection is active and periodicaly writed. The logs
>indicate that the conections are notifyied before port and connection close,
>but the browser never receives the notification.
>
>Thanks for your help
>
>##################test.py begins here#######################
>from twisted.application import internet, service
>from twisted.internet import reactor
>from twisted.web import resource, server, static
>import threading
>
>application = service.Application("test")
>
>LISTENING   = list()
>CHECK       = threading.Event()
>
>def writeToActiveConnections():
>    while not CHECK.isSet():
>        for request in LISTENING:
>            request.write("active<br />")
>        CHECK.wait(2)
>
>def onStop():
>    print "ON STOP CALLED"
>    CHECK.set()
>    for request in LISTENING:
>        request.write("<strong>Connection closed because of server
>shutdown</strong>")
>    print "ALL CONNECTIONS HAVE BEEN NOTIFIED"
>
>def onError(_error, _request):
>    print "Connection Closed %s" % _error
>    LISTENING.remove(_request)
>
>class ListenRessource(resource.Resource):
>    def render_GET(self, _request):
>        _request.write("listen connection opened<br />")
>        LISTENING.append(_request)
>        d = _request.notifyFinish()
>        d.addCallback(LISTENING.remove, _request)
>        d.addErrback(onError, _request)
>        return server.NOT_DONE_YET
>
>class MainRessource(resource.Resource):
>    def render_GET(self, _request):
>        return """
><html>
>    <head></head>
>    <body>
>        <h1>Test page</h1>
>        <iframe src=/listen></iframe>
>    </body>
></html>
>        """
>
>class TestSite(server.Site):
>    def __init__(self):
>        root = static.File("/tmp")
>        root.putChild("test", MainRessource())
>        root.putChild("listen", ListenRessource() )
>        server.Site.__init__(self, root)
>
>class TestService(internet.TCPServer):
>    def __init__(self):
>        internet.TCPServer.__init__(
>            self,
>            8080,
>            TestSite()
>        )
>        reactor.callInThread(writeToActiveConnections)
>        reactor.addSystemEventTrigger('before', 'shutdown', onStop)
>
>TestService().setServiceParent(application)

Twisted APIs are generally not safe to be invoked from any thread except
for the thread in which the reactor is running.

If you want to run some code periodically, don't do it with threads and
events, do it with reactor.callLater or twisted.internet.task.LoopingCall.

Jean-Paul




More information about the Twisted-Python mailing list