首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用PyTransition取消异步转换

如何用PyTransition取消异步转换
EN

Stack Overflow用户
提问于 2022-04-12 09:31:14
回答 1查看 33关注 0票数 0

我有一个排队的PyTransition状态机,有些状态在on_enter中工作。但是,我希望用户能够在任何时候停止机器而不需要等待。为此,我需要一种取消过渡的方法。

这是我现在所发现的。然而,访问_transition_queue_dict似乎是一次黑客攻击。有合适的方法吗?

代码语言:javascript
复制
#!/usr/bin/env python3

import asyncio
import logging

from transitions.extensions.asyncio import AsyncMachine

logging.getLogger('transitions').setLevel(logging.DEBUG)


class Model:
    async def do_long_work(self):
        print("Working...")
        await asyncio.sleep(10)
        print("Worked!")

    async def print_stop(self):
        print("Stopped!")

    async def interrupt(self):
        global machine
        await asyncio.sleep(1)
        for task in machine.async_tasks[id(self)]:
            task.cancel()
        machine._transition_queue_dict[id(model)].clear()

        await self.stop()

model = Model()
machine = AsyncMachine(model=model, queued=True)

machine.add_states('running', on_enter=[model.do_long_work])
machine.add_states('stopped', on_enter=[model.print_stop])
machine.add_transition('run', 'initial', 'running')
machine.add_transition('stop', 'running', 'stopped')


async def run():
    await asyncio.gather(machine.dispatch('run'), model.interrupt())

asyncio.run(run())

我使用最后一次提交主(3836dc4)。

EN

回答 1

Stack Overflow用户

发布于 2022-09-26 12:55:10

这里的问题是您传递了queued=True,它指示机器将新事件放入模型队列并依次处理事件。由于您希望能够中断事件,所以当您转换掉/退出状态时,省略queued=True或设置queued=False (默认值)将取消事件。在这种情况下,不需要修改内部队列。

代码语言:javascript
复制
import asyncio
import logging

from transitions.extensions.asyncio import AsyncMachine

logging.getLogger('transitions').setLevel(logging.DEBUG)


class Model:
    async def do_long_work(self):
        print("Working...")
        await asyncio.sleep(10)
        print("Worked!")

    async def print_stop(self):
        print("Stopped!")

    async def interrupt(self):
        await asyncio.sleep(1)
        await self.stop()


model = Model()
machine = AsyncMachine(model=model, queued=False)

machine.add_states('running', on_enter=[model.do_long_work])
machine.add_states('stopped', on_enter=[model.print_stop])
machine.add_transition('run', 'initial', 'running')
machine.add_transition('stop', 'running', 'stopped')


async def run():
    await asyncio.gather(machine.dispatch('run'), model.interrupt())

asyncio.run(run())
# Working...
# Stopped!
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71840255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档