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

timer: sleep future should become !Unpin #3028

Closed
carllerche opened this issue Oct 22, 2020 · 12 comments · Fixed by #3080
Closed

timer: sleep future should become !Unpin #3028

carllerche opened this issue Oct 22, 2020 · 12 comments · Fixed by #3080
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. M-time Module: tokio/time
Milestone

Comments

@carllerche
Copy link
Member

This would allow using an intrusive-list for the timer.

@carllerche carllerche added A-tokio Area: The main tokio crate C-feature-request Category: A feature request. labels Oct 22, 2020
@carllerche carllerche added this to the v1.0 milestone Oct 22, 2020
@Darksonn Darksonn added the M-time Module: tokio/time label Oct 22, 2020
@Darksonn
Copy link
Contributor

Be aware that it is very commonly used in manual Future and Stream impls since it's the easiest way to hook into Tokio's timer.

@carllerche
Copy link
Member Author

You think that adding Pin<Box<_>> in the docs w/ an example of a manual impl is enough?

@Darksonn
Copy link
Contributor

If we keep it as a named type rather than an async fn, it's probably ok, although then their type becomes !Unpin too unless they box it.

@carllerche
Copy link
Member Author

Is there a reason for it to stay a named type of boxing it is an acceptable strategy? We can document the pattern.

@Darksonn
Copy link
Contributor

If it stays named, boxing is not forced since they can use pin-project.

@carllerche carllerche mentioned this issue Oct 27, 2020
10 tasks
@zaharidichev
Copy link
Contributor

I am interested in picking that up if it is fine. If so, a bit of guidance will be highly appreciated.

@sfackler
Copy link
Contributor

It should just require the addition of a PhantomPinned field in the Sleep type: https://docs.rs/tokio/0.3.1/src/tokio/time/sleep.rs.html#62-67

@zaharidichev
Copy link
Contributor

I figured that much. My question was more around the transition to using intrusive list for the timer.

@carllerche
Copy link
Member Author

This would be a breaking change and we haven't forked off for 1.0 yet. I also believe @bdonlan is exploring a bigger timer change right now.

@zaharidichev
Copy link
Contributor

I see, that makes sense

@bdonlan
Copy link
Contributor

bdonlan commented Oct 27, 2020

For 1.0, I would be inclined to have an API that looks a bit like this:

struct Timer { ..., _p: PhantomPinned }

fn sleep(dur: Duration) -> Timer;
fn sleep_until(t: Instant) -> Timer;

struct TimerUnpin { ... }

impl TimerUnpin {
  fn sleep(dur: Duration) -> Self;
  fn sleep_until(t: Instant) -> Self;
}

The reason to do this this way is that it may be possible to avoid boxing even for unpinned timers in some cases. In particular, we can have a single per-task timer that tracks the earliest timeout seen the last time the task was polled. This would allow us to avoid allocation or pinning provided that the timer is polled on a tokio reactor thread (of course, if polled outside the reactor, we must actually create a timer object that we register with whatever reactor it was created on).

@bdonlan
Copy link
Contributor

bdonlan commented Oct 27, 2020

Upon further thought, avoiding timer state (by associating wakeup times with the task) would require changes in Context. We can't use thread-locals as we might be going through a nested executor, so we'd need a way to interrogate Context for a backchannel to set a wake-up time. Since adding a TimerUnpin is an API-compatible change we could just encourage people to use Box<Pin<Timer>> in the near term.

As for the intrusive list changes, I'm actively working on them at the moment.

bdonlan pushed a commit to bdonlan/tokio that referenced this issue Oct 30, 2020
This is more-or-less a half-rewrite of the current time driver, supporting the
use of intrusive futures for timer registration.

Fixes: tokio-rs#3028, tokio-rs#3069
carllerche pushed a commit that referenced this issue Nov 23, 2020
More-or-less a half-rewrite of the current time driver, supporting the
use of intrusive futures for timer registration.

Fixes: #3028, #3069
bors bot pushed a commit to sigp/lighthouse that referenced this issue Feb 10, 2021
## Issue Addressed

resolves #2129
resolves #2099 
addresses some of #1712
unblocks #2076
unblocks #2153 

## Proposed Changes

- Updates all the dependencies mentioned in #2129, except for web3. They haven't merged their tokio 1.0 update because they are waiting on some dependencies of their own. Since we only use web3 in tests, I think updating it in a separate issue is fine. If they are able to merge soon though, I can update in this PR. 

- Updates `tokio_util` to 0.6.2 and `bytes` to 1.0.1.

- We haven't made a discv5 release since merging tokio 1.0 updates so I'm using a commit rather than release atm. **Edit:** I think we should merge an update of `tokio_util` to 0.6.2 into discv5 before this release because it has panic fixes in `DelayQueue`  --> PR in discv5:  sigp/discv5#58

## Additional Info

tokio 1.0 changes that required some changes in lighthouse:

- `interval.next().await.is_some()` -> `interval.tick().await`
- `sleep` future is now `!Unpin` -> tokio-rs/tokio#3028
- `try_recv` has been temporarily removed from `mpsc` -> tokio-rs/tokio#3350
- stream features have moved to `tokio-stream` and `broadcast::Receiver::into_stream()` has been temporarily removed -> `tokio-rs/tokio#2870
- I've copied over the `BroadcastStream` wrapper from this PR, but can update to use `tokio-stream` once it's merged tokio-rs/tokio#3384

Co-authored-by: realbigsean <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. M-time Module: tokio/time
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants