I am new to twisted and I am trying to understand the design patterns for asynchronous prog开发者_如何学运维ramming in general and twisted in particular. From a design standpoint, is it a good idea to access the reactor from a Protocol subclass as follows:
class A(Protocol):
def __init__(self):
reactor.callLater(5, function_not_defined_here)
Yes, that's absolutely standard. You can call reactor methods from anywhere in your application (pre or post reactor.run()
). The only exception being when using threads, in which case you'll want to wrap your reactor method calls in reactor.callFromThread()
, eg:
reactor.callFromThread(reactor.callLater, 5, function_not_defined_here)
You might consider several adjustments to this:
- Accept the
reactor
as an argument. This makes your code more easily testable, since it means you can pass in a fake reactor in your unit tests which is independent of real time and can be inspected to verifyA
behaves as intended. - Don't discard the result of
reactor.callLater
. Save it as an attribute on theA
instance so that you can use it later if necessary. For example, you may want to cancel it (consider the case where theA
instance loses its connection before the delayed call runs). - Don't call
reactor.callLater
inA.__init__
. Instead, call it inA.connectionMade
. This one depends a bit on why you're using a delayed call at all, but it's much more likely that you want to do something some time after the connection is established, rather than some time after the protocol is instantiated. This also lets you have anA
instance that isn't messing around with the reactor yet (which is another thing you might want to do in your unit tests).
精彩评论