cpp_client_telemetry
cpp_client_telemetry copied to clipboard
Time should be represented internally by std::chrono types
Problem Right now, time points and durations are represented by a pletora of types (to name a few): int, unsigned, uint64_t, int64_t
This is undesirable, as not only is it inconsistent, but C++11 introduces the chrono header, which provides both: std::chrono::time_point - A representation of a point in time. std::chrono::duration - A representation of the span between two points in time.
Proposed Solution Standardize on std::chrono types for representing durations and points in time. Use these types everywhere possible (it may not be doable in the C-API). Serialize these values to the appropriate CS types during serialization, not before.
To start, the PAL methods which return the current time should be updated to return a std::chrono type. This way, the epoch can be controlled from a central point and differing OS epochs (.NET, Win32, UNIX, etc.) can be abstracted away from the caller.
Non Goals Will not address time representations in the public API surface of the SDK, as that's a bigger conversation.
I disagree with this proposal. It is convenient and generally suitable for a timepoint to be represented in a simple type, such as uint64_t inside the SDK. This is not something that is exposed on API surface to the customer.
How is using a std::chrono type inconvenient?
Not only does it prevent mistakes from assumptions around the period of the data (does the uint64_t represent seconds? milliseconds? nanoseconds? 100ns (like ETW)?), it allows does the time related math for you (e.g. no manually multiplying by 1000 to go from seconds to milliseconds) as well as the useful helpers of: time_point + duration = time_point; duration + duration = duration; (check out std::chrono::duration_cast, it's super neato) time_point - time_point = duration;
All this is done in a type-safe manner, and will produce errors at compile time (rather than run-time) if a conversion cannot be performed. We should not let developer convenience trump correctness, and prevent an easy class of bugs all-together by leveraging the type system.
Addendum: The Mars Climate Orbiter's crash is the best example of why we should take advantage of the type-system to prevent bugs.
Thanks for bringing this up @mkoscumb, good topic!
For interface (e.g. exposed APIs, data types, schema), we should follow something like ISO 8601, we should not expose implementation detail (e.g. types that are specific to OS, runtime or language) via the interface unless we have a good control of the ABI.
For implementation (e.g. the internal data exchange within the SDK), having a consistent data format is great, as long as the data format we choose meets with the following criteria:
- It is widely adopted and is considered the de facto standard.
- It has a good performance, and works across the targeted platforms/runtimes.
- It is language idiomatic.
@mkoscumb - this one appears to be stale. Do you have some thoughts on further improvements or can we close it?