【发布时间】:2020-03-01 11:06:39
【问题描述】:
我正在为actix-web 编写的服务器应用程序编写一个 GET 方法。 LMDB 是我使用的数据库,它的事务需要在其生命周期结束之前中止或提交。
为了避免一堆嵌套的matching,我尝试在所有返回结果的函数上使用map_err。在那里我尝试中止事务,但事务被移入关闭而不是被借用。
有什么办法可以将事务借入闭包中,还是我必须硬着头皮写一堆嵌套匹配?本质上,编写这个函数最符合人体工程学的方式是什么?
示例代码(见txn.abort()旁边的cmets):
pub async fn get_user(db: Data<Database>, id: Identity) -> Result<Json<User>, Error> {
let username = id.identity().ok_or_else(|| error::ErrorUnauthorized(""))?;
let txn = db
.env
.begin_ro_txn()
.map_err(|_| error::ErrorInternalServerError(""))?;
let user_bytes = txn.get(db.handle_users, &username).map_err(|e| {
txn.abort(); // txn gets moved here
match e {
lmdb::Error::NotFound => {
id.forget();
error::ErrorUnauthorized("")
}
_ => error::ErrorInternalServerError(""),
}
})?;
let user: User = serde_cbor::from_slice(user_bytes).map_err(|_| {
txn.abort(); // cannot use txn here as is was moved
error::ErrorInternalServerError("")
})?;
txn.abort(); // cannot use txn here as is was moved
Ok(Json(user))
}
【问题讨论】: