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

Make SystemClock into a Customizable Class #8636

Closed
wants to merge 15 commits into from

Conversation

mrambacher
Copy link
Contributor

Made SystemClock into a Customizable class, complete with CreateFromString.

Cleaned up some of the existing SystemClock implementations that were redundant (NoSleep was the same as the internal one for MockEnv).

Changed MockEnv construction to allow Clock to be passed to the Memory/MockFileSystem.

// The name of this system clock
virtual const char* Name() const = 0;

static const char* kDefaultName() { return "DefaultClock"; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Why we need the kDefaultName() here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are two classes (Posix and Windows) which are both default, so both of these classes return true for IsInstanceOf(kDefaultName).

Additionally, you can get an instance of the default system clock via SystemClock::CreateFromString(kDefaultName, ...)

And address PR comments
During merge, the registration of the MockSystemClock was missed
@facebook-github-bot
Copy link
Contributor

@mrambacher has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@@ -108,7 +109,7 @@ class BlobFileBuilderTest : public testing::Test {
ASSERT_EQ(footer.expiration_range, ExpirationRange());
}

MockEnv mock_env_;
Copy link
Contributor

Choose a reason for hiding this comment

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

Any essential need to change to std::unique_ptr?

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 allows me to make the MockEnv constructor private. The MockFileSystem requires a Clock at the time it is being created, which requires two steps.

env/mock_env.h Outdated
explicit FakeSleepSystemClock(const std::shared_ptr<SystemClock>& c)
: SystemClockWrapper(c), fake_sleep_micros_(0) {}

void SleepForMicroseconds(int micros) override {
Copy link
Contributor

Choose a reason for hiding this comment

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

I may use "FakeSleepForMicroseconds" here and also rename the "MockSleepForMicroseconds" to "FakeSleepForMicroseconds", what do you think. Otherwise, the name itself does not provide the information that we "Fake" the sleep action.

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 class is FakeSleepSystemClock. It is meant to override a "Sleep" with a fake. I am not sure how the renaming does what you want?

Copy link
Contributor

@zhichao-cao zhichao-cao Aug 24, 2021

Choose a reason for hiding this comment

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

Right, but after user has something like std::unique_ptr<FakeSleepSystemClock> clock, the will just will clock->SleepForMicroseconds, which can be misleading in the code. I may prefer we keep the "Fake" in the function name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is meant to be a test class that simulates a sleep by just keeping track of the delay and not actually sleeping. If the internal code calls SleepForMicroseconds and this method is called "FakeSleepForMicroseconds", this method/class will have no effect.

The point of this class is to NOT do a real Sleep when the code (internal or test) calls Sleep.

The SpecialEnv class does something similar to sometimes (but not always) override the true sleep.

Copy link
Contributor

@zhichao-cao zhichao-cao left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@facebook-github-bot
Copy link
Contributor

@mrambacher has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@mrambacher has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@mrambacher has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@mrambacher has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@mrambacher has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

This is the implementation of a SystemClock present in SpecialEnv.  The clock is used for MockEnv if no clock is specified.  For the DBTests, the mock env is wrapped by another SpecialEnv with this clock, so there is no reason to do the wrapping again.

At some point, the SpecialEnv will be refactored into a SpecialFS/CompositeEnvWrapper and can then take advantage of this same class.
@facebook-github-bot
Copy link
Contributor

@mrambacher has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@mrambacher has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@mrambacher has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@mrambacher has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.


const char* Name() const override { return "MockSystemClock"; }
MockEnv::MockEnv(Env* env, const std::shared_ptr<FileSystem>& fs,
Copy link
Contributor

Choose a reason for hiding this comment

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

The new TimeElapesSystemClock class looks good to me in general (the name may not be that appropriate......). Can you describe what's the testing failure when using MockSystemClock and why it is resolved in current implementation?

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 TimeElapseSystemClock was extracted from SpecialEnv. Feel free to suggest a better name. SpecialClock sounded nondescript and there is another class already called MockSystemClock.

There were some failures with the "FakeSystemClock" when running under MEM_ENV. The problem is that the SpecialEnv would do a "Sleep" and defer to the wrapper clock, which in this case was a FakeSystemClock that did a fake sleep. Tests that were depending on a real sleep would therefore fail. I believe the failures were typically around the rate limiter tests but my recollection may be off.


namespace ROCKSDB_NAMESPACE {
// A SystemClock that can "mock" sleep and counts its operations.
class TimeElapseSystemClock : public SystemClockWrapper {
Copy link
Contributor

Choose a reason for hiding this comment

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

how about "TimeEmulatedSystemClock"?


bool IsTimeElapseOnlySleep() const { return time_elapse_only_sleep_.load(); }
void SetMockSleep(bool enabled = true) { no_slowdown_ = enabled; }
bool UseMockSleep() const { return no_slowdown_; }
Copy link
Contributor

Choose a reason for hiding this comment

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

"UseMockSleep()" -> "IsMockSleepUsed()"

Rename TimeElapsedSystemClock to EmulatedSystemClock, to address PR comments.
@facebook-github-bot
Copy link
Contributor

@mrambacher has updated the pull request. You must reimport the pull request before landing.

Copy link
Contributor

@zhichao-cao zhichao-cao left a comment

Choose a reason for hiding this comment

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

LGTM, do remember to mention in HISTORY.md that customizable class is extended to SystemClock. And also, even EmulatedSystemClock is not a public API, we may need to inform user this new class.

@facebook-github-bot
Copy link
Contributor

@mrambacher has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@mrambacher has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@mrambacher merged this pull request in 6924869.

yoori pushed a commit to yoori/rocksdb that referenced this pull request Nov 26, 2023
Summary:
Made SystemClock into a Customizable class, complete with CreateFromString.

Cleaned up some of the existing SystemClock implementations that were redundant (NoSleep was the same as the internal one for MockEnv).

Changed MockEnv construction to allow Clock to be passed to the Memory/MockFileSystem.

Pull Request resolved: facebook/rocksdb#8636

Reviewed By: zhichao-cao

Differential Revision: D30483360

Pulled By: mrambacher

fbshipit-source-id: cd0e3a876c39f8c98fe13374c06e8edbd5b9f2a1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants