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

time: Event::TimeSystem abstraction to make it feasible to inject time with simulated timers #4257

Merged
merged 65 commits into from
Sep 5, 2018

Conversation

jmarantz
Copy link
Contributor

@jmarantz jmarantz commented Aug 26, 2018

Description: Unifies the TimeSource so that system and monotonic sources are always handled similarly (mocks, real-time, or in the future, simulated), and derives a new interface, Event::TimeSystem, which managers timers. This is a pure refactor; none of the operation or semantics of any production or test code is changed with this PR. This is another step in resolving #4160.

Risk Level: medium, just because PR is large and merge conflicts happen, but it should be pretty safe
Testing: //test/...
Docs Changes: n/a
Release Notes: n/a

…(at least one with my own new assert).

Signed-off-by: Joshua Marantz <[email protected]>
Signed-off-by: Joshua Marantz <[email protected]>
Signed-off-by: Joshua Marantz <[email protected]>
Signed-off-by: Joshua Marantz <[email protected]>
…rkerFactory::createWorker,

Signed-off-by: Joshua Marantz <[email protected]>
…nt an assert and made it not fire.

Signed-off-by: Joshua Marantz <[email protected]>
…eeds is a MonotonicTimeSource, so no need for the added test complexity.

Signed-off-by: Joshua Marantz <[email protected]>
Signed-off-by: Joshua Marantz <[email protected]>
Signed-off-by: Joshua Marantz <[email protected]>
Signed-off-by: Joshua Marantz <[email protected]>
Signed-off-by: Joshua Marantz <[email protected]>
This reverts commit 5338985.

Signed-off-by: Joshua Marantz <[email protected]>
Signed-off-by: Joshua Marantz <[email protected]>
Signed-off-by: Joshua Marantz <[email protected]>
Signed-off-by: Joshua Marantz <[email protected]>
…to use

'SimulatedTestTime' which hasn't been built yet.

Signed-off-by: Joshua Marantz <[email protected]>
Signed-off-by: Joshua Marantz <[email protected]>
…if they are not copyable.

Signed-off-by: Joshua Marantz <[email protected]>
…Source as distinct class hierarchies.

Signed-off-by: Joshua Marantz <[email protected]>
@jmarantz jmarantz changed the title WIP: Event::TimeSystem abstraction to make it feasible to inject time with simulated timers time: Event::TimeSystem abstraction to make it feasible to inject time with simulated timers Aug 29, 2018
@dnoe
Copy link
Contributor

dnoe commented Aug 29, 2018

Does removal of the WIP imply this one is ready for reviewer assignment?

@jmarantz
Copy link
Contributor Author

Yes I think this is ready for review.

@dnoe dnoe self-assigned this Aug 29, 2018
Copy link
Contributor

@dnoe dnoe left a comment

Choose a reason for hiding this comment

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

I really like the better support for simulated time here, and getting all of this infrastructure in place will make it much easier to do things that have been tricky in the past.

A few nits and some feedback about using duration_cast to address.

typedef std::unique_ptr<TimerFactory> TimerFactoryPtr;

/**
* Captures a system for measuring time and setting timers with callbacks.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: This phrase seems weird to me, both the use of "Captures" (I think you mean that this interface includes both measuring time and setting timers) and the fact that it sounds like it allows you to set timers using a callback, but I think it actually allows you to set timers that call callbacks when the timer fires.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

reworded:

/**
 * Interface providing a mechanism to measure time and set timers that run callbacks
 * when the timer fires.
 */

@@ -194,8 +195,9 @@ class Instance {

/**
* @return the time source used for the server.
* TODO(jmarantz): rename this to timeSystem().
Copy link
Contributor

Choose a reason for hiding this comment

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

Above you had a PR number for the timeSystem() rename TODO, might want to be consistent either way.

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

source/common/common/utility.h Outdated Show resolved Hide resolved
source/common/event/dispatcher_impl.h Show resolved Hide resolved
} else {
std::chrono::microseconds us = std::chrono::duration_cast<std::chrono::microseconds>(d);
timeval tv;
tv.tv_sec = us.count() / 1000000;
Copy link
Contributor

Choose a reason for hiding this comment

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

The conversion factors here could be more readable by using duration cast:

auto secs = std::chrono::duration_cast<std::chrono::seconds>(d);
auto usecs = std::chrono::duration_cast<std::chrono::microseconds>(d - secs);
tv.tv_secs = secs.count();
tv.tv_usecs = usecs.count();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, but I have strictly moved this code verbatim from timer_impl.h and would prefer not to rewrite it in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I decided to restore timer_impl.h and timer_impl.cc which reveals the 'verbatim' note above to be a lie; there is a slight change which is more visible now (the timers are constructed with a libevent base rather than a dispatcher).

I did this in anticipation of delegating to real-time TimerImpl when building simulated-time TimerImpl in the next PR, but it also makes this diff cleaner :). In simulated time, the real-time timer delegate won't be enabled until the simulated time has advanced enough for it to fire, but I still want it to fire via the libevent dispatcher mechanism.

namespace Event {

/**
* Real-time implementation of TimeSystem.
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment here - RealTimeSystem reads OK, but "Real-time" makes it sound like it's some extra high resolution thing. How about "Real clock implementation of TimeSystem"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to "Real-world time"

@@ -13,16 +13,11 @@ class DangerousDeprecatedTestTime {
public:
DangerousDeprecatedTestTime();

TimeSource& timeSource() { return time_source_; }
// TODO(jmarantz) rename this method and all call-sites to timeSystem().
Copy link
Contributor

Choose a reason for hiding this comment

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

Use PR/issue number TODO?

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

@@ -26,7 +26,9 @@
# Files matching these exact names can reference prod time. These include the class
# definitions for prod time, the construction of them in main(), and perf annotation.
# For now it includes the validation server but that really should be injected too.
PROD_TIME_WHITELIST = ('./source/common/common/utility.h',
REAL_TIME_WHITELIST = ('./source/common/common/utility.h',
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you update the comment above to consistently refer to this as "real clock time" or whatever sounds good? It still calls it "prod time" in the comment.

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

@@ -77,8 +79,8 @@ def whitelistedForProtobufDeps(file_path):
# Production time sources should not be instantiated in the source, except for a few
Copy link
Contributor

Choose a reason for hiding this comment

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

Real clock time sources should not be...

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

if not whitelistedForProdTime(file_path):
if 'ProdSystemTimeSource' in line or 'ProdMonotonicTimeSource' in line:
if not whitelistedForRealTime(file_path):
if 'RealTimeSource' in line or 'RealTimeSystem' in line:
reportError("Don't reference real-time sources from production code; use injection")
Copy link
Contributor

Choose a reason for hiding this comment

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

I realize this isn't in your PR, but I still think we should lose the dash in real-time since it make it sound like a RTOS reference.

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

Signed-off-by: Joshua Marantz <[email protected]>
Signed-off-by: Joshua Marantz <[email protected]>
… use thread-safe post() to wake up the correct threads.

Signed-off-by: Joshua Marantz <[email protected]>
…asier to use thread-safe post() to wake up the correct threads."

This reverts commit 3fe902f.

Signed-off-by: Joshua Marantz <[email protected]>
Copy link
Contributor

@dnoe dnoe left a comment

Choose a reason for hiding this comment

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

I'm not sure I understood your comment about not using duration_cast. I'd definitely prefer to see the more idiomatic C++ style way rather than math on struct timeval with ones-with-lots-of-zeros code, so if it won't be fixed in this PR can you create a GH issue and TODO for cleaning it up?

@@ -96,7 +96,7 @@ class AccessLogDateTimeFormatter {
};

/**
* Real-time implementation of TimeSource.
* Real-world time implementation of TimeSource.
Copy link
Contributor

Choose a reason for hiding this comment

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

Perfect wording, thanks!

@jmarantz
Copy link
Contributor Author

jmarantz commented Sep 4, 2018

Added TODO for duration_cast hacking.

@dnoe
Copy link
Contributor

dnoe commented Sep 4, 2018

Assigned @htuch for senior maintainer.

Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

Looks like a nice cleanup.

@htuch htuch merged commit c6bfc7d into envoyproxy:master Sep 5, 2018
@jmarantz jmarantz deleted the mock-time-for-gzip-test branch September 5, 2018 00:08
htuch pushed a commit that referenced this pull request Sep 7, 2018
…stem() as appropriate (#4343)

In #4257, Event::TimeSystem was introduced to augment the TimeSource abstraction to include timers. Most places in the system that had previously held onto a TimeSource held it in a member variable time_source_ and, if appropriate, exposed it as a method timeSource(), and #4257 changed those to Event::TimeSystem without renaming them, in order to minimize diffs. This PR just renames the members and methods to time_system_ and timeSystem() as appropriate. This is part of the chain of CLs to resolve #4160.

Risk Level: low -- no functional risk, but depending on timing of when this gets merged, an easily-remedied build breakage could arise.
Testing: //test/...
Docs Changes: n/a
Release Notes: n/a

Signed-off-by: Joshua Marantz <[email protected]>
rshriram pushed a commit to rshriram/envoy that referenced this pull request Oct 30, 2018
Pulling the following changes from github.com/envoyproxy/envoy:

f936fc6 ssl: serialize accesses to SSL socket factory contexts (envoyproxy#4345)
e34dcd6 Fix crash in tcp_proxy (envoyproxy#4323)
ae6a252 router: fix matching when all domains have wildcards (envoyproxy#4326)
aa06142 test: Stop fake_upstream methods from accidentally succeeding (envoyproxy#4232)
5d73187 rbac: update the authenticated.user to a StringMatcher. (envoyproxy#4250)
c6bfc7d time: Event::TimeSystem abstraction to make it feasible to inject time with simulated timers (envoyproxy#4257)
752483e Fixing the fix (envoyproxy#4333)
83487f6 tls: update BoringSSL to ab36a84b (3497). (envoyproxy#4338)
7bc210e test: fixing interactions between waitFor and ignore_spurious_events (envoyproxy#4309)
69474b3 admin: order stats in clusters json admin (envoyproxy#4306)
2d155f9 ppc64le build (envoyproxy#4183)
07efc6d fix static initialization fiasco problem (envoyproxy#4314)
0b7e3b5 test: Remove declared but undefined class methods (envoyproxy#4297)
1485a13 lua: make sure resetting dynamic metadata wrapper when request info is marked dead
d243cd6 test: set to zero when start_time exceeds limit (envoyproxy#4328)
0a1e92a test: fix heap use-after-free in ~IntegrationTestServer. (envoyproxy#4319)
cddc732 CONTRIBUTING: Document 'kick-ci' trick. (envoyproxy#4335)
f13ef24 docs: remove reference to deprecated value field (envoyproxy#4322)
e947a27 router: minor doc fixes in stream idle timeout (envoyproxy#4329)
0c2e998 tcp-proxy: fixing a TCP proxy bug where we attempted to readDisable a closed connection (envoyproxy#4296)
00ffe44 utility: fix strftime overflow handling. (envoyproxy#4321)
af1183c Re-enable TcpProxySslIntegrationTest and make the tests pass again. (envoyproxy#4318)
3553461 fuzz: fix H2 codec fuzzer post envoyproxy#4262. (envoyproxy#4311)
42f6048 Proto string issue fix (envoyproxy#4320)
9c492a0 Support Envoy to fetch secrets using SDS service. (envoyproxy#4256)
a857219 ratelimit: revert `revert rate limit failure mode config` and add tests (envoyproxy#4303)
1d34172 dns: fix exception unsafe behavior in c-ares callbacks. (envoyproxy#4307)
1212423 alts: add gRPC TSI socket (envoyproxy#4153)
f0363ae fuzz: detect client-side resets in H2 codec fuzzer. (envoyproxy#4300)
01aa3f8 test: hopefully deflaking echo integration test (envoyproxy#4304)
1fc0f4b ratelimit: link legacy proto when message is being used (envoyproxy#4308)
aa4481e fix rare List::remove(&target) segfault (envoyproxy#4244)
89e0f23 headers: fixing fast fail of size-validation (envoyproxy#4269)
97eba59 build: bump googletest version. (envoyproxy#4293)
0057e22 fuzz: avoid false positives in HCM fuzzer. (envoyproxy#4262)
9d094e5 Revert ac0bd74 (envoyproxy#4295)
ddb28a4 Add validation context provider (envoyproxy#4264)
3b47cba added histogram latency information to Hystrix dashboard stream (envoyproxy#3986)
cf87d50 docs: update SNI FAQ. (envoyproxy#4285)
f952033 config: fix update empty stat for eds (envoyproxy#4276)
329e591 router: Add ability of custom headers to rely on per-request data (envoyproxy#4219)
68d20b4  thrift: refactor build files and imports (envoyproxy#4271)
5fa8192 access_log: log requested_server_name in tcp proxy (envoyproxy#4144)
fa45bb4 fuzz: libc++ clocks don't like nanos. (envoyproxy#4282)
53f8944 stats: add symbol table for future stat name encoding (envoyproxy#3927)
c987b42 test infra: Remove timeSource() from the ClusterManager api (envoyproxy#4247)
cd171d9 websocket: tunneling websockets (and upgrades in general) over H2 (envoyproxy#4188)
b9dc5d9 router: disallow :path/host rewriting in request_headers_to_add. (envoyproxy#4220)
0c91011 network: skip socket options and source address for UDS client connections (envoyproxy#4252)
da1857d build: fixing a downstream compile error by noting explicit fallthrough (envoyproxy#4265)
9857cfe fuzz: cleanup per-test environment after each fuzz case. (envoyproxy#4253)
52beb06 test: Wrap proto string in std::string before comparison (envoyproxy#4238)
f5e219e extensions/thrift_proxy: Add header matching to thrift router (envoyproxy#4239)
c9ce5d2 fuzz: track read_disable_count bidirectionally in codec_impl_fuzz_test. (envoyproxy#4260)
35103b3 fuzz: use nanoseconds for SystemTime in RequestInfo. (envoyproxy#4255)
ba6ba98 fuzz: make runtime root hermetic in server_fuzz_test. (envoyproxy#4258)
b0a9014 time: Add 'format' test to ensure no one directly instantiates Prod*Time from source. (envoyproxy#4248)
8567460 access_log: support beginning of epoch in START_TIME. (envoyproxy#4254)
28d5f41 proto: unify envoy_proto_library/api_proto_library. (envoyproxy#4233)
f7d3cb6 http: fix allocation bug introduced in envoyproxy#4211. (envoyproxy#4245)

Fixes istio/istio#8310 (once pulled into istio/istio).

Signed-off-by: Piotr Sikora <[email protected]>
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.

3 participants