From 46acfcb8fced24ff96933fc2208c3c77308470c8 Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Thu, 8 Apr 2021 09:25:28 -0700 Subject: [PATCH] Allow swapping the clock implementation for TransactionTelemetry Summary: The `TransactionalTelemetryTest`s are flaky because they use a real clock and assert on how much time has passed (with a threshold, but that's no good either). Using the real clock in the test is the cause for the test to be flaky because it depends on the assumption that it's the sole process running, never risking to be put in the process-queue of the OS. However, that's not the case and is why the test sporadically fails if the OS decided to schedule other threads/process in the middle of the test. This diff allows parametrising the `TransactionTelemetry` class with the clock implementation so that tests can use a Mock Clock if desired (separate diff). Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D27618516 fbshipit-source-id: 5a08e115b388398ca2b05b9d5ae0fd281dfe3b04 --- .../telemetry/TransactionTelemetry.cpp | 27 ++++++++++++------- .../renderer/telemetry/TransactionTelemetry.h | 6 +++++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/ReactCommon/react/renderer/telemetry/TransactionTelemetry.cpp b/ReactCommon/react/renderer/telemetry/TransactionTelemetry.cpp index 1b0df9e3185..b7b5fe37c03 100644 --- a/ReactCommon/react/renderer/telemetry/TransactionTelemetry.cpp +++ b/ReactCommon/react/renderer/telemetry/TransactionTelemetry.cpp @@ -14,6 +14,13 @@ namespace react { thread_local TransactionTelemetry *threadLocalTransactionTelemetry = nullptr; +TransactionTelemetry::TransactionTelemetry() + : TransactionTelemetry(telemetryTimePointNow) {} + +TransactionTelemetry::TransactionTelemetry( + std::function now) + : now_{now} {} + TransactionTelemetry *TransactionTelemetry::threadLocalTelemetry() { return threadLocalTransactionTelemetry; } @@ -29,63 +36,63 @@ void TransactionTelemetry::unsetAsThreadLocal() { void TransactionTelemetry::willCommit() { react_native_assert(commitStartTime_ == kTelemetryUndefinedTimePoint); react_native_assert(commitEndTime_ == kTelemetryUndefinedTimePoint); - commitStartTime_ = telemetryTimePointNow(); + commitStartTime_ = now_(); } void TransactionTelemetry::didCommit() { react_native_assert(commitStartTime_ != kTelemetryUndefinedTimePoint); react_native_assert(commitEndTime_ == kTelemetryUndefinedTimePoint); - commitEndTime_ = telemetryTimePointNow(); + commitEndTime_ = now_(); } void TransactionTelemetry::willDiff() { react_native_assert(diffStartTime_ == kTelemetryUndefinedTimePoint); react_native_assert(diffEndTime_ == kTelemetryUndefinedTimePoint); - diffStartTime_ = telemetryTimePointNow(); + diffStartTime_ = now_(); } void TransactionTelemetry::didDiff() { react_native_assert(diffStartTime_ != kTelemetryUndefinedTimePoint); react_native_assert(diffEndTime_ == kTelemetryUndefinedTimePoint); - diffEndTime_ = telemetryTimePointNow(); + diffEndTime_ = now_(); } void TransactionTelemetry::willLayout() { react_native_assert(layoutStartTime_ == kTelemetryUndefinedTimePoint); react_native_assert(layoutEndTime_ == kTelemetryUndefinedTimePoint); - layoutStartTime_ = telemetryTimePointNow(); + layoutStartTime_ = now_(); } void TransactionTelemetry::willMeasureText() { react_native_assert( lastTextMeasureStartTime_ == kTelemetryUndefinedTimePoint); - lastTextMeasureStartTime_ = telemetryTimePointNow(); + lastTextMeasureStartTime_ = now_(); } void TransactionTelemetry::didMeasureText() { numberOfTextMeasurements_++; react_native_assert( lastTextMeasureStartTime_ != kTelemetryUndefinedTimePoint); - textMeasureTime_ += telemetryTimePointNow() - lastTextMeasureStartTime_; + textMeasureTime_ += now_() - lastTextMeasureStartTime_; lastTextMeasureStartTime_ = kTelemetryUndefinedTimePoint; } void TransactionTelemetry::didLayout() { react_native_assert(layoutStartTime_ != kTelemetryUndefinedTimePoint); react_native_assert(layoutEndTime_ == kTelemetryUndefinedTimePoint); - layoutEndTime_ = telemetryTimePointNow(); + layoutEndTime_ = now_(); } void TransactionTelemetry::willMount() { react_native_assert(mountStartTime_ == kTelemetryUndefinedTimePoint); react_native_assert(mountEndTime_ == kTelemetryUndefinedTimePoint); - mountStartTime_ = telemetryTimePointNow(); + mountStartTime_ = now_(); } void TransactionTelemetry::didMount() { react_native_assert(mountStartTime_ != kTelemetryUndefinedTimePoint); react_native_assert(mountEndTime_ == kTelemetryUndefinedTimePoint); - mountEndTime_ = telemetryTimePointNow(); + mountEndTime_ = now_(); } void TransactionTelemetry::setRevisionNumber(int revisionNumber) { diff --git a/ReactCommon/react/renderer/telemetry/TransactionTelemetry.h b/ReactCommon/react/renderer/telemetry/TransactionTelemetry.h index 6d06c2e59e7..ab3a398d785 100644 --- a/ReactCommon/react/renderer/telemetry/TransactionTelemetry.h +++ b/ReactCommon/react/renderer/telemetry/TransactionTelemetry.h @@ -9,6 +9,7 @@ #include #include +#include #include @@ -25,6 +26,10 @@ class TransactionTelemetry final { * Thread-local Telemetry instance */ static TransactionTelemetry *threadLocalTelemetry(); + + TransactionTelemetry(); + TransactionTelemetry(std::function now); + void setAsThreadLocal(); void unsetAsThreadLocal(); @@ -75,6 +80,7 @@ class TransactionTelemetry final { int numberOfTextMeasurements_{0}; int revisionNumber_{0}; + std::function now_; }; } // namespace react