tokio的例子跑不起来,异步使用报错
FourSpaces opened this issue · 2 comments
FourSpaces commented
有以下几个问题:
1、taokio的例子 在运行时会报错,错误内容:
error: future cannot be sent between threads safely
--> src/main.rs:13:23
|
13 | handlers.push(tokio::spawn(async move {
| ^^^^^^^^^^^^ future created by async block is not `Send`
|
= help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `Rc<RefCell<SentinelEntry>>`
2、使用异步的时候,会报错,主要代码如下:
pub async fn sentinel_limiting(
req: Request<Body>,
next: Next<Body>,) -> Result<impl IntoResponse, (StatusCode, String)> {
let entry_builder = EntryBuilder::new(String::from(RESOURCE_NAME))
.with_traffic_type(base::TrafficType::Inbound);
match entry_builder.build() {
Ok(entry) => {
let res = {next.run(req).await};
entry.exit();
Ok(res)
},
Err(_) => {
log::info!("被限流了");
Err((StatusCode::PAYLOAD_TOO_LARGE, String::from("")))},
}
}
主要报错如下:
error: future cannot be sent between threads safely
--> src/main.rs:48:10
|
48 | .layer(middleware::from_fn(sentinel_limiting))
| ^^^^^ future returned by `sentinel_limiting` is not `Send`
|
= help: within `FromFnResponseFuture<impl Future<Output = std::result::Result<Opaque(DefId(0:548 ~ rs_logonline[3f0a]::middlewares::limiting::sentinel_limiting::{opaque#0}::{opaque#0}), []), (StatusCode, std::string::String)>>>`, the trait `Send` is not implemented for `Rc<RefCell<SentinelEntry>>`
note: future is not `Send` as this value is used across an await
--> src/middlewares/limiting.rs:41:37
|
40 | Ok(entry) => {
| ----- has type `EntryStrongPtr` which is not `Send`
41 | let res = {next.run(req).await};
| ^^^^^^ await occurs here, with `entry` maybe used later
...
44 | },
| - `entry` is later dropped here
note: required by a bound in `Router::<B>::layer`
--> /Users/weicheng/.cargo/registry/src/github.com-1ecc6299db9ec823/axum-0.5.1/src/routing/mod.rs:298:63
|
298 | <L::Service as Service<Request<NewReqBody>>>::Future: Send + 'static,
| ^^^^ required by this bound in `Router::<B>::layer`
FourSpaces commented
我已经找到问题了,由于用到了异步,需要在Cargo.toml 中添加 features = ["async"]
原来的 Cargo.toml 中
sentinel-core = { version = "0.1.1", features = ["full"]
调整后的 Cargo.toml :
sentinel-core = { version = "0.1.1", features = ["async"] }
调整后,entry 的类 由 Rc<RefCell> 变为了 Arc<RwLock>,就解决了 Send约束问题。
总之:使用异步时候需要在 Cargo.toml 中 指定 features 为 "async"