管理后台异步任务

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 swing表单配置文件中显示动态布局   swing Java使用GridLayout和鼠标交互式JPanel创建JFrame   java使用jsp dao和servlet从数据库中的4行中只插入几行   java SqlLite:我们可以选择行作为列吗?   启动glassfish服务器时java获取错误   PersistenceUnit的java部署[…]失败。关闭此PersistenceUnit的所有工厂   java将具有多个关系的实体与集合中的任何元素进行匹配   java对命名模式的建议,该模式在op失败时尝试强制转换返回null   使用jtwitter的java安卓抛出错误   使用Java方法查找数组中最小int的位置   SwingJava。网络气球提示没有出现   java无法使用JavaMail api发送邮件   java HashSet contains()为自定义对象返回false。hashCode()和equals()似乎实现正确   Java:在运行时和编译时向类中添加字段?   java正在服务类中导入jersey和JAXR,这被认为是错误的做法