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

Provide task::yield() #177

Closed
carllerche opened this issue Sep 26, 2016 · 8 comments
Closed

Provide task::yield() #177

carllerche opened this issue Sep 26, 2016 · 8 comments

Comments

@carllerche
Copy link
Member

This would be implemented something like:

pub fn yield() {
    park().unpark();
}

// usage
task::yield();
return Ok(Async::NotReady);

Another option would be to provide a yield!(); macro that includes the return.

@alexcrichton
Copy link
Member

Oh gah yield is a reserved keyword :(

@ipetkov
Copy link
Contributor

ipetkov commented Sep 27, 2016

We should consider having the yield equivalent indicate an explicit state in the task rather than just alias an immediate unpark. That way top level loops may intelligently handle yields (e.g. schedule a different task, back off on repeated yields, etc.) instead of spinning on the same task.

@alexcrichton
Copy link
Member

@ipetkov yeah it's also possible to do that, but we'd likely do that through something like Async::Yield if we were to do it. Right now though the logic around that is pretty complicated, and the benefit seems marginal, so we figure it's fine for now to stick with park().unpark() to see how far we get.

@ipetkov
Copy link
Contributor

ipetkov commented Sep 28, 2016

@alexcrichton IMO I don't think this alias helps very much (well, except for avoiding the awkard looking park().unpark(), but I'll leave the name bikeshedding for elsewhere) because I find the name misleading since it's not guaranteed another task will get scheduled and we could end up spinning in place.

As for using something like Async::Yield, it can definitely provide the needed distinction, however, it forces all future combinators to correctly merge/propagate results from inner futures. For example, a JoinN's inner futures could collectively park/unpark/yield and the combinator would have to remember to also propagate the results on (in this case probably an Async::Yield). If the task handles this for us, it both allows combinators to be "dumber", and it allows for custom handling of unpark/yield via with_unpark_event since combinator behavior won't get in the way.

@carllerche
Copy link
Member Author

@ipetkov you could say the same about thread yielding "not providing a guarantee". A yield here would be equivalent here. The scheduler has the opportunity to schedule another task.

Anything more advanced (back off on repeated yields, etc) can be handled by the scheduler providing its own API. Any such api can be built on top of the provided primitives.

@ipetkov
Copy link
Contributor

ipetkov commented Sep 28, 2016

Anything more advanced (back off on repeated yields, etc) can be handled by the scheduler providing its own API. Any such api can be built on top of the provided primitives.

@carllerche Given the current primitives (and the proposition for yield), it's not clear to me how the same future could sometimes yield and sometimes unpark its task, yet allow the scheduler to react differently to each event.

@carllerche
Copy link
Member Author

The scheduler could provide its own constructs.

For example, imagine the CPU Pool lib could provide pool::exponential_backoff_yield()

Keep in mind that the scheduler knows which task is currently being executed.

@ipetkov
Copy link
Contributor

ipetkov commented Sep 28, 2016

For example, imagine the CPU Pool lib could provide pool::exponential_backoff_yield()

Keep in mind that the scheduler knows which task is currently being executed.

That makes sense. Seems unfortunate to tightly couple a given future to a scheduler it may run on. Maybe it would be worth considering passing user specified tokens through unpark or equivalent, as long as the future and scheduler agree?

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

No branches or pull requests

4 participants