Skip to content

write_fmt fails inside spawned task #329

@yoshuawuyts

Description

@yoshuawuyts
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.

Activity

ghost

ghost commented on Oct 14, 2019

@ghost

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

yoshuawuyts

yoshuawuyts commented on Oct 15, 2019

@yoshuawuyts
ContributorAuthor

Oh lol, I like that. Sounds good!

yoshuawuyts

yoshuawuyts commented on Oct 15, 2019

@yoshuawuyts
ContributorAuthor

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

Michael-J-Ward

Michael-J-Ward commented on Oct 15, 2019

@Michael-J-Ward
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

Michael-J-Ward commented on Oct 15, 2019

@Michael-J-Ward
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

yoshuawuyts commented on Oct 15, 2019

@yoshuawuyts
ContributorAuthor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @yoshuawuyts@Michael-J-Ward

        Issue actions

          write_fmt fails inside spawned task · Issue #329 · async-rs/async-std