-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Use CLOCK_BOOTTIME for Instant in Fuchsia/Android #132331
base: master
Are you sure you want to change the base?
Use CLOCK_BOOTTIME for Instant in Fuchsia/Android #132331
Conversation
Fuchsia and Android both want Instants to progress during periods of suspension, and thus must use CLOCK_BOOTTIME as the backing reference clock.
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @tmandry (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
cc @maurer |
This comment was marked as off-topic.
This comment was marked as off-topic.
Don't have official review powers, but LGTM as the Android maintainer. |
Could you also update this table in the docs? Lines 221 to 229 in 88eafa4
|
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.
LGTM once docs are updated.
r? rust-lang/libs - Both platform owners approve this change, but I would like your team to be in the loop also. This change is allowed by my reading of the Instant docs.
|
They cannot rely on this because the documentation explicitly does not guarantee for this behavior:
Until #87906 is settled we shouldn't introduce platform-specific behavior that makes code non-portable. Also who is this "android wants" person that attempts to define how the Rust standard library should behave? And where did that discussion happen? |
As a brief summary of the situation resulting from the other thread:
|
Then, at the moment, the crates have a bug. It would be great if we could offer a portable solution here, but currently we can't because not all OSes provide such a clock. So I don't see this as a path to actually solving the problem, possibly even making it worse. The options I see are
|
Fuchsia and Android both want Instants to progress during periods of suspension, and thus must use CLOCK_BOOTTIME as the backing reference clock.
I've updated the docs to reflect the usage of boot time in Android and Fuchsia.
As @maurer has pointed out, the |
The current situation does not exist to enable specific crates to keep their broken implementations forever. But this PR would. Enabling crates in their reliance on implementation details on one platform makes this into a problem for other platforms. In other words you would be amplifying hyrum, and you're shifting the burden to other OSes. It goes roughly like this:
Instead the fact that such clocks aren't available on all platforms should be made explicit and the crates then will have to think about fallbacks or other ways to guard against whatever undesirable behavior we're talking about here in the abstract. Or at least they could make the error upfront and fail loudly when an essential building block is missing. Additionally this ignores the issue that there also are uses where not counting suspend can also be useful, so it just trades one benefit for another rather than enabling both. Yes the current situation isn't great. And you're feeling pain due to it. But imo that pain should be incentive to either fix the broken crates or help with a proper solution in std. Not papering over bugs for just one platform. |
Also, just because which clock is used on particular platforms is documented does not mean you're allowed to rely on it. It says
so even if this PR were accepted today, someone could come along tomorrow and change it back. |
Is this even correct for Fuchsia in the first place? |
I have a patch to fix |
The justification for this PR is in #88714 (comment):
The owners of a platform get to define what that standard monotonic clock is for their platform. In this case, both Fuchsia and Android want the standard monotonic clock to be the boottime clock, and this PR reflects that.
Which minority platforms are you worrying about here? This is two minority platforms deciding that they'd rather diverge from the majority (Linux and macOS) because they think it will work better in the majority of cases for the application classes that their platforms are designed for. Yes we want portable code, but in the absence of a well-defined semantics the precise details of what that code does may be impacted by the platform it is running on, which is relevant insofar as it informs us what kind of behavior is expected for applications running on that platform. There is precedent on either side; Windows being the main example of using boot time. It seems like you are arguing against the past decision to make the behavior of this API platform-specific in the first place. Arguments about past decisions should not block PRs like this.
Yes, and it would be great if std had two APIs to enable both cases, but it does not. In the absence of a perfect solution we are forced to make tradeoffs. The particular tradeoff here is what should most code on this platform do most of the time.
We'll have to disagree here – platform maintainers are not fungible assets who can take on a much larger project of defining new std APIs and migrating the ecosystem to it. That's orders of magnitude more work that requires a different set of skills and social connections, and it's letting the perfect be the enemy of the good. Pushing back on incremental improvements like this does no one any good, including the Rust project. If someone is interested in contributing to Rust in a small way, even in a way that's initially scoped to their platform, let them. That's how we will grow contributors with more impact over time. |
Would it simplify things if we refactored this PR to just focus on Fuchsia, and a separate one for Android? Right now all the known rust code that's targetting Fuchsia is owned by the Fuchsia team, whereas Android may have users that could be impacted by this change. |
That sounds like you intend to rely on implementation details. Is this correct?
No. The I'm arguing that guaranteed behavior is not provided here. When it comes to suspend it is unspecified, NOT specified-per-platform. The documentation is very explicit about this (even though it does not have to be, anything not explicitly specified is, well, unspecified):
Which means we could flip a coin at each program startup to choose between CLOCK_BOOTTIME and CLOCK_MONOTONIC on any platform that has both. Therefore any program that relies on this property has a potential correctness problem on future Rust versions and a portability problem. Changing the behavior to aid crates that want to rely on non-guaranteed behavior is encouraging the wrong thing.
I don't see how it's an improvement. If we just let platform-maintainers do uncoordinated decisions, e.g. if platform A says "we think accounting for suspend should be the default" and platform B says "suspend is not time spent working on anything, therefore shouldn't be included", then To get to an endpoint where Instant can provide a guarantee that suspend is either included or excluded everyone must move in the same direction. But this PR doesn't move in any of those directions. As far as I can tell it's aiming to encourage or enable crate authors to ignore the API contract.
Fuchsia is Tier 2, the target tier policy says that it must not be exclusively useful to a closed group. So we should assume external users do exist. |
My interpretation of
is that was referring to the OS developers changing whatever their main/preferred clock API used for timing, waiting, sleeping etc. and I.e. I understand it as an argument for implementation flexibility, enabled by the current absence of guarantees. Not as an argument for someone wanting to make Hyrum more powerful (more guarantees, less implementation flexibility). So if you want to guarantee more behavior then I think you have to request an API change from the libs-API team. |
This feels rather idealistic. I guarantee you that if you were to actually implement that change to flip a coin on startup and randomly choose a clock, a lot of rust programs in the wild would break. Calling every single one of those programs incorrect is, is in my opinion, an extremely impractical position. Telling contributors that they must modify/fix the standard library whenever they want to make existing software that uses those libraries work on their platform is pretty frustrating. In any case, I think this argumentation is kind of getting us nowhere. How am I expected to make progress here? I have a very simple problem to solve: a large amount of code on Fuchsia that uses
How would the rust library maintainers like us to proceed? (side note: who makes these decisions for the rust community?) |
This option is worse than hyrum's law. Currently this is not even an implementation detail. You want to make this an implementation detail and then turn around and write code that relies on that. So you want to create de-facto API guarantees without using those words. I hope you see how shady this looks. API design does not happen by the process of writing crates that want something, then changing the std implementation and then presenting us with a fait accompli.
Usually platform maintainers are not the same people writing most of the downstream crates for a platform, so they're not in a position where they want to change an std implementation to suit their own crates' needs. If your code needs a novel API guarantee then that is a feature request, one that will require discussion and design work. It's the libs-api team that approves API changes. See https://std-dev-guide.rust-lang.org/development/feature-lifecycle.html Alternatively you can ask the libs-team if this could be considered a bug-fix or quality-of-implementation improvement, though I must say I would oppose that for the reasons I explained above. If you're saying there are lots of programs that are broken unless you use a custom std which changes behavior that sounds like a rather dire situation and I feel that this has not been accurately reflected in previous discussion. It would be helpful to have more context to understand the issue (perhaps not in this PR though). The kind and extent of breakage are we talking about, what are some big offending crates, how are they used, etc. |
We discussed this in the libs-api meeting today. One concern that was raised is that the sleep/timeout APIs all use On a more general note, there isn't really a suitable global policy for whether to include time suspended or not: different call site may want different behavior depending on what is being measured. As such we want to ask: would it be acceptable to leave struct Instant<C: Clock = DefaultClock>;
struct DefaultClock; // Clock used for OS sleep/timeout
struct ContinuousClock; // Clock which counts time in sleep
struct SuspendingClock; // Clock which doesn't count time in sleep
trait Clock: Sealed {
fn now() -> Instant<Self>;
} |
@Amanieu that's along the lines of what @mathukumillia and I were playing around with offline. I've started an experimental port of the standard library over to parameterize the Clock to see how it feels on a large codebase. I'm pretty sure we'd also need to parameterize We also need to figure out how an external library like tokio would map these types to the various syscalls. In tokio-rs/tokio#3185 (comment), on Linux only some of the networking APIs support different clocks. |
We specifically talked about All timeouts/sleeps are only defined against |
Fuchsia and Android both want Instants to progress during periods of suspension, and thus must use CLOCK_BOOTTIME as the backing reference clock.
r? @tmandry