[GH-ISSUE #1065] dev: future returned by Session::connect() is no longer Send #503

Closed
opened 2026-02-27 19:31:00 +03:00 by kerem · 3 comments
Owner

Originally created by @gdesmott on GitHub (Oct 15, 2022).
Original GitHub issue: https://github.com/librespot-org/librespot/issues/1065

See this simple change to demonstrate the problem:

diff --git a/examples/play.rs b/examples/play.rs
index 1209bf9..9875658 100644
--- a/examples/play.rs
+++ b/examples/play.rs
@@ -12,6 +12,10 @@ use librespot::{
     },
 };
 
+async fn wait_connect(fut: impl std::future::Future<Output = ()> + Send) {
+    fut.await;
+}
+
 #[tokio::main]
 async fn main() {
     let session_config = SessionConfig::default();
@@ -31,10 +35,14 @@ async fn main() {
 
     println!("Connecting...");
     let session = Session::new(session_config, None);
-    if let Err(e) = session.connect(credentials, false).await {
-        println!("Error connecting: {}", e);
-        exit(1);
-    }
+
+    let fut = async {
+        if let Err(e) = session.connect(credentials, false).await {
+            println!("Error connecting: {}", e);
+            exit(1);
+        }
+    };
+    wait_connect(fut).await;
 
     let mut player = Player::new(player_config, session, Box::new(NoOpVolume), move || {
         backend(None, audio_format)

This doesn't work because the Future returned by Session::connect() is not Send.

error: future cannot be sent between threads safely
  --> examples/play.rs:45:5
   |
45 |     wait_connect(fut).await;
   |     ^^^^^^^^^^^^ future created by async block is not `Send`
   |
   = help: the trait `std::marker::Send` is not implemented for `(dyn digest::digest::DynDigest + 'static)`
note: future is not `Send` as this value is used across an await
  --> /var/home/cassidy/dev/rust/librespot/core/src/connection/handshake.rs:95:48
   |
80 |     let padding = rsa::padding::PaddingScheme::new_pkcs1v15_sign(Some(rsa::hash::Hash::SHA1));
   |         ------- has type `rsa::padding::PaddingScheme` which is not `Send`
...
95 |     client_response(&mut connection, challenge).await?;
   |                                                ^^^^^^ await occurs here, with `padding` maybe used later
...
98 | }
   | - `padding` is later dropped here
note: required by a bound in `wait_connect`
  --> examples/play.rs:15:68
   |
15 | async fn wait_connect(fut: impl std::future::Future<Output = ()> + Send) {
   |                                                                    ^^^^ required by this bound in `wait_connect`

error: future cannot be sent between threads safely
  --> examples/play.rs:45:5
   |
45 |     wait_connect(fut).await;
   |     ^^^^^^^^^^^^ future created by async block is not `Send`
   |
   = help: the trait `std::marker::Send` is not implemented for `(dyn rand_core::RngCore + 'static)`
note: future is not `Send` as this value is used across an await
  --> /var/home/cassidy/dev/rust/librespot/core/src/connection/handshake.rs:95:48
   |
80 |     let padding = rsa::padding::PaddingScheme::new_pkcs1v15_sign(Some(rsa::hash::Hash::SHA1));
   |         ------- has type `rsa::padding::PaddingScheme` which is not `Send`
...
95 |     client_response(&mut connection, challenge).await?;
   |                                                ^^^^^^ await occurs here, with `padding` maybe used later
...
98 | }
   | - `padding` is later dropped here
note: required by a bound in `wait_connect`
  --> examples/play.rs:15:68
   |
15 | async fn wait_connect(fut: impl std::future::Future<Output = ()> + Send) {
   |                                                                    ^^^^ required by this bound in `wait_connect`

error: could not compile `librespot` due to 2 previous errors

Because of this librespot cannot longer be used with framework such as Rocket which requires futures to be Send.

This used to work fine with an older version so this is likely a regression.

Originally created by @gdesmott on GitHub (Oct 15, 2022). Original GitHub issue: https://github.com/librespot-org/librespot/issues/1065 See this simple change to demonstrate the problem: ```diff diff --git a/examples/play.rs b/examples/play.rs index 1209bf9..9875658 100644 --- a/examples/play.rs +++ b/examples/play.rs @@ -12,6 +12,10 @@ use librespot::{ }, }; +async fn wait_connect(fut: impl std::future::Future<Output = ()> + Send) { + fut.await; +} + #[tokio::main] async fn main() { let session_config = SessionConfig::default(); @@ -31,10 +35,14 @@ async fn main() { println!("Connecting..."); let session = Session::new(session_config, None); - if let Err(e) = session.connect(credentials, false).await { - println!("Error connecting: {}", e); - exit(1); - } + + let fut = async { + if let Err(e) = session.connect(credentials, false).await { + println!("Error connecting: {}", e); + exit(1); + } + }; + wait_connect(fut).await; let mut player = Player::new(player_config, session, Box::new(NoOpVolume), move || { backend(None, audio_format) ``` This doesn't work because the `Future` returned by `Session::connect()` is not `Send`. ```console error: future cannot be sent between threads safely --> examples/play.rs:45:5 | 45 | wait_connect(fut).await; | ^^^^^^^^^^^^ future created by async block is not `Send` | = help: the trait `std::marker::Send` is not implemented for `(dyn digest::digest::DynDigest + 'static)` note: future is not `Send` as this value is used across an await --> /var/home/cassidy/dev/rust/librespot/core/src/connection/handshake.rs:95:48 | 80 | let padding = rsa::padding::PaddingScheme::new_pkcs1v15_sign(Some(rsa::hash::Hash::SHA1)); | ------- has type `rsa::padding::PaddingScheme` which is not `Send` ... 95 | client_response(&mut connection, challenge).await?; | ^^^^^^ await occurs here, with `padding` maybe used later ... 98 | } | - `padding` is later dropped here note: required by a bound in `wait_connect` --> examples/play.rs:15:68 | 15 | async fn wait_connect(fut: impl std::future::Future<Output = ()> + Send) { | ^^^^ required by this bound in `wait_connect` error: future cannot be sent between threads safely --> examples/play.rs:45:5 | 45 | wait_connect(fut).await; | ^^^^^^^^^^^^ future created by async block is not `Send` | = help: the trait `std::marker::Send` is not implemented for `(dyn rand_core::RngCore + 'static)` note: future is not `Send` as this value is used across an await --> /var/home/cassidy/dev/rust/librespot/core/src/connection/handshake.rs:95:48 | 80 | let padding = rsa::padding::PaddingScheme::new_pkcs1v15_sign(Some(rsa::hash::Hash::SHA1)); | ------- has type `rsa::padding::PaddingScheme` which is not `Send` ... 95 | client_response(&mut connection, challenge).await?; | ^^^^^^ await occurs here, with `padding` maybe used later ... 98 | } | - `padding` is later dropped here note: required by a bound in `wait_connect` --> examples/play.rs:15:68 | 15 | async fn wait_connect(fut: impl std::future::Future<Output = ()> + Send) { | ^^^^ required by this bound in `wait_connect` error: could not compile `librespot` due to 2 previous errors ``` Because of this `librespot` cannot longer be used with framework such as Rocket which [requires futures to be Send](https://github.com/SergioBenitez/Rocket/blob/master/core/lib/src/lib.rs#L263). This used to work fine with an older version so this is likely a regression.
kerem 2026-02-27 19:31:00 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@roderickvd commented on GitHub (Oct 20, 2022):

Well regression... this is new functionality but still! Thanks for that minimal working example.

From a quick look it seems that the problem is that one of the variants of rsa::padding::PaddingScheme is not Send but not the one that we are using. I also see that there is an update of that crate with some API changes.

I don't have much time right now but maybe that either of these offer some direction.

<!-- gh-comment-id:1285030284 --> @roderickvd commented on GitHub (Oct 20, 2022): Well regression... this is new functionality but still! Thanks for that minimal working example. From a quick look it seems that the problem is that one of the variants of `rsa::padding::PaddingScheme` is not `Send` but not the one that we are using. I also see that there is an update of that crate with some API changes. I don't have much time right now but maybe that either of these offer some direction.
Author
Owner

@gdesmott commented on GitHub (Oct 20, 2022):

Well regression... this is new functionality but still!

Let's say it's a regression from an older dev version. ;)

From a quick look it seems that the problem is that one of the variants of rsa::padding::PaddingScheme is not Send but not the one that we are using. I also see that there is an update of that crate with some API changes.

PaddingScheme is still !Send in the latest version of the crate so that won't help.

I reported the problem to the rsa crate as well: https://github.com/RustCrypto/RSA/issues/214

<!-- gh-comment-id:1285713908 --> @gdesmott commented on GitHub (Oct 20, 2022): > Well regression... this is new functionality but still! Let's say it's a regression from an older `dev` version. ;) > From a quick look it seems that the problem is that one of the variants of `rsa::padding::PaddingScheme` is not `Send` but not the one that we are using. I also see that there is an update of that crate with some API changes. `PaddingScheme` is still `!Send` in [the latest version of the crate](https://docs.rs/rsa/latest/rsa/padding/enum.PaddingScheme.html) so that won't help. I reported the problem to the rsa crate as well: https://github.com/RustCrypto/RSA/issues/214
Author
Owner

@gdesmott commented on GitHub (Oct 20, 2022):

not the one that we are using.

Then we can easily workaround this problem: https://github.com/librespot-org/librespot/pull/1066

<!-- gh-comment-id:1285737086 --> @gdesmott commented on GitHub (Oct 20, 2022): > not the one that we are using. Then we can easily workaround this problem: https://github.com/librespot-org/librespot/pull/1066
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/librespot#503
No description provided.