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

write_fmt fails inside spawned task #329

Open
yoshuawuyts opened this issue Oct 14, 2019 · 6 comments
Open

write_fmt fails inside spawned task #329

yoshuawuyts opened this issue Oct 14, 2019 · 6 comments
Labels
bug Something isn't working

Comments

@yoshuawuyts
Copy link
Contributor

It turns out that Arguments is non-Send, which means passing it to a spawned Future may not work because the future itself is Send.

use async_std::task;
use async_std::prelude::*;
use async_std::io;

fn main() {
    task::block_on(async {
        task::spawn(async {
            // This doesn't compile
            io::stderr().write_fmt(format_args!("hello")).await?;
        }).await
    })
}

2019-10-14-185507_1920x1080

This is causing some bugs. Posting this for future reference.

@yoshuawuyts yoshuawuyts added the bug Something isn't working label Oct 14, 2019
@ghost
Copy link

ghost commented Oct 14, 2019

As a temporary hack, we could write first to a String and the write that String into the writer.

@yoshuawuyts
Copy link
Contributor Author

Oh lol, I like that. Sounds good!

@yoshuawuyts
Copy link
Contributor Author

Going to mark this as "good first issue" so someone can pick this up!

@yoshuawuyts yoshuawuyts added the good first issue Good for newcomers label Oct 15, 2019
@Michael-J-Ward
Copy link
Contributor

As a temporary hack, we could write first to a String and the write that String into the writer.

Isn't that what it's already doing?

// In order to not have to implement an async version of `fmt` including private types
// and all, we convert `Arguments` to a `Result<Vec<u8>>` and pass that to the Future.
// Doing an owned conversion saves us from juggling references.
let mut string = String::new();
let res = std::fmt::write(&mut string, fmt)
.map(|_| string.into_bytes())
.map_err(|_| io::Error::new(io::ErrorKind::Other, "formatter error"));
WriteFmtFuture { writer: self, res: Some(res), buffer: None, amt: 0 }

@Michael-J-Ward
Copy link
Contributor

Or do you mean to change the signature of write_fmt so it takes a String instead of an Arguments like this, which I have working:

use async_std::task;
use async_std::prelude::*;
use async_std::io;

fn main() {
    femme::start(log::LevelFilter::Trace).unwrap();

    task::block_on(async {
        task::spawn(async {
            let error_msg = format!("hello errors");
            io::stderr().write_fmt(error_msg).await;
        }).await
    });
}

@yoshuawuyts
Copy link
Contributor Author

@Michael-J-Ward dang, you're right. Okay this may not be as straight forward as we'd like :/

@yoshuawuyts yoshuawuyts removed the good first issue Good for newcomers label Oct 15, 2019
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

No branches or pull requests

2 participants