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

"Working with Futures" page needs improvement around implementing Future #67

Open
carllerche opened this issue Oct 9, 2018 · 8 comments

Comments

@carllerche
Copy link
Member

Regarding: https://github.com/tokio-rs/doc-push/blob/master/outline/futures-streams-sinks.md#working-with-futures

There is currently a point "Implementing custom combinators", but this does not do justice to the topic of implementing futures.

Future is implemented more than just for custom combinators. Entire applications can be written by only implementing Future and other poll_ based functions.

Maybe there should be an additional page in that section dedicated to writing code (or entire apps) entirely without future combinators?

@davidbarsky
Copy link
Member

Big plus one on this. The example on “Returning Futures” under the title “Custom types” would be great if it could be fleshed out. As a bit of low-hanging fruit, the following example (particularly the ... in fn foo) body is one such candidate:

struct MyFuture {
    inner: Sender<i32>,
}

fn foo() -> MyFuture {
    let (tx, rx) = oneshot::channel();
    // ...
    MyFuture { inner: tx }
}

impl Future for MyFuture {
    // ...
}

Assuming that several future combinator chains occur in the body of foo() it'd be nice to see how values could be send to the tx value without dropping things.

On an aside, I find working with the poll API to be far more understandable than the combinators API, and I recall @hawkw noting the best way to work Tokio/Futures 0.1 in the large is to implement the futures yourself (unlike Scala or TypeScript, where the futures are a library feature that you only interact with).

@davidbarsky
Copy link
Member

An example I'd like to write:

use hyper::{Client, StatusCode};

struct MyFuture {
    inner: Receiver<i32>,
}

fn foo() -> MyFuture {
    let (sender, receiver) = oneshot::channel();
    let client = Client::new();
    client
         .get("google.com".parse::<Uri>().unwrap())
         .and_then(|res| sender.send(res.status_code));

    MyFuture { inner: receiver }
}

impl Future for MyFuture {
    // ...
}

...without getting a cancelation on the oneshot—I think the client/sender is getting deallocated before the status code value could be sent.

@carllerche
Copy link
Member Author

@davidbarsky it looks like you are dropping the return value of and_then, which cancels the entire future. Maybe you want to spawn that work?

@davidbarsky
Copy link
Member

@carllerche Good point. In this case, should I use oneshot's spawn or Tokio's spawn?

@carllerche
Copy link
Member Author

Tokio' spawn for tokio examples I guess.

@davidbarsky
Copy link
Member

Hmm, I'm seeing Spawn Error { is_shutdown: true } errors. To avoid wasting your time, can you point me to an example that implements a future over oneshot?

@carllerche
Copy link
Member Author

@davidbarsky I can't think of an existing example off the top of my head.

The problem is most likely that you are calling foo() from off the runtime. You probably want to do:

use futures::future::lazy;

tokio::run(lazy(|| {
   // setup here, probably call `foo())`.
   Ok(())
}))

This sucks and I hope to fix it in 0.2, but for now it is what it is. I would probably ask that you figure out where some of these concepts should be introduced in the docs, because you are stumbling on issues that others have as well.

@davidbarsky
Copy link
Member

The problem is most likely that you are calling foo() from off the runtime. You probably want to do:

Hmm, tried that, and the issues persisted. I'll try to create a minimal example that demonstrates what I'm doing.

This sucks and I hope to fix it in 0.2, but for now it is what it is. I would probably ask that you figure out where some of these concepts should be introduced in the docs, because you are stumbling on issues that others have as well.

I guess the biggest one would be "the how's and why's" of implementing Future yourself, because the intuition as to when someone should implement their own Future seems to be the biggest gap between intermediate and advanced users of Tokio.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants