[Twisted-web] [Athena] Is ReliableMessageDelivery really necessary?

Paul Thomas spongelavapaul at googlemail.com
Mon Dec 7 17:16:44 EST 2009


On 1 Jul 2009, at 22:45, Jean-Paul Calderone wrote:

> On Wed, 1 Jul 2009 11:15:35 +0100, Paul Thomas <spongelavapaul at googlemail.com 
> > wrote:
>> Hi,
>>
>> I've hit a problem as my app has got bigger (about 30-40 widgets  
>> now,  all
>> chattering roughly once every 2 seconds) where the reliable  message
>> delivery mechanism is spiralling out of control. It seems that  the  
>> constant
>> back and forth means that large 'baskets' of messages are  resent.  
>> The more
>> this happens, the busier everything gets until the  browser becomes
>> unresponsive.
>
> If you can produce a minimal example which demonstrates this  
> behavior, it
> would probably be very helpful in improving the situation.

It's been quite some time, but I may have time to look into this soon  
(meaning in the next few months).

I have a minimal example code, but it's a bit big - does this need to  
be in a ticket somewhere?

Paul.

8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
// resources/css/test1.css

#workspace > div {
     display: inline-block;
     margin: 10px;
     padding: 5px;
     border: 1px solid black;
}

#workspace > div p {
     margin: 0;
     padding: 0;
     font-size: 10pt;
}

h3 {
     font-size: 12pt;
     margin: 0;
     padding: 0;
}
8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
// resources/js/widgets/Status.js

// import Divmod
// import Nevow.Athena

Nevow.Athena.Widget.subclass(Status, 'SimpleStatus').methods(
     function __init__(self, node) {
         Status.SimpleStatus.upcall(self, '__init__', node);
         self.contentP = node.getElementsByTagName("p")[0];
         self.count = 0
     },

     function update(self, count) {
         self.contentP.innerHTML = "T: " + count;
         if( count != self.count + 1 ){
             self.node.style.background = "red";
         }
         self.count = count

     }
);
8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
// test1.py
from os import path
from logging import getLogger, basicConfig, INFO, DEBUG, WARN
from random import random

from twisted.internet import reactor
from twisted.python.log import ILogObserver, PythonLoggingObserver

from nevow.athena import LivePage, LiveElement, AutoJSPackage, expose,  
renderer
from nevow import loaders, tags as T, static

#from guppy import hpy
#h = hpy()

basicConfig(level=DEBUG)
#heap_log = getLogger('heap')
#getLogger('twisted').setLevel(WARN)

def heap_poll():
     heap_log.debug("==== HEAP =====")
     heap_log.debug(h.heap())
     reactor.callLater(5, heap_poll)

#reactor.callWhenRunning(heap_poll)

_RESOURCE_DIR = path.join(path.dirname(path.abspath(__file__)),  
'resources')

log = getLogger('comet-test1')

class SimpleStatus(LiveElement):
     jsClass = u'Status.SimpleStatus'
     docFactory = loaders.stan(T.div(render=T.directive('liveElement'),
                                     class_='widget')[
         T.div(class_='widget-header', render=T.directive('title')),
         T.div(class_='widget-editbox'),
         T.div(class_='widget-content')[
             T.p['None']]])

     def __init__(self, id):
         super(SimpleStatus, self).__init__()
         self.num = id
         self.count = 0
         reactor.callLater(int(random() * 2 + 1), self._poll)

     def _poll(self):
         self.count += 1
         self.callRemote('update', self.count)
         reactor.callLater(random() * 2 + 1, self._poll)

     @renderer
     def title(self, req, tag):
         return tag[T.h3['Widget %d' % self.num]]

     @expose
     def getSomething(self, name):
         log.debug('getSomething(%r)' % name)
         return 'Not sure'

class Root(LivePage):
     docFactory = loaders.stan(
         T.html[
             T.head(render=T.directive('liveglue'))[
                 T.title['Comet Test 1'],
                 T.link(rel='stylesheet', type='text/css',
                        href='css/test1.css')],
             T.body[
                 T.div(id='workspace', class_='widget-place')[
                     [T.div(render=T.directive('simpleStatus'))] * 50
                 ]]])
     addSlash = True

     children = {
         'css': static.File(path.join(_RESOURCE_DIR,'css')),
         'js': static.File(path.join(_RESOURCE_DIR,'js'))}

     def __init__(self):
         super(Root, self).__init__()
         self.jsModules.mapping.update(AutoJSPackage(path.join(
             _RESOURCE_DIR,'js','widgets')).mapping)
         log.info(str(self.jsModules.mapping))
         self.next_id = 1

     def child_(self, ctx):
         return Root()

     def render_simpleStatus(self,ctx,data):
         f = SimpleStatus(self.next_id)
         self.next_id += 1
         f.setFragmentParent(self)
         return ctx.tag[f]

from nevow import appserver
from twisted.application import service, internet

site = appserver.NevowSite(Root())

application = service.Application("Test 1")
webService = internet.TCPServer(8080, site)
webService.setServiceParent(application)

application.setComponent(ILogObserver, PythonLoggingObserver().emit)




More information about the Twisted-web mailing list