处理来自autobahn订阅的消息时异步、非阻塞的程序

2024-10-06 12:04:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个python“设备”在docker容器中运行。它连接到一个纵横制路由器,在订阅的频道上接收高速公路/WAMP事件消息。你知道吗

当某个事件发布时,我的设备正在调用一个在几秒钟内完成的方法。 现在,我希望它在方法仍在运行时跳过或处理接收到的同一事件的任何消息。我试图通过使用Twisted的@inlinecallback decorator并设置自己忙“-设备上的标志。你知道吗

但是它并没有立即返回一个延迟的消息,相反,它的行为就像一个普通的阻塞方法,所以传入的消息会被一个接一个地处理。你知道吗

这是我的密码:

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] = []

我已经走了这条老路自我管理者顺便说一下,字典。你知道吗

编辑

阻塞方法为:

yield self._timed_switch(self.direction_leds[direction], 'red', 0.2, 5)

它控制一个RaspberryPi的GPIOs上的neopix,让它闪烁1s

def handler_no_access(self, direction)

当\u定时\u开关还没有完成时,应该跳过,这样它们就不会堆积起来。你知道吗

解决方案

@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

Tags: 方法noself消息accesshandlersdef事件
1条回答
网友
1楼 · 发布于 2024-10-06 12:04:34

inlineCallbacks不会将阻塞代码变成非阻塞代码。它只是使用延迟的另一个API。延期只是管理回调的一种方式。你知道吗

你需要重写你的阻塞代码,使之以其他方式成为非阻塞代码。实际上,您还没有说代码的哪一部分被阻塞,也没有说它阻塞了什么,所以很难建议您如何执行此操作。将阻塞代码转换为非阻塞代码的两个通用工具是线程和进程。因此,您可以在单独的线程或进程中运行该函数。函数可能在这样的执行上下文中工作,也可能不工作(同样,如果不确切知道它做什么,就无法知道)。你知道吗

相关问题 更多 >