【发布时间】:2017-10-17 16:49:35
【问题描述】:
我有一个在 docker 容器中运行的 python“设备”。它连接到 Crossbar 路由器,在订阅的频道上接收高速公路/WAMP 事件消息。
发布某个事件时,我的设备正在调用一个在几秒钟内完成的方法。 现在,我希望它在方法仍在运行时跳过或处理接收到的同一事件的任何消息。我尝试通过使用 Twisted 的 @inlinecallback 装饰器并在设备上设置“self.busy”标志来实现这一点。
但它并没有立即返回延迟,而是表现得像一个正常的阻塞方法,因此传入的消息被一个接一个地处理。
这是我的代码:
from autobahn.twisted.wamp import ApplicationSession
from twisted.internet.defer import inlineCallbacks
class Pixel(ApplicationSession):
@inlineCallbacks
def onJoin(self, details):
yield self.subscribe(self.handler_no_access, 'com.event.no_access')
@inlineCallbacks
def handler_no_access(self, direction):
entries = len(self.handlers['no_access'][direction])
if entries == 0:
self.handlers['no_access'][direction].append(direction)
result = yield self._handler_no_access()
return result
else:
yield print('handler_no_access: entries not 0: ', self.handlers['no_access'])
@inlineCallbacks
def _handler_no_access(self):
for direction in self.handlers['no_access']:
for message in self.handlers['no_access'][direction]:
yield self._timed_switch(self.direction_leds[direction], 'red', 0.2, 5)
self.handlers['no_access'][direction] = []
顺便说一句,我已经用 self.handler 字典走了一条老路。
编辑
拦截方式为:
yield self._timed_switch(self.direction_leds[direction], 'red', 0.2, 5)
它在 RaspberryPi 的 GPIO 上控制 Neopixel,让它闪烁 1 秒。对该方法的任何进一步调用
def handler_no_access(self, direction)
当 _timed_switch 没有完成时,应该被跳过,所以它们不会叠加。
解决方案
@inlineCallbacks
def handler_no_access(self, direction):
direction = str(direction)
if self.busy[direction] is False:
self.busy[direction] = True
# non-blocking now
yield deferToThread(self._handler_no_access, direction)
else:
yield print('handler_no_access: direction {} busy '.format(direction))
def _handler_no_access(self, direction):
# this takes 1s to execute
self._timed_switch(self.direction_leds[direction], 'red', 0.2, 5)
self.busy[direction] = False
【问题讨论】:
标签: python docker twisted autobahn