我正在使用Actix_web在Rust中构建API服务。我有一个API处理函数register_business
,负责向数据库添加新业务。
my API处理程序函数
#[post("/businesses/")]
async fn add_business(payload: web::Json<BusinessPayload>,pool: Connection) ->Result<HttpResponse,Error>{
//error thrown here web::block
let reg_business = web::block(move || {
let conn = pool.get().unwrap();
register_business(payload.into_inner(), &conn)
})
.await
.unwrap()
.await
.map_err(|_| actix_web::error::ErrorInternalServerError("Internal Server Error"))?;
Ok(HttpResponse::Ok().json(reg_business))
}
字符串register_business
函数
pub async fn register_business(payload: BusinessPayload, conn: &PgConnection) -> Result<Business, DbError> {
let images_paths = upload_images(payload.images).await.unwrap();
let reg_business = NewBusiness {
uuid: nanoid!(),
images: images_paths,
//assigning other payload values here
};
let res_registration = diesel::insert_into(businesses)
.values(®_business)
.get_result(conn)?;
Ok(res_registration)
}
型
最后我的upload_image
,它接受一个base64编码字符串数组,向cloudinary API发出请求并存储图像路径。
pub async fn upload_images(payload: Vec<String>) -> Result<Vec<String>, Error> {
let client = Client::default();
let mut uploaded_images = Vec::new();
//TODO: move key to env var
let api_key = String::from("api-key-here");
let authorization_header = format!("Bearer {}", api_key);
for image_data in payload {
let response = client
.post("https://api.cloudinary.com/v1_1/deye3gicq/image/upload")
.insert_header(("Authorization", authorization_header.clone()))
.send_body(image_data)
.await
.unwrap()
.json::<Value>()
.await
.unwrap();
if let Some(image_url) = response.get("imageUrl").and_then(Value::as_str) {
uploaded_images.push(image_url.to_string());
println!("{:?}", image_url);
}
}
Ok(uploaded_images)
}
型
我正在使用这个项目来学习Rust,无法确定这里可能有什么问题。如有任何帮助,我们将不胜感激。
我试过检查Rust手册,但无法修复此错误。对于上下文,这是完整的编译器诊断错误。
error: future cannot be sent between threads safely
--> src/routes/handlers.rs:32:24
|
32 | let reg_business = web::block(move || {
| ^^^^^^^^^^ future returned by `register_business` is not `Send`
|
= help: within `diesel::PgConnection`, the trait `Sync` is not implemented for `NonNull<pq_sys::pg_conn>`
note: future is not `Send` as this value is used across an await
--> src/utils/helpers.rs:19:53
|
18 | pub async fn register_business(payload: BusinessPayload, conn: &PgConnection) -> Result<Business, DbError> {
| ---- has type `&diesel::PgConnection` which is not `Send`
19 | let images_paths = upload_images(payload.images).await.unwrap();
| ^^^^^^ await occurs here, with `conn` maybe used later
...
44 | }
| - `conn` is later dropped here
note: required by a bound in `block`
--> /Users/cooper/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-web-4.3.1/src/web.rs:215:8
|
215 | R: Send + 'static,
| ^^^^ required by this bound in `block`
型
1条答案
按热度按时间nzk0hqpo1#
错误是说传入
web::block
的闭包的返回类型不是Send
。这个错误看起来有点复杂,因为实际上是从web::block
返回Future
。这几乎总是错误的。web::block
用于执行 * 分块 * 代码,而不是异步代码。您可以通过仅在实际的diesel交互(阻塞代码)上进行阻塞来解决此问题。看看the example diesel integration。
字符串