-
-
Notifications
You must be signed in to change notification settings - Fork 632
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 more consistent time representation throughout the engine #8143
Use more consistent time representation throughout the engine #8143
Conversation
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
span.stop() | ||
|
||
def from_secs_and_nanos_to_float(secs, nanos): | ||
return secs + nanos/NUM_NANOSECS_IN_SEC |
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.
feel free to ignore, but some parens around the division would make me feel good.
src/python/pants/engine/native.py
Outdated
c = self._ffi.from_handle(context_handle) | ||
return c.to_value(u64) | ||
|
||
@_extern_decl('Handle', ['ExternContext*', 'uint32_t']) |
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.
So, because python doesn't really differentiate between these types, there isn't really much advantage to having all of these methods. You could probably drop uint32_t
and cast on the rust side to widen things to 64.
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.
That's fair enough. I saw this as a tad more explicit, but it's true that it may be seen as unnecessary. I'll follow your advice.
@@ -15,6 +15,7 @@ | |||
|
|||
logger = logging.getLogger(__name__) | |||
|
|||
NUM_NANOSECS_IN_SEC = 1000000000.0 |
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.
The _IN_SEC
suffix here looks like we're describing the unit of this variable, which is a bit confusing. Maybe NANOSECONDS_PER_SECOND
or something?
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.
It might be cleaner just to define a const NANOSECOND = 10^-9 then you would multiply instead of divide.
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 kind of like Stu's suggestion of NANOSECONDS_PER_SECONDS a bit better because the name is explicit. Will go with it.
c92ee08
to
0403383
Compare
Actioned the code review comment and fixed a python formatting error. (I edited the existing commits out of habit, although with our squash-on-merge strategy, I may as well have created new commits). The diff can be seen in the github UI by checking the "force-pushed" hyperlink. |
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, modulo the comments.
/// A timespan | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] | ||
pub struct TimeSpan { | ||
/// Duration since the UNIX_EPOCH |
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 found this comment confusing (in part because didn't read the names of the bound variables). I interpreted it as "Duration from UNIX_EPOCH until the end of this timespan".
/// Duration since the UNIX_EPOCH | |
/// Duration from the UNIX_EPOCH to the start of this TimeSpan. |
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.
Uhm. Not sure about this. Comments apply to the line directly below them, so I thing avoiding the repetition is better. If I mention "the start of this TimeSpan" and then rename start
or TimeSpan
for some reason, I'll have to edit the comment to keep in sync, which the compiler won't help me with.
duration: duration.into(), | ||
}); | ||
if time_span.is_none() { | ||
warn!( |
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.
Should this just crash? I'll look through the usages, but it doesn't look like returning None
is what we want to do.
I think I'd prefer just crashing, or returning a Result<Timespan, String>
or something like this.
Would also be okay to leave it as a TODO:
warn!( | |
// TODO Make this return a Result<> or panic instead of just warning. | |
warn!( |
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 see your point, and it may be worth doing in a separate PR. The reason I'm only warning here is because this change is a simple refactoring, so I'm not aiming to change the behaviour too significantly. You can find the old behaviour in src/rust/engine/process_execution/src/remote.rs (duplicated a few times).
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 could return an Err from here and warn at the call site, though.
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.
Addressed in an extra commit
Thanks for the code review 😄 I addressed the comments |
One of the CI failures is legit: forgot to run (and update) the tests after my last add-on commit. Fix coming. |
2bd6a7f
to
93ee5ca
Compare
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.
Looks great, thanks!
Are we actually using the serde-ness anywhere? If not, may be worth skipping it until we need it (because compile times).
Yes, we are. For instance, we serialize metadata to json in fs_util. |
The failures in travis look like a corrupted 3rdparty artifact in the cache. I've cleared the caches for this PR and will restart. |
To represent timestamps and durations, we used to use a mix of various strategies: * `f64` representing a number of seconds * `time::Timespec` * `protobuf::well_known_type::Timestamp` A span of time was sometimes represented as * a start and an end timestamp, or * a start and a duration This lead to many little helper functions converting from one type of time representation to another, which caused clutter. There were valid reasons for alternating between different representations. For instance, we sometimes wanted a timestamp that could be serialized and an `f64` filled that role. We sometimes wanted a timestamp that was more strongly typed, and a `time::Timespec` filled that role, despite coming from a deprecated crate. In general, we should use `std::time` for time operations, but these types don't lend themselves to serialization as they explicitely avoid exposing their internals through serialization or otherwise to avoid misleading programmers into serializing a timestamp, checking it on a different machine with a different timezone and ending up with broken assumptions. Since we do want to serialize durations (since EPOCH, so a timestamp or since another duration), create a simple struct called `concrete_time::Duration` that can seemlessly be converted from and into a `std::time::Duration` and that can also be serialized. For convenience, also create a `TimeSpan` that encapsulates the idea of starting at some point and ending at some other point. Give it constructors that make sense given the contexts in which we populate timespans (from protobuf and from measurements). Also change the ffi boundary to push the float representation of time as far as possible, to the py_zipkin interface; so the python code can more conveniently compare timestamps for equality in tests. Note that brfs was purposefully omitted from the homogeneisation effort as it only used `time::Timespec` without any conversions and that is what the `fuse` API expects.
Let the caller decide how to deal with the error case (by warning)
93ee5ca
to
a1ed999
Compare
Huge number of network flakes. Cleared caches for those and restarted. |
Thanks for this 👍 |
To represent timestamps and durations, we used to use a mix of various
strategies:
f64
representing a number of secondstime::Timespec
protobuf::well_known_type::Timestamp
A span of time was sometimes represented as
This lead to many little helper functions converting from one type of
time representation to another, which caused clutter.
There were valid reasons for alternating between different
representations. For instance, we sometimes wanted a timestamp that
could be serialized and an
f64
filled that role.We sometimes wanted a timestamp that was more strongly typed, and a
time::Timespec
filled that role, despite coming from a deprecatedcrate.
In general, we should use
std::time
for time operations, but thesetypes don't lend themselves to serialization as they explicitely avoid
exposing their internals through serialization or otherwise to avoid
misleading programmers into serializing a timestamp, checking it on a
different machine with a different timezone and ending up with broken
assumptions.
Since we do want to serialize durations (since EPOCH, so a timestamp or
since another duration), create a simple struct called
concrete_time::Duration
that can seemlessly be converted from and intoa
std::time::Duration
and that can also be serialized.For convenience, also create a
TimeSpan
that encapsulates the idea ofstarting at some point and ending at some other point. Give it
constructors that make sense given the contexts in which we populate
timespans (from protobuf and from measurements).
Also change the ffi boundary to push the float representation of time as
far as possible, to the py_zipkin interface; so the python code can more
conveniently compare timestamps for equality in tests.
Note that brfs was purposefully omitted from the homogeneisation effort
as it only used
time::Timespec
without any conversions and that iswhat the
fuse
API expects.