Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Server can't be run due to lack of Send trait on run() future #125

Closed
pacmancoder opened this issue Nov 23, 2020 · 3 comments · Fixed by #128
Closed

[BUG] Server can't be run due to lack of Send trait on run() future #125

pacmancoder opened this issue Nov 23, 2020 · 3 comments · Fixed by #128
Assignees
Labels
bug Something isn't working

Comments

@pacmancoder
Copy link
Contributor

Description
The following simple code snippet fails on compilation when trying to use saphir 2.8.0 alongside with tokio 0.3.4

use saphir::server::Server;
use tokio::runtime::Runtime;

fn main() {
    let server = Server::builder().build();
    tokio::spawn(server.run());
}
[package]
name = "saphir-test"
version = "0.1.0"
edition = "2018"

[dependencies]
tokio = { version = "=0.3.4", features = [ "rt" ]}
saphir = "=2.8"

This code fails due to the following error:

error[E0277]: `(dyn Future<Output = ()> + Unpin + 'static)` cannot be sent between threads safely
   --> src\main.rs:6:5
    |
6   |     tokio::spawn(server.run());
    |     ^^^^^^^^^^^^ `(dyn Future<Output = ()> + Unpin + 'static)` cannot be sent between threads safely
    | 
   ::: C:\Users\pacmancoder\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.3.4\src\task\spawn.rs:128:21
    |
128 |         T: Future + Send + 'static,
    |                     ---- required by this bound in `tokio::spawn`
    |
    = help: the trait `Send` is not implemented for `(dyn Future<Output = ()> + Unpin + 'static)`
    = note: required because of the requirements on the impl of `Send` for `Unique<(dyn Future<Output = ()> + Unpin + 'static)>`
    = note: required because it appears within the type `Box<(dyn Future<Output = ()> + Unpin + 'static)>`
    = note: required because it appears within the type `Pin<Box<(dyn Future<Output = ()> + Unpin + 'static)>>`
    = note: required because it appears within the type `saphir::server::ServerShutdown`
    = note: required because it appears within the type `for<'r, 's, 't0, 't1, 't2, 't3, 't4, 't5, 't6, 't7, 't8, 't9, 't10, 't11, 't12, 't13, 't14, 't15, 't16, 't17, 't18, 't19, 't20, 't21, 't22, 't23, 't24, 't25, 't26, 't27, 't28, 't29, 't30, 't31, 't32, 't33, 't34, 't35, 't36, 't37, 't38, 't39, 't40, 't41, 't42, 't43, 't44, 't45, 't46, 't47, 't48, 't49, 't50, 't51, 't52, 't53, 't54, 't55, 't56, 't57, 't58> {ResumeTy, saphir::server::Server, ListenerConfig, saphir::server::Stack, HeaderValue, Option<usize>, &'r saphir::server::Stack, saphir::hyper::server::conn::Http, &'s String, String, impl Future, (), tokio::net::tcp::listener::TcpListener, SocketAddr, tokio::net::tcp::incoming::Incoming<'t0>, saphir::server::ServerShutdown, Arc<saphir::server::SeverShutdownState>, Option<u64>, u64, futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t1>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#1}]>, saphir::server::ServerFuture<futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t17>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#1}]>, saphir::server::ServerShutdown>, futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t33>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#2}]>, saphir::server::ServerFuture<futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t46>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#2}]>, saphir::server::ServerShutdown>}`
    = note: required because it appears within the type `[static generator@saphir::server::Server::run::{closure#0} for<'r, 's, 't0, 't1, 't2, 't3, 't4, 't5, 't6, 't7, 't8, 't9, 't10, 't11, 't12, 't13, 't14, 't15, 't16, 't17, 't18, 't19, 't20, 't21, 't22, 't23, 't24, 't25, 't26, 't27, 't28, 't29, 't30, 't31, 't32, 't33, 't34, 't35, 't36, 't37, 't38, 't39, 't40, 't41, 't42, 't43, 't44, 't45, 't46, 't47, 't48, 't49, 't50, 't51, 't52, 't53, 't54, 't55, 't56, 't57, 't58> {ResumeTy, saphir::server::Server, ListenerConfig, saphir::server::Stack, HeaderValue, Option<usize>, &'r saphir::server::Stack, saphir::hyper::server::conn::Http, &'s String, String, impl Future, (), tokio::net::tcp::listener::TcpListener, SocketAddr, tokio::net::tcp::incoming::Incoming<'t0>, saphir::server::ServerShutdown, Arc<saphir::server::SeverShutdownState>, Option<u64>, u64, futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t1>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#1}]>, saphir::server::ServerFuture<futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t17>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#1}]>, saphir::server::ServerShutdown>, futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t33>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#2}]>, saphir::server::ServerFuture<futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t46>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#2}]>, saphir::server::ServerShutdown>}]`
    = note: required because it appears within the type `from_generator::GenFuture<[static generator@saphir::server::Server::run::{closure#0} for<'r, 's, 't0, 't1, 't2, 't3, 't4, 't5, 't6, 't7, 't8, 't9, 't10, 't11, 't12, 't13, 't14, 't15, 't16, 't17, 't18, 't19, 't20, 't21, 't22, 't23, 't24, 't25, 't26, 't27, 't28, 't29, 't30, 't31, 't32, 't33, 't34, 't35, 't36, 't37, 't38, 't39, 't40, 't41, 't42, 't43, 't44, 't45, 't46, 't47, 't48, 't49, 't50, 't51, 't52, 't53, 't54, 't55, 't56, 't57, 't58> {ResumeTy, saphir::server::Server, ListenerConfig, saphir::server::Stack, HeaderValue, Option<usize>, &'r saphir::server::Stack, saphir::hyper::server::conn::Http, &'s String, String, impl Future, (), tokio::net::tcp::listener::TcpListener, SocketAddr, tokio::net::tcp::incoming::Incoming<'t0>, saphir::server::ServerShutdown, Arc<saphir::server::SeverShutdownState>, Option<u64>, u64, futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t1>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#1}]>, saphir::server::ServerFuture<futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t17>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#1}]>, saphir::server::ServerShutdown>, futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t33>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#2}]>, saphir::server::ServerFuture<futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t46>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#2}]>, saphir::server::ServerShutdown>}]>`
    = note: required because it appears within the type `impl Future`
    = note: required because it appears within the type `impl Future`

error: aborting due to previous error; 1 warning emitted

However, on version 2.7.7 of saphir everything works as expected.

Expected behavior
The provided snippet can be run with saphir 2.8.0 the same way it works with saphir 2.7.7

Additional info (please complete the following information):

  • OS & OS Version: Windows 10 rev.2004
  • Saphir Version: 2.8.0
  • Rust toolchain & version: stable 1.48
@richerarc richerarc added the bug Something isn't working label Nov 24, 2020
@Samuel-B-D
Copy link
Contributor

Saphir itself is still running on tokio 0.2.x, and it is not recommended to mix a tokio 0.2.x and a 0.3.x executor in the same project.
Even though 2.7.7 worked, I personally ran into other issues when using tokio 0.3.5, but everything was fine for me with tokio 0.2.22.

Saphir should eventually be upgraded to tokio 0.3.x, but it is a bit more work than a simple version bump because a lot of the TCP API changed in tokio 0.3.x.

(The issue you pointed out should and will be fixed, as it will be required to upgrade to 0.3.x anyways. I'm just adding a bit more context to the discussion)

@richerarc
Copy link
Owner

@Samuel-B-D Thanks for the additional context but it is important to note that Saphir does not RUN on tokio 0.2.22, it uses Tokio 0.2 networking streams & futures. That being said, compatibility with the executor of Tokio 0.3 should be assured at least until fully updated to the newest version.

@pacmancoder
Copy link
Contributor Author

@Samuel-B-D @richerarc tried to run the same snippet which I posted above, same result with tokio 0.2.22:

[package]
name = "saphir-test"
version = "0.1.0"
edition = "2018"

[dependencies]
tokio = { version = "=0.2.22", futures = ["rt-core"]}
saphir = "2.8.0"

Error:

error[E0277]: `(dyn std::future::Future<Output = ()> + Unpin + 'static)` cannot be sent between threads safely
   --> src\main.rs:6:5
    |
6   |     tokio::spawn(server.run());
    |     ^^^^^^^^^^^^ `(dyn std::future::Future<Output = ()> + Unpin + 'static)` cannot be sent between threads safely
    | 
   ::: C:\Users\pacmancoder\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.2.22\src\task\spawn.rs:127:21
    |
127 |         T: Future + Send + 'static,
    |                     ---- required by this bound in `tokio::spawn`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants