cloudflare / cloudflare/workers-rs

[BUG] `Rc<RefCell<wasm_bindgen_futures::Inner>>` cannot be sent between threads safely

Open
#485 20 comments 3 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
3.7k
Forks
429
Avg merge
20h 28m
Merged PRs (30d)
7

Description

### Is there an existing issue for this?

- [X] 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](https://github.com/cloudflare/workers-rs/tree/main/examples/axum). This is great! It would allow use of the entire [tower](https://crates.io/crates/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:

```rs
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,
}

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> {
console_error_panic_hook::set_once();
Ok(router(env).call(req).await?)
}

#[debug_handler]
pub async fn root(State(AppState { env }): State) -> &'static str {
env.bucket("BUCKET")
.unwrap()
.list()
.execute()
.await
.unwrap();
"Hello Axum!"
}
```

However, we see this is not possible:

```
error[E0277]: `Rc>` cannot be sent between threads safely
--> src/lib.rs:28:1
|
28 | #[debug_handler]
| ^^^^^^^^^^^^^^^^ `Rc>` cannot be sent between threads safely
29 | pub async fn root(State(AppState { env }): State) -> &'static str {
| --------------------------------------------------------------------------- within this `impl Future`
|
= help: within `impl Future`, the trait `Send` is not implemented for `Rc>`
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 {
| ___________________________________________________^
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`, `Arc`, `Bucket`, `impl Future>`
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) -> &'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

1. Modify axum example with the above code to read R2 bucket
2. Observe failure to build

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.