In the following program, what prevents the deferred "d" from being gc'd? (nothing saves the return of foo() in any variable). Do I need to keep a reference to it around to ensure the callbacks will run? #!/usr/bin/env python from twisted.internet import defer,reactor,utils def foo(): d = utils.getProcessOutput('sleep', args=['2']) def cb(data): print "cb fired" return data d.addCallback(cb) return d foo() reactor.callLater(5, reactor.stop) reactor.run() Yet when I run it, it seems everything works fine: $ ./spawner.py cb fired $ I am just questioning the need to keep deferreds in memory somewhere, if they haven't fired their callbacks yet. Thanks.
On Tue, Jul 8, 2008 at 4:11 PM, Rutt, Benjamin
#!/usr/bin/env python from twisted.internet import defer,reactor,utils
def foo(): d = utils.getProcessOutput('sleep', args=['2']) def cb(data): print "cb fired" return data d.addCallback(cb) return d
foo()
reactor.callLater(5, reactor.stop) reactor.run()
Yet when I run it, it seems everything works fine:
$ ./spawner.py cb fired $
getProcessOutput will cause a reference to be held to it. It needs that reference so it can fire the deferred once the process is complete.
I am just questioning the need to keep deferreds in memory somewhere, if they haven't fired their callbacks yet. Thanks.
Um, how will their callbacks be fired if they're not in memory any more? -- Christopher Armstrong International Man of Twistery http://radix.twistedmatrix.com/ http://twistedmatrix.com/ http://canonical.com/
Right, I was questioning the need for me, in my user code, to keep the deferred around. I now see that utils.getProcessOutput keeps a reference to the deferred it returns, so it can call it later. So there's no need for me to make a special effort for it to remain in memory in my user code. Makes sense now. Thanks.
On 08:11 pm, benjamin.rutt@gs.com wrote:
In the following program, what prevents the deferred "d" from being gc'd? (nothing saves the return of foo() in any variable). Do I need to keep a reference to it around to ensure the callbacks will run?
The reactor has a reference to a process transport. The process transport has a reference to its process protocol, specifically a twisted.internet.utils._BackRelay. The process protocol has a reference to the Deferred. When the reactor learns that there is some information available for the process transport, it relays it to the transport which relays it to the protocol which may deliver it to the Deferred. When the event fires which causes the Deferred to be called back, some of these references are broken, and it can generally be GC'd (unless there are more references or more callbacks).
I am just questioning the need to keep deferreds in memory somewhere, if they haven't fired their callbacks yet. Thanks.
I don't understand this question. If the Deferred isn't in memory, then the callback will never be called. All Deferreds which have interesting effects hang around for a while until those callbacks are called. Are you suggesting that the Deferred get written out to disk or something, so it can be removed from memory? There are a whole lot of reasons why *that* doesn't make any sense :).
participants (3)
-
Christopher Armstrong
-
glyph@divmod.com
-
Rutt, Benjamin