workers-rs: [BUG] `Rc>` cannot be sent between threads safely
Is there an existing issue for this?
- I have searched the existing issues
What version of workers-rs are you using?
0.0.21
What version of wrangler are you using?
2.13.0
Describe the bug
I see that you have recently added an example with axum. This is great! It would allow use of the entire tower ecosystem.
Env implements unsafe Send which is perfect. But any attempt to use it fails. I cannot figure out how to make this work with any non-trivial example. Could you please share how you imagine this should work? For example, here I have extended the example to try and list R2 objects:
use std::sync::Arc;
use axum::{extract::State, routing::get, Router};
use axum_macros::debug_handler;
use tower_service::Service;
use worker::*;
#[derive(Clone)]
pub struct AppState {
env: Arc<Env>,
}
fn router(env: Env) -> Router {
let state = AppState { env: Arc::new(env) };
Router::new().route("/", get(root)).with_state(state)
}
#[event(fetch)]
async fn fetch(
req: HttpRequest,
env: Env,
_ctx: Context,
) -> Result<axum::http::Response<axum::body::Body>> {
console_error_panic_hook::set_once();
Ok(router(env).call(req).await?)
}
#[debug_handler]
pub async fn root(State(AppState { env }): State<AppState>) -> &'static str {
env.bucket("BUCKET")
.unwrap()
.list()
.execute()
.await
.unwrap();
"Hello Axum!"
}
However, we see this is not possible:
error[E0277]: `Rc<RefCell<wasm_bindgen_futures::Inner>>` cannot be sent between threads safely
--> src/lib.rs:28:1
|
28 | #[debug_handler]
| ^^^^^^^^^^^^^^^^ `Rc<RefCell<wasm_bindgen_futures::Inner>>` cannot be sent between threads safely
29 | pub async fn root(State(AppState { env }): State<AppState>) -> &'static str {
| --------------------------------------------------------------------------- within this `impl Future<Output = &'static str>`
|
= help: within `impl Future<Output = &'static str>`, the trait `Send` is not implemented for `Rc<RefCell<wasm_bindgen_futures::Inner>>`
note: required because it appears within the type `JsFuture`
--> /Users/creston/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-bindgen-futures-0.4.42/src/lib.rs:101:12
|
101 | pub struct JsFuture {
| ^^^^^^^^
= note: required because it captures the following types: `worker::ListOptionsBuilder<'_>`, `JsFuture`
note: required because it's used within this `async` fn body
--> /Users/creston/Projects/workers-rs/worker/src/r2/builder.rs:396:51
|
396 | pub async fn execute(self) -> Result<Objects> {
| ___________________________________________________^
397 | | let list_promise = self.edge_bucket.list(
398 | | js_object! {
399 | | "limit" => self.limit,
... |
420 | | Ok(Objects { inner })
421 | | }
| |_____^
= note: required because it captures the following types: `axum::extract::State<AppState>`, `Arc<worker::Env>`, `Bucket`, `impl Future<Output = std::result::Result<Objects, worker::Error>>`
note: required because it's used within this `async` fn body
--> src/lib.rs:29:77
|
29 | pub async fn root(State(AppState { env }): State<AppState>) -> &'static str {
| _____________________________________________________________________________^
30 | | env.bucket("BUCKET")
31 | | .unwrap()
32 | | .list()
... |
36 | | "Hello Axum!"
37 | | }
| |_^
note: required by a bound in `__axum_macros_check_root_future::check`
--> src/lib.rs:28:1
|
28 | #[debug_handler]
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
= note: this error originates in the attribute macro `debug_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
Steps To Reproduce
- Modify axum example with the above code to read R2 bucket
- Observe failure to build
About this issue
- Original URL
- State: open
- Created 3 months ago
- Comments: 20 (19 by maintainers)
Maybe the macro is the best solution after all. We’ll have to
unsafeimplementSendandSyncfor our app state (which I was hoping to avoid) but I think there’s no way around that without a large refactor of theworkercrate to useSendFuturethe crate.