-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
feat: add downcast on Sleep
trait
#3125
Conversation
I think it'd be a bit cleaner to implement downcasting methods directly on Sleep without requiring implementors to deal with it: mod private {
pub struct PrivacyToken;
}
pub trait Sleep: Send + Sync + Future<Output = ()> {
// PrivacyToken can't be named outside of this crate, so it prevents anyone from overriding this default
// implementation in another crate. That allows us to trust it to be correct in the downcast methods below.
#[doc(hidden)]
fn __private_api_type_id(&self, _: private::PrivacyToken) -> TypeId {
TypeId::of::<Self>()
}
}
impl dyn Sleep {
/// Returns `true` if the sleep's type is `T`.
pub fn is<T>(&self) -> bool
where
T: Sleep,
{
self.__private_api_type_id(private::PrivacyToken) == TypeId::of::<T>()
}
/// Attempts to downcast the sleep to the type `T` if it has that type.
pub fn downcast_ref<T>(&self) -> Option<&T>
where
T: Sleep,
{
if self.is::<T>() {
unsafe { Some(&*(self as *const dyn Sleep as *const T)) }
} else {
None
}
}
// downcast_pin as well similarly
} |
That's a good point. We can probably make Though, |
Are there any relevant non-'static Sleep implementations? |
fc9e8f3
to
b7d56c9
Compare
I don't think so, but we shouldn't be too concerned about it now anyways imo. I have also added some docs to it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks goot to me, @sfackler anything else you'd need?
src/rt/mod.rs
Outdated
|
||
pub mod timer; | ||
|
||
pub use timer::*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest this be an explicit list, just to prevent any accidents now or in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/rt/mod.rs
Outdated
//! If the `runtime` feature is disabled, the types in this module can be used | ||
//! to plug in other runtimes. | ||
|
||
pub mod timer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps let's start with the module being private, we can always make it public later if it'd be helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/rt/timer.rs
Outdated
/// A future returned by a `Timer`. | ||
pub trait Sleep: Send + Sync + Future<Output = ()> { | ||
#[doc(hidden)] | ||
/// This method is private and should not be implemented by downstream crate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can not be implemented, not should not be implemented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/rt/timer.rs
Outdated
//! if sleep.downcast_ref::<TokioSleep>().is_some() { | ||
//! *sleep = self.sleep_until(new_deadline); | ||
//! } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't make much sense to me. The whole point of downcasting is to not have to create a new timer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think I understood the issue better now. I updated the example code with an implementation of tokio::time::Sleep::reset
src/rt/timer.rs
Outdated
/// Downcast the Sleep object to its original type | ||
pub fn downcast_ref<T>(&self) -> Option<&T> | ||
where | ||
T: Sleep + 'static, | ||
{ | ||
if self.is::<T>() { | ||
unsafe { Some(&*(self as *const dyn Sleep as *const T)) } | ||
} else { | ||
None | ||
} | ||
} | ||
|
||
/// Similar to `downcast_ref` but returns a mutable version instead | ||
pub fn downcast_mut<T>(&mut self) -> Option<&mut T> | ||
where | ||
T: Sleep + 'static, | ||
{ | ||
if self.is::<T>() { | ||
unsafe { Some(&mut *(self as *mut dyn Sleep as *mut T)) } | ||
} else { | ||
None | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think these two downcast methods are going to be too useful, since reset
is working with a &mut Pin<Box<dyn Sleep>>
. I think we'd probably need a pub fn downcast_pin_mut<T>(self: Pin<&mut Self>) -> Option<Pin<&mut T>>
probably?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be good to update the test |
Hey @dswij, just wanted to check if you think you'll have time to update this. No worries if you can't, just checking to reduce duplicate work. :) |
Sorry for the delay, I was on a break a while ago and I haven't caught up to my backlog yet. I'll try to take a look at this PR on the weekend 🙂 |
4dc245c
to
6858fab
Compare
This commit adds `as_any` downcast method for the `Sleep` trait. BREAKING CHANGE: `Sleep` trait now needs `as_any` implementation
This commit allows downcasting pinned `Sleep` object to support implementations of `Timer::reset`. One example where this is useful is when using `TokioSleep`, i.e. `Sleep` provided by tokio.
@seanmonstar @sfackler sorry for the delay, turned out it took a while for me to get back to this. Would you guys able to help give another round of review? |
@seanmonstar sorry to nag, but is there anything I can do to move this forward? |
This commit allows downcasting pinned `Sleep` object to support implementations of `Timer::reset`. One example where this is useful is when using `TokioSleep`, i.e. `Sleep` provided by tokio. Closes hyperium#3027
This commit allows downcasting pinned `Sleep` object to support implementations of `Timer::reset`. One example where this is useful is when using `TokioSleep`, i.e. `Sleep` provided by tokio. Closes hyperium#3027 Signed-off-by: Sven Pfennig <[email protected]>
closes #3027
This pr adds a downcast for the
Sleep
trait.