Asyncio任务,将自身的副本添加到循环中

时间:2018-06-11 20:15:37

标签: python python-asyncio

我对asyncio很新,我此时无法自己解决这个问题,并且非常感谢任何帮助。

用例如下:

  • 当发送过多请求时,我需要从该限制器和黑名单中获取数据的Web服务。
  • 我需要向此Web服务发出大量数据请求
  • Web服务以分页方式发送数据,即当给定请求的数据太多时,需要进行后续请求以获取更多页面。
  • 是否需要获取更多页面可以通过检查特定请求的响应来计算出来。
  • 在客户端收到数据后,需要将其写入磁盘

所以,在我看来,设置可能如下:   - 准备了需要进行的初始请求列表   - 信号量控制每单位时间内控制限制的请求数。   - 所有初始请求都添加到循环中。   - 当收到响应时,将分派一个单独的协程(或者可能是一个线程?)来保存数据。我不希望持久性阻止获取更多数据。   - 收到响应后,将检查是否需要更多页面才能获取完整数据。如果需要更多页面,则会在循环中添加另一个任务以获取下一页。

我已经为一个最小的例子编写了一些代码,这些代码应该为我想要实现的目标提供框架:

select t.*,1+(row_number() over(order by row_id)-1)/3 as grp
from tbl t

这似乎正确地设置了信号量并运行了工作者,但它留下了几个未回答的问题:

  • 首先,如何动态添加更多工作人员(以获取后续页面)到循环中?
  • 如何处理持久性以便它不会阻止数据获取?
  • 假设多个页面需要在同一个文件中结束,我如何安全地从这些请求中收集所有数据,合并它,然后在不阻止其他数据获取请求的情况下保留?

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

  

首先,如何动态添加更多工作者(以获取后续页面)到循环中?

您可以使用asyncio.ensure_future将新协程排入事件循环。

  

如何处理持久性以便它不会阻止数据提取?

如果您正在谈论写入数据库,那么有一些库。如果您正在谈论写入文件,那么这很棘手 - 本地文件IO几乎总是阻塞,因此您必须将工作委托给单独的线程。幸运的是,asyncio为此提供了帮助:loop.run_in_executor

  

假设多个页面需要在同一个文件中结束,我如何安全地从这些请求中收集所有数据,合并它,然后在不阻止其他数据获取请求的情况下持续存在?

这开始超出SO的一个好问题的范围。您应该阅读不同的并发模式。