Skip to content
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

event: create timer from ScaledRangeTimerManager #13524

Merged
merged 11 commits into from
Oct 21, 2020

Conversation

akonradi
Copy link
Contributor

Commit Message: Create TimerPtr from ScaledRangeTimerManager
Additional Description:
Split ScaledRangeTimerManager out as an interface, and add a new method to return
an implementation of the Timer interface directly, in addition to the method that returns
a RangeTimerImpl instance.

Risk Level: low
Testing: added unit tests
Docs Changes: n/a
Release Notes: n/a

This will allow mocking for users of the timer manager.

Signed-off-by: Alex Konradi <akonradi@google.com>
Add a method to ScaledRangeTimerManager to return a TimerPtr that wraps
a RangeTimerImpl. While the wrapper could be implemented externally by
wrapping a RangeTimerPtr, wrapping the impl class is more efficient
since it requires less indirection and fewer heap allocations.

Signed-off-by: Alex Konradi <akonradi@google.com>
Copy link
Contributor

@antoniovicente antoniovicente left a comment

Choose a reason for hiding this comment

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

Great improvement to the scaled timer internal APIs. Thanks for splitting this off into a separate change and adding appropriate tests.

include/envoy/event/scaled_range_timer_manager.h Outdated Show resolved Hide resolved
source/common/event/scaled_range_timer_manager_impl.cc Outdated Show resolved Hide resolved
source/common/event/scaled_range_timer_manager_impl.cc Outdated Show resolved Hide resolved
source/common/event/scaled_range_timer_manager_impl.cc Outdated Show resolved Hide resolved
test/common/event/scaled_range_timer_manager_impl_test.cc Outdated Show resolved Hide resolved
test/common/event/scaled_range_timer_manager_impl_test.cc Outdated Show resolved Hide resolved

// With the default scale factor of 1, the timer should fire at its maximum timeout.
MockFunction<TimerCb> callback;
auto timer = manager.createTimer(ScaleFactor(0.5), callback.AsStdFunction());
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if ScaleFactor is set to 100?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's the same as providing a min time to a range timer that's larger than max. The max will always be honored.

Copy link
Contributor

Choose a reason for hiding this comment

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

My read of RangeTimerImpl::enableTimer is that the min is honored, not the max.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, what I meant was that the lesser of {min, max} will always be honored. So if min > max, then max is honored.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

...and I see that the code was buggy. Added some tests and fixed it.

test/server/overload_manager_impl_test.cc Outdated Show resolved Hide resolved
// With the default scale factor of 1, the timer should fire at its maximum timeout.
MockFunction<TimerCb> callback;
auto timer =
manager.createTimer(AbsoluteValue(std::chrono::seconds(3)), callback.AsStdFunction());
Copy link
Contributor

Choose a reason for hiding this comment

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

Remind me, what happens when the max is smaller than an absolute min? Which of the two values wins? It seems to me that the max should win since it's the one that is more explicitly configured.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The max is always honored, even if the min is larger than the max.

Copy link
Contributor

Choose a reason for hiding this comment

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

My read of RangeTimerImpl::enableTimer is that the min is honored, not the max.

Signed-off-by: Alex Konradi <akonradi@google.com>
Explicitly provide the template parameters to absl::visit since
using deduction causes Windows builds to fail. It appears that there is
an internal instantiation of std::variant_size, which doesn't work with
subclasses of absl::variant.

Signed-off-by: Alex Konradi <akonradi@google.com>
Signed-off-by: Alex Konradi <akonradi@google.com>
…rface

Signed-off-by: Alex Konradi <akonradi@google.com>
…rface

Signed-off-by: Alex Konradi <akonradi@google.com>
Signed-off-by: Alex Konradi <akonradi@google.com>
Signed-off-by: Alex Konradi <akonradi@google.com>
antoniovicente
antoniovicente previously approved these changes Oct 19, 2020
@asraa
Copy link
Contributor

asraa commented Oct 20, 2020

@mattklein123 Do you have time for a non-googler/senior maintainer pass? Or pass back, thank you!

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Thanks LGTM with a few small comments. Thank you!

/wait

* Describes a minimum timer value that is equal to a scale factor applied to the maximum.
*/
struct ScaledMinimum {
explicit ScaledMinimum(double scale_factor) : scale_factor_(scale_factor) {}
Copy link
Member

Choose a reason for hiding this comment

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

I think this is the wrapper I was suggesting in the previous PR? Do we assume that this is between 0.0 and 1.0? Can we document that and ASSERT that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As mentioned below, I'm going to leave this for a refactoring PR.

* controls the minimum. Passing a value of ScaleFactor(x) sets the min to (x * max) when the
* timer is enabled, while AbsoluteValue(y) sets the min to the duration y.
*/
virtual TimerPtr createTimer(ScaledTimerMinimum minimum, TimerCb callback) PURE;
Copy link
Member

Choose a reason for hiding this comment

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

Can RangeTimer just derive from Timer? It seems like we could avoid by allowing a RangeTimer to also be stored as a normal timer if needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the RangeTimer interface is destined for the bit bucket; we don't need it for any consumer code now that we have a createTimer method and it's not used anywhere. I think we should just remove it. Thoughts on doing that in this PR or another one?

Copy link
Member

Choose a reason for hiding this comment

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

Just do it!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, PTAL.

* duration, a factor of 0.5 causes firing halfway between min and max, and a factor of 1 causes
* firing at max.
*/
virtual void setScaleFactor(double scale_factor) PURE;
Copy link
Member

Choose a reason for hiding this comment

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

Should this take a ScaledMinimum (or similar) which can better ASSERT that it's between 0.0 and 1.0 and then clamp if needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Between here and the OverloadAction class, I think it would be a good idea to have a single simple wrapper class that enforces 0.0 and 1.0 bounds. I'm going to do that in a future PR.

Signed-off-by: Alex Konradi <akonradi@google.com>
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Thanks!

@mattklein123
Copy link
Member

I think this might be hung due to an AZP outage. Can you try merging main?

/wait

…rface

Signed-off-by: Alex Konradi <akonradi@google.com>
@mattklein123 mattklein123 merged commit 7e799c5 into envoyproxy:master Oct 21, 2020
@akonradi akonradi deleted the scaled-timer-interface branch October 21, 2020 17:43
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.

4 participants