Skip to content

Add extension methods for using a StopToken, and use Result instead of Option #5

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

Closed
wants to merge 5 commits into from

Conversation

gavrie
Copy link

@gavrie gavrie commented Aug 5, 2020

I found myself writing the following code often:

let fut = some_future();
let mut fut = stop_token.stop_future(fut);
let result = fut.await;

Adding an extension method makes this more readable, since a fluent style can be used:

let result = some_future().with_stop_token(&stop_token).await;

In addition, I often had to use match to check for the None value being returned. This make the code very verbose.
Using Result instead makes it possible to use the question mark style for early return upon a dropped StopSource.

Unfortunately this can be done only for StopFuture and not for StopStream, since streams use Option explicitly.
But it still remains worthwhile to use it for futures.

Oh, and one more thing: Using a Result makes it possible to add more types of early termination, such as via a timeout instead of via the stop token. I often find myself setting up a timeout explicitly, and it would be nice to be able to add a timeout as well via a method -- and then receive a different Error value to be able to match on that.

My codebase (unfortunately not Open Source at this moment) became much cleaner with these changes.
The test I added demonstrates the usage.

@matklad @dignifiedquire I'd love your feedback on this.

@yoshuawuyts
Copy link
Collaborator

I love the functionality of this PR; I've been thinking of something similar for a while too (notes). The API I came up with for the Stream and Futures extensions was Stream::stop_on and Future::stop_on:

use stop_token::StopToken;

async fn main() {
    let src = StopSource::new();
    let token = src.stop_token();

    // The `work` stream will end early: as soon as `token` is StopSource.
    for ev.await in work.stop_on(token) {
        process_event(event).await
    }
}

I'm not sure what the right name for this is (paging @matklad who has a knack for this), but def think this would make for a good addition! -- Also def eyeing adding this to async-std itself once we've settled on an API.

@yoshuawuyts
Copy link
Collaborator

Prior art also in C#: async iterators expose the WithCancellation method: https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.threading.threadingtools.withcancellation?view=visualstudiosdk-2019

var cts = new CancellationTokenSource();
await foreach (int item in RangeAsync(10, 3).WithCancellation(cts.Token) { ... }

@yoshuawuyts
Copy link
Collaborator

Thanks for opening this PR! - This feature has been merged as part of #10. Thanks!

@yoshuawuyts yoshuawuyts closed this Oct 2, 2021
@gavrie
Copy link
Author

gavrie commented Oct 2, 2021

Thanks for opening this PR! - This feature has been merged as part of #10. Thanks!

Nice to see this done!

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

Successfully merging this pull request may close these issues.

2 participants