使用标准对 actix_web api 进行基准测试时遇到问题

问题描述

我一直在尝试使用 Criterion 板条箱向我的 actix_web 应用程序添加基准测试。我一直在努力让它工作,因为 AsyncExecutor 特征没有为 tokio 0.2.x 实现。我尝试为 actix_rt 运行时实现 trait,但也遇到了问题,代码如下

impl AsyncExecutor for ActixRuntime {
    fn block_on<T>(&self,future: impl Future<Output=T>) -> T {
        self.rt.block_on(future)
    }
}

pub struct ActixRuntime {
    rt: actix_rt::Runtime,}

impl ActixRuntime {
    pub fn new() -> Self {
        ActixRuntime {
            rt: actix_rt::Runtime::new().unwrap(),}
    }
}

这个错误是因为 actix_rt(和 tokio 0.2.x)的 block_on 函数一个签名 block_on(&mut self,...) -> ... { ... } 所以我不能实现这个 trait,因为 trait 有一个不可变的引用。

在我更深入地尝试完成这项工作之前,我想问一下我正在尝试的事情是否可行。有没有办法将 Criterionactix 一起使用?或者目前这是不可能的?如果不可能,是否还有其他可用的框架,或者我应该查看 Rust 工具链之外的解决方案?

感谢您的任何建议或帮助,欢迎提供链接和示例!

干杯!

解决方法

actix-rt v2 的 block_on 方法现在采用 &self after upgrading to tokio 1.0。升级应该可以解决您的问题:

// pin your deps: https://github.com/actix/actix-web/issues/1944
actix-rt = "=2.0.0-beta.2"
actix-web = "4.0.0-beta.1"
actix-service = "=2.0.0-beta.3"

如果升级不是一种选择,您可以使用内部可变性包装器,例如 RefCell

impl AsyncExecutor for ActixRuntime {
    fn block_on<T>(&self,future: impl Future<Output=T>) -> T {
        self.rt.borrow_mut().block_on(future)
    }
}

pub struct ActixRuntime {
    rt: RefCell<actix_rt::Runtime>,}

impl ActixRuntime {
    pub fn new() -> Self {
        ActixRuntime {
            rt: RefCell::new(actix_rt::Runtime::new().unwrap())
        }
    }
,

似乎没有什么好方法可以做到这一点。没有支持 actix_rt 2.0.x 的稳定 actix 版本(尽管它会修复 AsyncExecutor 中的可变性冲突)。截至目前,actix-web 4.0.x 处于测试阶段,对于我现有的应用程序来说太不稳定了(使用时会导致各种问题)。现在我将等到 actix-web 4.0.0 发布并稳定后为我的 api 实现基准测试。