我有一个 ETL 程序,将会按顺序实现如下功能:
其中,第 4 步是使用 requests 来发送 post 请求到一个 NLP 分析接口实现的。现在由于数据量增加,第 4 步的网络请求成为了瓶颈,因此希望把第 4 步改成 aiohttp.
但是,由于 aiohttp 需要使用 async/await, 如果从 0 开始的话,要加入事件循环,每个相关的函数也要改为 async def 来定义,而且也难以使用 class。
单独从 0 开始使用 async/await 重写这个 ETL 程序当然没有问题,但是有没有办法以最小的代码修改量替换第 4 步操作?最好能实现 1235 步的代码都不需要改动。
1
shoaly 2019-10-24 11:08:30 +08:00
换个思路, 第四步用队列去完成
|
2
ClericPy 2019-10-24 11:17:20 +08:00
以前学习的时候实现过同步代码里使用协程
from torequests.dummy import Requests req = Requests(frequencies={'p.3.cn': (2, 2)}) tasks = [ req.get( 'http://p.3.cn', retry=1, timeout=5, callback=lambda x: (len(x.content), print(req.frequencies, flush=1))) for i in range(4) ] req.x # or [task.x for task in tasks] result = [task.cx for task in tasks] print(result) 这里的 cx 是 callback 的返回结果, 如果没有 callback, 直接使用 task.x 就有了, 和普通协程比, 性能损失倒也不算大. 不过还是习惯在全局协程里用 |
3
locoz 2019-10-24 11:21:39 +08:00
加入中间件,将第四部拆出来放到另一个程序中处理
|
4
Trim21 2019-10-24 11:27:09 +08:00 via iPhone
只在第四步里开一个事件循环,并发请求
可以考虑一下 httpx,跟 requests 是 api 兼容的, |
5
Trim21 2019-10-24 11:30:37 +08:00 via iPhone
|
6
itskingname OP @Trim21 我看一看,感谢
|
7
itskingname OP @locoz 最后没有更好的办法时,确实会使用这个办法。
|