main:
...
let wrap_pool = Arc::new(RwLock::new(pool));
// Compose the routes
let app = Router::new()
.route("/insert", post(insert_new_round))
// Add middleware to all routes
.layer(
ServiceBuilder::new()
.layer(HandleErrorLayer::new(|error: BoxError| async move {
if error.is::<tower::timeout::error::Elapsed>() {
Ok(StatusCode::REQUEST_TIMEOUT)
} else {
Err((
StatusCode::INTERNAL_SERVER_ERROR,
format!("Unhandled internal error: {error}"),
))
}
}))
.timeout(Duration::from_secs(10))
.layer(TraceLayer::new_for_http())
.into_inner(),
)
.with_state(wrap_pool);
...
async fn insert_new_round(State(db): State<Arc<RwLock<Pool<Sqlite>>>>, Json(round): Json<Round>) -> impl IntoResponse {
let db_lock = db.write().unwrap();
let pool_ref = &*db_lock;
match insert_round_to_db(pool_ref, &round).await {
Ok(_) => return (StatusCode::OK, Json( "Success".to_string())),
Err(e) => return (StatusCode::OK, Json(e.to_string())),
}
// return (StatusCode::OK, Json( "Success".to_string()));
}
async fn insert_round_to_db(pool: &SqlitePool, round: &Round) -> Result<i64, String>
在
route("/insert", post(insert_new_round))
出现编译错误
--> src/main.rs:70:32
|
70 | .route("/insert", post(insert_new_round))
| ---- ^^^^^^^^^^^^^^^^ the trait `Handler<_, _>` is not implemented for fn item `fn(State<Arc<std::sync::RwLock<sqlx::Pool<Sqlite>>>>, axum::Json<Round>) -> impl std::future::Future<Output = impl IntoResponse> {insert_new_round}`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `Handler<T, S>`:
<axum::handler::Layered<L, H, T, S> as Handler<T, S>>
<MethodRouter<S> as Handler<(), S>>
note: required by a bound in `post`
但是奇怪的是如果insert_new_round 函数修改成
async fn insert_new_round(State(db): State<Arc<RwLock<Pool<Sqlite>>>>, Json(round): Json<Round>) -> impl IntoResponse {
let db_lock = db.write().unwrap();
let pool_ref = &*db_lock;
// match insert_round_to_db(pool_ref, &round).await {
// Ok(_) => return (StatusCode::OK, Json( "Success".to_string())),
// Err(e) => return (StatusCode::OK, Json(e.to_string())),
// }
return (StatusCode::OK, Json( "Success".to_string()));
}
就没有编译错误了. 问题就出在 函数中是否调用了 insert_round_to_db(pool_ref, &round).await .
搜索了很久没有搞明白为什么会出现这个错误.
1
共 4 条评论, 1 页
评论区
写评论多谢多谢. 基本搞明白了.
--
👇
Bai-Jinlin: 你的锁是用的标准库的RwLock,RwLockWriteGuard是!Send的,!Send只要跨越了await点会导致你这个future不是Send的,所以不满足trait bound。 非形式的来说是因为你这个future在这个线程lock,但是这个future可能会在await点被tokio转移到其他线程这时在非lock线程unlock是不被定义的行为,所以这个Guard是!Send。改成tokio的锁就好了。
--
👇
招宝进财: 可否解释的更详细一些?
--
👇
bestgopher: lock跨await导致函数非Send
你的锁是用的标准库的RwLock,RwLockWriteGuard是!Send的,!Send只要跨越了await点会导致你这个future不是Send的,所以不满足trait bound。 非形式的来说是因为你这个future在这个线程lock,但是这个future可能会在await点被tokio转移到其他线程这时在非lock线程unlock是不被定义的行为,所以这个Guard是!Send。改成tokio的锁就好了。
--
👇
招宝进财: 可否解释的更详细一些?
--
👇
bestgopher: lock跨await导致函数非Send
可否解释的更详细一些?
--
👇
bestgopher: lock跨await导致函数非Send
lock跨await导致函数非Send