如何在rust中调用腾讯&百度的翻译服务
阅读本篇博客后,您将掌握关于Tokio库实现批量任务处理的实用技巧,并了解如何有效地进行并发限制。
背景
在开发ComfyUI Startup插件管理和模型管理功能的过程中,我发现对模型数据和插件数据的需求。在研究ComfyUI Manager如何实现将模型下载至特定目录时,我注意到其仓库中包含的数据文件仅提供英文版本。为了满足国际化需求,我决定着手翻译这些数据文件。然而,显然逐一手动翻译并不现实。因此,我选择利用tokio
和reqwest
库调用百度或腾讯的翻译API,以自动化的方式进行翻译工作。
先实现一个翻译请求的调用
1 | rust复制代码use crate::CLIENT; |
然后再实现批量调用
起初,我设想采用for循环逐个调用的方式实现功能,但这种方式未能充分利用Tokio框架提供的高并发特性。这一思考受到了TypeScript编程经验的影响,在TypeScript中,Promise会在定义后立即执行,而Rust语言中的Future则不同,它们仅在遇到await表达式时才会真正执行其异步操作。因此,为了适应Rust及Tokio的异步编程模型,我们需要采取更恰当的方式来调度并发任务以发挥其优势。
1 | rust复制代码pub async fn run<P: AsRef<Path>>( |
第二版本,使用join_all来批量执行
1 | rust复制代码pub async fn run2<P: AsRef<Path>>( |
这里将数据转换成批量异步任务,再使用join_all来等待他们所有执行完成。
其实这里有更好的方法就是使用futures::stream::FuturesUnordered
,这里为了简便就使用了join_all。
并发限制
在实践高并发场景时,我发现百度API存在一定的调用频率限制,即每秒允许的请求次数有限制。因此,为了避免超出限制,我不得不对并发任务进行控制。鉴于这种情况下的时间敏感性,我没有选择使用tokio::sync::Semaphore
作为并发限制工具,而是采用了批量分时执行策略:将任务划分为多个批次,每一批次之间的执行间隔为3秒,确保每批任务在前一批次执行满3秒后才开始执行,从而符合接口调用频率要求。
1 | rust复制代码pub async fn run<P: AsRef<Path>>( |
上面代码在我的GitHub translate
目录中,如果觉得有用,请给我点个赞吧,另外也恳请您为我的仓库点个Star,谢谢客官老爷。
本文转载自: 掘金