开发者

Using twisted.internet.reactor inside a Protocol subclass

开发者 https://www.devze.com 2023-03-15 07:28 出处:网络
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

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 verify A behaves as intended.
  • Don't discard the result of reactor.callLater. Save it as an attribute on the A instance so that you can use it later if necessary. For example, you may want to cancel it (consider the case where the A instance loses its connection before the delayed call runs).
  • Don't call reactor.callLater in A.__init__. Instead, call it in A.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 an A instance that isn't messing around with the reactor yet (which is another thing you might want to do in your unit tests).
0

精彩评论

暂无评论...
验证码 换一张
取 消