wingo - in flumotion/trunk: . flumotion/common flumotion/component
flumotion/test
flumotion-commit at lists.fluendo.com
flumotion-commit at lists.fluendo.com
Tue Jul 24 12:56:20 CEST 2007
Author: wingo
Date: Tue Jul 24 12:46:51 2007
New Revision: 5347
Modified:
flumotion/trunk/ChangeLog
flumotion/trunk/flumotion/common/debug.py
flumotion/trunk/flumotion/component/feed.py
flumotion/trunk/flumotion/test/test_component_feed.py
Log:
2007-07-24 Andy Wingo <wingo at pobox.com>
* flumotion/component/feed.py (FeedMedium.stopConnecting): Drop
any remote reference, just in case.
(FeedMedium._doFeedTo): Drop the remote reference after the pb
handshaking is finished and the transport is closed. Fixes
uncollectable object leaks when reconnecting feeds.
* flumotion/common/debug.py (AllocMonitor.analyze)
(AllocMonitor._printCycle, AllocMonitor._printParents)
(AllocMonitor._printKids): More informative printing of object
cycles.
* flumotion/test/test_component_feed.py (TestUpstreamFeedClient):
Add assertions regarding the state of the feedmedium's reference
to the RemoteReference.
Modified: flumotion/trunk/ChangeLog
==============================================================================
--- flumotion/trunk/ChangeLog (original)
+++ flumotion/trunk/ChangeLog Tue Jul 24 12:46:51 2007
@@ -1,3 +1,20 @@
+2007-07-24 Andy Wingo <wingo at pobox.com>
+
+ * flumotion/component/feed.py (FeedMedium.stopConnecting): Drop
+ any remote reference, just in case.
+ (FeedMedium._doFeedTo): Drop the remote reference after the pb
+ handshaking is finished and the transport is closed. Fixes
+ uncollectable object leaks when reconnecting feeds.
+
+ * flumotion/common/debug.py (AllocMonitor.analyze)
+ (AllocMonitor._printCycle, AllocMonitor._printParents)
+ (AllocMonitor._printKids): More informative printing of object
+ cycles.
+
+ * flumotion/test/test_component_feed.py (TestUpstreamFeedClient):
+ Add assertions regarding the state of the feedmedium's reference
+ to the RemoteReference.
+
2007-07-24 Michael Smith <msmith at fluendo.com>
* flumotion/component/feedcomponent010.py:
Modified: flumotion/trunk/flumotion/common/debug.py
==============================================================================
--- flumotion/trunk/flumotion/common/debug.py (original)
+++ flumotion/trunk/flumotion/common/debug.py Tue Jul 24 12:46:51 2007
@@ -179,7 +179,27 @@
else:
self.allocPrint(p, allocators[p])
import gc
- print '\ngc.garbage:', gc.garbage
+ for o in gc.garbage:
+ print '\nUncollectable object cycle in gc.garbage:'
+ self._printCycle(new[id(o)])
+
+ def _printCycle(self, root):
+ print "Parents:"
+ self._printParents(root, 2)
+ print "Kids:"
+ self._printKids(root, 2)
+
+ def _printParents(self, wrap, level, indent=' '):
+ print indent, self._wrapperRepr(wrap)
+ if level > 0:
+ for p in wrap.parents:
+ self._printParents(p, level - 1, indent + ' ')
+
+ def _printKids(self, wrap, level, indent=' '):
+ print indent, self._wrapperRepr(wrap)
+ if level > 0:
+ for kid in wrap.children:
+ self._printKids(kid, level - 1, indent + ' ')
def _allocStack(self, wrap, stack):
stack.append(wrap)
Modified: flumotion/trunk/flumotion/component/feed.py
==============================================================================
--- flumotion/trunk/flumotion/component/feed.py (original)
+++ flumotion/trunk/flumotion/component/feed.py Tue Jul 24 12:46:51 2007
@@ -191,6 +191,9 @@
if self._factory:
self._factory.disconnect()
self._factory = None
+ # not sure if this is necessary; call it just in case, so we
+ # don't leave a lingering reference cycle
+ self.setRemoteReference(None)
### IMedium methods
def setRemoteReference(self, remoteReference):
@@ -239,6 +242,10 @@
# on the transport.
t.connectionLost(failure.Failure(main.CONNECTION_DONE))
+ # This medium object is of no use any more; drop our reference
+ # to the remote so we can avoid cycles.
+ self.setRemoteReference(None)
+
(flowName, componentName, feedName) = common.parseFullFeedId(fullFeedId)
feedId = common.feedId(componentName, feedName)
Modified: flumotion/trunk/flumotion/test/test_component_feed.py
==============================================================================
--- flumotion/trunk/flumotion/test/test_component_feed.py (original)
+++ flumotion/trunk/flumotion/test/test_component_feed.py Tue Jul 24 12:46:51 2007
@@ -143,6 +143,8 @@
client = feed.FeedMedium(component)
factory = feed.FeedClientFactory(client)
+ self.failIf(client.hasRemoteReference())
+
def login():
port = self.feedServer.getPortNum()
self.assertAdditionalFDsOpen(1, 'connect (socket)')
@@ -152,6 +154,9 @@
password='test'))
def cleanup(res):
+ # We're not using requestFeed, so no reference should be set
+ self.failIf(client.hasRemoteReference())
+
self.assertAdditionalFDsOpen(3, 'cleanup (socket, client, server)')
factory.disconnect()
@@ -179,6 +184,8 @@
client = feed.FeedMedium(component)
factory = feed.FeedClientFactory(client)
+ self.failIf(client.hasRemoteReference())
+
def login():
port = self.feedServer.getPortNum()
self.assertAdditionalFDsOpen(1, 'connect (socket)')
@@ -189,7 +196,9 @@
def sendFeed(remote):
# apparently one has to do magic to get the feed to work
+ self.failIf(client.hasRemoteReference())
client.setRemoteReference(remote)
+ self.failUnless(client.hasRemoteReference())
self.assertAdditionalFDsOpen(3, 'feed (socket, client, server)')
return remote.callRemote('sendFeed', '/foo/bar:baz')
@@ -212,6 +221,9 @@
# this likely fires directly, not having dropped into the
# reactor.
+ # The feed medium should have dropped its reference already
+ self.failIf(client.hasRemoteReference())
+
# this fd is not ours, we should dup it if we want to hold
# onto it
return self.feedServer.waitForAvatarExit()
@@ -265,6 +277,9 @@
# this likely fires directly, not having dropped into the
# reactor.
+ # The feed medium should have dropped its reference already
+ self.failIf(client.hasRemoteReference())
+
# this fd is not ours, we should dup it if we want to hold
# onto it
return self.feedServer.waitForAvatarExit()
@@ -324,6 +339,8 @@
def testRequestFeed(self):
client = feed.FeedMedium(logName='frobby')
+ self.failIf(client.hasRemoteReference())
+
def requestFeed():
port = self.feedServer.getPortNum()
self.assertAdditionalFDsOpen(1, 'connect (socket)')
@@ -331,10 +348,17 @@
fpb.Authenticator(username='user',
password='test'),
'/foo/bar:baz')
+ self.failIf(client.hasRemoteReference())
self.assertAdditionalFDsOpen(2, 'connect (socket, client)')
return d
def gotFeed((feedId, fd)):
+ # the feed medium should have dropped its reference to the
+ # remotereference by now, otherwise we get cycles, and
+ # remote references can't exist in cycles because they have
+ # a __del__ method
+ self.failIf(client.hasRemoteReference())
+
self.assertEquals(feedId, 'bar:baz')
self.assertAdditionalFDsOpen(3, 'cleanup (socket, client, server)')
# our responsibility to close fd
More information about the flumotion-commit
mailing list