Skip to content

Fix ambiguous duration units and add format check#12225

Merged
lizan merged 17 commits intoenvoyproxy:masterfrom
greenhouse-org:fix-ambiguous-std-chrono-duration
Aug 4, 2020
Merged

Fix ambiguous duration units and add format check#12225
lizan merged 17 commits intoenvoyproxy:masterfrom
greenhouse-org:fix-ambiguous-std-chrono-duration

Conversation

@sunjayBhatia
Copy link
Copy Markdown
Member

Commit Message:
Fix ambiguous duration units and add format check

  • ambiguous value-based std::chrono::{clock_type}::duration(value) constructors
    result in stdlib implementation specific default time units which are
    hard to read and potentially different on different platforms
  • this change removes any instances of these ambiguous constructions and adds
    a format check to prevent them; developers should specify an explicit unit of time
  • we explicitly saw this issue in router: add config to send date header with requests #11915 where
    the assumed duration unit was different on Windows, causing test failures

Additional Description:
Risk Level: Low
Testing: Adds format check test and adjust existing unit tests
Docs Changes: N/A
Release Notes: N/A

- ambiguous value-based std::chrono::{clock_type}::duration(value) constructors
  result in stdlib implementation specific default time units which are
  hard to read
- this change removes any instances of these ambiguous constructions and adds
  a format check to prevent them; developers should specify an explicit unit of time
- we explicitly saw this issue in #11915

Co-authored-by: William A Rowe Jr <wrowe@vmware.com>
Signed-off-by: William A Rowe Jr <wrowe@vmware.com>
Co-authored-by: Sunjay Bhatia <sunjayb@vmware.com>
Signed-off-by: Sunjay Bhatia <sunjayb@vmware.com>
@sunjayBhatia
Copy link
Copy Markdown
Member Author

cc @wrowe @davinci26 @nigriMSFT

Copy link
Copy Markdown
Contributor

@rebello95 rebello95 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this lint rule would be good to add 👍

@zuercher zuercher self-assigned this Jul 22, 2020
sunjayBhatia and others added 2 commits July 22, 2020 17:41
Signed-off-by: Sunjay Bhatia <sunjayb@vmware.com>
Signed-off-by: William A Rowe Jr <wrowe@vmware.com>
@zuercher
Copy link
Copy Markdown
Member

There's also this:

https://github.com/envoyproxy/envoy/blob/master/include/envoy/event/timer.h#L83

It doesn't look like TimeSystem::Duration is used anywhere, but it seems like it would have the same problems.

@zuercher
Copy link
Copy Markdown
Member

@jmarantz you may have input on this as well.

wrowe and others added 3 commits July 23, 2020 17:33
- Ensure [Dd]uration is the complete method name
- Allow for unambiguous values 0 or 0.0

Signed-off-by: William A Rowe Jr <wrowe@vmware.com>
…hrono-duration

Signed-off-by: Sunjay Bhatia <sunjayb@vmware.com>
…hrono-duration

Signed-off-by: William A Rowe Jr <wrowe@vmware.com>
@sunjayBhatia
Copy link
Copy Markdown
Member Author

Seems like the ARM job is generally unhealthy on master as well, otherwise i think this is ready?

zuercher
zuercher previously approved these changes Jul 24, 2020
Copy link
Copy Markdown
Member

@zuercher zuercher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I'll circle around and look at the build failures in a bit, but we'll probably need to merge master to pick up some fix before we can merge this.

…hrono-duration

Signed-off-by: Sunjay Bhatia <sunjayb@vmware.com>
@zuercher
Copy link
Copy Markdown
Member

I think Josh is away, @lizan can you have a quick look at this?

@zuercher zuercher assigned lizan and unassigned jmarantz Jul 27, 2020
Copy link
Copy Markdown
Member

@lizan lizan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks good by itself. Though aren't we on a long term path toward absl::Time for all durations/time? Let's define a common duration in TimeSystem (there is already one there but ambiguous) without ambiguity and use them?

…hrono-duration

Signed-off-by: wrowe@vmware.com
@wrowe
Copy link
Copy Markdown
Contributor

wrowe commented Jul 28, 2020

Though aren't we on a long term path toward absl::Time for all durations/time? Let's define a common duration in TimeSystem (there is already one there but ambiguous) without ambiguity and use them?

The issue doesn't change, though. an absl::Duration(1000) construction would be equally ambiguous as the std::chrono classes currently in use, because absl also doesn't define the unit of measure, it instead provides explicit constructors based on the time precision desired (including expressing a duration as a ratio);

https://abseil.io/docs/cpp/guides/time#:~:text=An%20absl%3A%3ADuration%20represents,natural%20integer%2Dlike%20arithmetic%20operations.

It appears that the absl::Duration class doesn't even have a constructor to accept a plain int, so we wouldn't have needed to address that ambiguity, although our code check does note this occurrence whether the author notes the compilation error, or not.

It seems that the effort to convert this MonotonicTime Duration storage falls in the scope of a completely different PR. But as long as we are dealing with so many third party libraries, some of which use std::chrono classes, this particular PR seems like the right immediate approach and a long-term win.

@lizan
Copy link
Copy Markdown
Member

lizan commented Jul 28, 2020

Though aren't we on a long term path toward absl::Time for all durations/time? Let's define a common duration in TimeSystem (there is already one there but ambiguous) without ambiguity and use them?

The issue doesn't change, though. an absl::Duration(1000) construction would be equally ambiguous as the std::chrono classes currently in use, because absl also doesn't define the unit of measure, it instead provides explicit constructors based on the time precision desired (including expressing a duration as a ratio);

https://abseil.io/docs/cpp/guides/time#:~:text=An%20absl%3A%3ADuration%20represents,natural%20integer%2Dlike%20arithmetic%20operations.

It appears that the absl::Duration class doesn't even have a constructor to accept a plain int, so we wouldn't have needed to address that ambiguity, although our code check does note this occurrence whether the author notes the compilation error, or not.

It seems that the effort to convert this MonotonicTime Duration storage falls in the scope of a completely different PR. But as long as we are dealing with so many third party libraries, some of which use std::chrono classes, this particular PR seems like the right immediate approach and a long-term win.

What I'm saying is define a type alias in timesystem for further replacement. That was one of the point using MonotonicTime/SystemTime rather than leaking std::chrono everywhere. You can name it without ambiguity, e.g. 'using DurationMs = std::chrono::milliseconds`?

@sunjayBhatia
Copy link
Copy Markdown
Member Author

sunjayBhatia commented Jul 29, 2020

What I'm saying is define a type alias in timesystem for further replacement. That was one of the point using MonotonicTime/SystemTime rather than leaking std::chrono everywhere. You can name it without ambiguity, e.g. 'using DurationMs = std::chrono::milliseconds`?

Do you want to replace TimeSystem::Duration with something or just add a new concrete duration alias?

Replacing sounds like it would break things like

/**
* Advances time forward by the specified duration, running any timers
* scheduled to fire, and blocking until the timer callbacks are complete.
* See also advanceTimeAsync(), which does not block.
*
* This function should be used in multi-threaded tests, where other
* threads are running dispatcher loops. Integration tests should usually
* use this variant.
*
* @param duration The amount of time to sleep.
*/
virtual void advanceTimeWait(const Duration& duration) PURE;
template <class D> void advanceTimeWait(const D& duration) {
advanceTimeWait(std::chrono::duration_cast<Duration>(duration));
}
/**
* Advances time forward by the specified duration. Timers may be triggered on
* their threads, but unlike advanceTimeWait(), this method does not block
* waiting for them to complete.
*
* This function should be used in single-threaded tests, in scenarios where
* after time is advanced, the main test thread will run a dispatcher
* loop. Unit tests will often use this variant.
*
* @param duration The amount of time to sleep.
*/
virtual void advanceTimeAsync(const Duration& duration) PURE;
template <class D> void advanceTimeAsync(const D& duration) {
advanceTimeAsync(std::chrono::duration_cast<Duration>(duration));
}

e.g.

time_system.advanceTimeWait(std::chrono::microseconds(10));

e.g. https://godbolt.org/z/nKsq7s

the TimeSystem::Duration* type would likely have to be in nanoseconds to encompass all potential uses and all the tests that use the above methods would have to be converted to the equivalent of nanoseconds it seems This is wrong, implicit conversion does happen if a unit can be converted to another, that seems ok, but if a test or something uses a representation or ratio that cannot be converted this will still be an issue

It feels ok to have a generic TimeSystem::Duration type that does not refer to any specific unit to be used like the above, but not ok to try to create a duration using that type b/c it could be ambiguous (which the format check prevents)

@lizan
Copy link
Copy Markdown
Member

lizan commented Jul 30, 2020

I'm OK with either, replacing TimeSystem::Duration sounds good too. What I want to prevent is leaking std::chrono to more places.

…hrono-duration

Signed-off-by: Sunjay Bhatia <sunjayb@vmware.com>
- Makes it more trivial to switch to absl::Duration at some point

Co-authored-by: Sunjay Bhatia <sunjayb@vmware.com>
Co-authored-by: William A Rowe Jr <wrowe@vmware.com>
Signed-off-by: Sunjay Bhatia <sunjayb@vmware.com>
Signed-off-by: William A Rowe Jr <wrowe@vmware.com>

Signed-off-by: Sunjay Bhatia <sunjayb@vmware.com>
@wrowe
Copy link
Copy Markdown
Contributor

wrowe commented Jul 30, 2020

What I want to prevent is leaking std::chrono to more places.

Let us know if the proposed change works for you?

@sunjayBhatia
Copy link
Copy Markdown
Member Author

sunjayBhatia commented Jul 30, 2020

I'm OK with either, replacing TimeSystem::Duration sounds good too. What I want to prevent is leaking std::chrono to more places.

It would slow this patch down to do all the replacement of std::chrono duration types, so we will open an issue for that unless there are objections

(here's the issue: #12384)

@lizan
Copy link
Copy Markdown
Member

lizan commented Jul 30, 2020

I'm OK with either, replacing TimeSystem::Duration sounds good too. What I want to prevent is leaking std::chrono to more places.

It would slow this patch down to do all the replacement of std::chrono duration types, so we will open an issue for that unless there are objections

(here's the issue: #12384)

SGTM. We don't have to do all replacement in this PR.

Signed-off-by: Sunjay Bhatia <sunjayb@vmware.com>
@sunjayBhatia
Copy link
Copy Markdown
Member Author

force pushed just to fix DCO

wrowe and others added 6 commits July 31, 2020 09:54
Signed-off-by: William A Rowe Jr <wrowe@vmware.com>
…hrono-duration

Signed-off-by: William A Rowe Jr <wrowe@vmware.com>
Signed-off-by: Sunjay Bhatia <sunjayb@vmware.com>
Signed-off-by: William A Rowe Jr <wrowe@vmware.com>
…hrono-duration

Signed-off-by: William A Rowe Jr <wrowe@vmware.com>
…hrono-duration

Signed-off-by: Sunjay Bhatia <sunjayb@vmware.com>
Signed-off-by: William A Rowe Jr <wrowe@vmware.com>
@wrowe
Copy link
Copy Markdown
Contributor

wrowe commented Aug 4, 2020

@lizan please review, this seems stalled out for your approval, and now for some new clang-tidy chaos on master?

@lizan lizan merged commit 0b1cf9d into envoyproxy:master Aug 4, 2020
@wrowe wrowe deleted the fix-ambiguous-std-chrono-duration branch August 4, 2020 21:52
chaoqin-li1123 pushed a commit to chaoqin-li1123/envoy that referenced this pull request Aug 7, 2020
- ambiguous value-based std::chrono::{clock_type}::duration(value) constructors
  result in stdlib implementation specific default time units which are
  hard to read and potentially different on different platforms
- this change removes any instances of these ambiguous constructions and adds
  a format check to prevent them; developers should specify an explicit unit of time
- we explicitly saw this issue in envoyproxy#11915 where
  the assumed duration unit was different on Windows, causing test failures

Additional Description:
Risk Level: Low
Testing: Adds format check test and adjust existing unit tests
Docs Changes: N/A
Release Notes: N/A

Signed-off-by: Sunjay Bhatia <sunjayb@vmware.com>
Co-authored-by: William A Rowe Jr <wrowe@vmware.com>
chaoqin-li1123 pushed a commit to chaoqin-li1123/envoy that referenced this pull request Aug 7, 2020
- ambiguous value-based std::chrono::{clock_type}::duration(value) constructors
  result in stdlib implementation specific default time units which are
  hard to read and potentially different on different platforms
- this change removes any instances of these ambiguous constructions and adds
  a format check to prevent them; developers should specify an explicit unit of time
- we explicitly saw this issue in envoyproxy#11915 where
  the assumed duration unit was different on Windows, causing test failures

Additional Description:
Risk Level: Low
Testing: Adds format check test and adjust existing unit tests
Docs Changes: N/A
Release Notes: N/A

Signed-off-by: Sunjay Bhatia <sunjayb@vmware.com>
Co-authored-by: William A Rowe Jr <wrowe@vmware.com>
Signed-off-by: chaoqinli <chaoqinli@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants