管理后台异步任务

aionurser的Python项目详细描述


https://travis-ci.com/malinoff/aionursery.svg?branch=masterhttps://codecov.io/gh/malinoff/aionursery/branch/master/graph/badge.svg

这个库实现了一个托儿所对象,类似于trio的Nurseryfor asyncio

asyncdefchild():...asyncdefparent():asyncwithaionursery.Nursery()asnursery:# Make two concurrent calls to childnursery.start_soon(child())nursery.start_soon(child())

任务形成一棵树:当您运行主协同程序(通过asyncio.get_event_loop().run_until_completeasyncio.run)时,这将创建一个初始任务,并且所有其他任务都将是主任务的子任务、孙子任务等。

async with块的主体类似于在托儿所内运行的初始任务,然后对nursery.start_soon的每次调用都会添加另一个并行运行的任务。

请记住:

  • 如果托儿所内的任何任务引发未处理的异常,则托儿所立即取消托儿所内的所有任务。
  • 由于所有任务都在块中异步运行,所以在所有任务完成之前,块不会退出。如果您使用过其他并发框架,那么可以将其视为异步结束时的取消缩进,并自动“连接”(等待)托儿所中的所有任务。
  • 所有任务完成后,然后: *托儿所被标记为“关闭”,这意味着不能在其中启动新任务。 *所有未处理的异常都会在父任务内部重新引发。如果存在多个异常,则它们将被收集到单个多错误异常中。

由于所有任务都是初始任务的子代,因此这会导致父任务在所有任务完成之前无法完成。

请注意,不能重用已退出的托儿所。再次尝试重新打开它,或在其中start_soon更多任务将引发NurseryClosed

阻止取消某些任务

然而,有时需要有相反的行为:无论在其他任务中引发了什么异常,子任务都必须执行。 想象一个支付交易在一个任务中运行,而一个短信在另一个任务中发送。 您当然不希望短信发送错误取消支付交易。

为此,您可以asyncio.shield在托儿所开始您的任务:

asyncdefperform_payment():...asyncdefsend_sms():...asyncdefparent():asyncwithNursery()asnursery:nursery.start_soon(asyncio.shield(perform_payment()))nursery.start_soon(send_sms())

从孩子那里得到结果

如果您的后台任务不是很长,并且返回一些您想要处理的有用值,那么您可以将所有任务收集到一个列表中,并像往常一样使用asyncio.wait(或类似的函数):

asyncdefparent():asyncwithNursery()asnursery:task_foo=nursery.start_soon(foo())task_bar=nursery.start_soon(bar())results=awaitasyncio.wait([task_foo,task_bar])

如果后台任务是长寿命的,则应使用asyncio.Queue在子任务和父任务之间传递对象:

asyncdefchild(queue):whileTrue:data=awaitfrom_external_system()awaitqueue.put(data)asyncdefparent():queue=asyncio.Queue()asyncwithNursery()asnursery:nursery.start_soon(child(queue))whilesome_condition():data=awaitqueue.get()awaitdo_stuff_with(data)

async_timeout

集成

您可以在async_timeout.timeout上下文管理器中包装托儿所。 超时时,整个托儿所取消:

fromasync_timeoutimporttimeoutasyncdefchild():awaitasyncio.sleep(1000*1000)asyncdefparent():asyncwithtimeout(10):asyncwithNursery()asnursery:nursery.start_soon(child())awaitasyncio.sleep(1000*1000)

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java使用测试类查看两个整数值是否适合参数   java Apache Tomcat 7域问题代理设置   java排序从程序计算的分数   java发送批量通知,希望决定调度程序的时间频率   避免全局状态的REST服务器java存储和加载配置(即单例与上下文、依赖注入)   单击按钮时的java选择方法   java Sringboot日志文件与logbakspring一起工作不正常。xml   java为什么匕首注入不起作用,而是组件。getObject是   java一个表达式包含“最多一个副作用,作为其最外层的操作”,这意味着什么?   java如何从文本文件读取/加载此HashMap?   java如何从菜单处理程序重新实例化零件类?   计划任务如何使用在不同机器上运行的多个java程序访问同一个表而不会出现死锁   多线程循环的java效率   java使用已经获取的MySQL数据行向DIV追加新的MySQL数据   java允许不带引号的soap操作JAXWS