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

Could be a Stream, not a Future? #1

Open
FauxFaux opened this issue Feb 7, 2020 · 0 comments
Open

Could be a Stream, not a Future? #1

FauxFaux opened this issue Feb 7, 2020 · 0 comments

Comments

@FauxFaux
Copy link

@FauxFaux FauxFaux commented Feb 7, 2020

I would like to know if a user presses ctrl+c again, after the first time.

This is common in applications which do task-based work, such as network servers or clients. The first "ask to exit" causes them to stop creating new work, and the second "ask to exit" tries much harder to cancel in-flight work (e.g. by killing jobs), but still do a clean shutdown. postgres, aria2, etc. all do this, to some extent.

This isn't possible with the current code, because the Future provided is essentially Fused; it will always resolve Ready once it has resolved Ready once.

Maybe the crate could expose a Stream of events, which resolve the same way as the current futures resolve? Existing users would have an easy migration path; they only care about the first future returned, and the stream could return pre-fused futures (like the current future, but explicict).

Thoughts?


I'm worried this is essentially identical to the following, however, ignoring multiple runtimes (async-std vs. tokio) and error handling (Pfft! Trivial concerns!).

let (term_send, mut term_recv) = futures::channel::mpsc::channel(1);
ctrlc::set_handler(move || {
    let _ async_std::task::block_on(term_send.clone().send(()));
})
.expect("adding termination");

Then:

let ctrl_c = term_recv.next().fuse();

Or something like FauxFaux/async-echo@e843262 , maybe:

loop {
  select! {
    _ = term_recv.next() => break,
    complete => break,
    actual_work = actual_workers.next() => { .. },
  }
}

let ctrl_c = term_recv.next().fuse();
for actual_work in actual_workers {
  ctrl_c.race(actual_work.cancel()).await?;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
You can’t perform that action at this time.