[TransWarp] releasing component subtrees

alexander smishlajev alex at ank-sia.com
Tue Oct 21 09:56:39 EDT 2003


hello!

is there a simple and safe way to release subtrees in the component 
hierarchy?

our application from time to time is runnung tasks that should die after 
doing their job.  but my colleague found that the dead tasks remain in 
memory because of circular references between parent and child 
components that are not detected by python gc.  these cycles may be 
broken by wrapping each binding into weakref, but this would be a 
remarkable additional work.

below is a simple example.  it creates a task with two subtasks.  each 
of these tasks terminates as soon as it is run.  no reference is kept to 
the container task, but none of the tasks is garbage collected.

does anyone have any suggestions?

best wishes,
alex.

=== cut ===
import sys

from peak.api import binding, config, exceptions
from peak.running import commands, daemons

def path(component):
     return str(binding.getComponentPath(component))

class TestTask(daemons.AdaptiveTask):
     runEvery = .5
     def __start(self):
         print "MAKE %s" % path(self)
     __start = binding.Make(__start, uponAssembly=True)
     def getWork(self):
         return True
     def doWork(self, job):
         print "DONE %s" % path(self)
         raise exceptions.StopRunning
     def __del__(self):
         print "DEL %s" % path(self)

class TestContainer(TestTask):
     task1 = binding.Make(TestTask)
     task2 = binding.Make(TestTask)
     def __start(self):
         # touch contained tasks to instantiate
         self.task1
         self.task2
     __start = binding.Make(__start, uponAssembly=True)

class TestCommand(commands.EventDriven):
     stopAfter = 1
     def _run(self):
         # instantiate TestContainer, but do not keep it's reference
         # to allow the container to release itself when completed
         TestContainer(parentComponent=self, componentName="container")
         super(TestCommand, self)._run()

def main():
     TestCommand(config.makeRoot()).run()

if __name__ == "__main__":
     main()






More information about the PEAK mailing list