Athena - browser memory leak

Mick O'Doherty <[email protected]> Thu, 1 Jul 2010 18:04:43 +0100
Newsgroups gmane.comp.python.quotient.dev
Message-ID <[email protected]>
Hi,

I have seen memory leak issues in an application built  using Nevow  
Athena, so decided to go back to the basic tutorial example at the  
link below to check that:

http://divmod.org/trac/wiki/DivmodNevow/Athena/Tutorials/LiveElement

I noted that when I run this (with no changes other than absolute path  
in mymodule_pkg.py - files downloaded from the page above) this  
appears to also have memory leak issues with Internet Explorer (IE8)  
and Firefox (3.6.3) both running on Windows XP - if you open the task  
manager and repeatedly hit the 'PUSH" button you will see memory  
slowly creep up.

I then modified the code to repeatedly send some info to the browser  
to simulate a use case where the browser remains on the same page and  
is regularly updated via 'COMET' type push messages. This causes even  
more alarming memory increases in IE8 and in Firefox. The modified  
code is:

mymodule.js:
// import Nevow.Athena

MyModule = {};

MyModule.MyWidget = Nevow.Athena.Widget.subclass('MyModule.MyWidget');

MyModule.MyWidget.method(
     'echo',
     function(self, argument) {
         document.getElementById('athenaid:1-messageArea').innerHTML =  
'<p>Message received: '+ argument + '</p>'
         return argument;
     });

MyModule.MyWidget.method(
     'clicked',
     function(self) {
         self.callRemote('echo', 'hello, world');
     });


And updated MyElement class in myelement.tac (you also need to add an  
import for task from twisted.internet at the top):

class MyElement(athena.LiveElement):
     jsClass = u'MyModule.MyWidget'
     counter = 0

     docFactory = loaders.stan(T.div(render=T.directive('liveElement'))[
         T.div(id="messageArea")[1],
         T.input(type="submit", value="Push me",  
onclick='Nevow.Athena.Widget.get(this).clicked()')])

     def __init__(self, *a, **kw):
         super(MyElement, self).__init__(*a, **kw)
         reactor.callLater(1, self.startEventTask)

     def startEventTask(self):
         self.myEventTask = task.LoopingCall(self.myEvent)
         self.myEventTask.start(1.0)

     def myEvent(self):
         print 'My Event Firing'
         self.counter = self.counter + 1
         self.callRemote('echo', self.counter)

     def echo(self, argument):
         print 'Echoing', argument
         return argument
     athena.expose(echo)

Is anyone aware of this issue and are there any know solutions or  
workarounds?

Cheers,

Mick