Commit 354e50d4 authored by Dan Melnic's avatar Dan Melnic Committed by Facebook GitHub Bot

Add support for microsecond intervals in the function scheduler

Summary: Add support for microsecond intervals in the function scheduler

Reviewed By: arushiagg

Differential Revision: D23433411

fbshipit-source-id: 39d201feaaed8007ec880a799129ed94bedd827a
parent 16d63941
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <folly/String.h> #include <folly/String.h>
#include <folly/system/ThreadName.h> #include <folly/system/ThreadName.h>
using std::chrono::milliseconds; using std::chrono::microseconds;
using std::chrono::steady_clock; using std::chrono::steady_clock;
namespace folly { namespace folly {
...@@ -33,11 +33,11 @@ namespace folly { ...@@ -33,11 +33,11 @@ namespace folly {
namespace { namespace {
struct ConsistentDelayFunctor { struct ConsistentDelayFunctor {
const milliseconds constInterval; const microseconds constInterval;
explicit ConsistentDelayFunctor(milliseconds interval) explicit ConsistentDelayFunctor(microseconds interval)
: constInterval(interval) { : constInterval(interval) {
if (interval < milliseconds::zero()) { if (interval < microseconds::zero()) {
throw std::invalid_argument( throw std::invalid_argument(
"FunctionScheduler: " "FunctionScheduler: "
"time interval must be non-negative"); "time interval must be non-negative");
...@@ -53,18 +53,18 @@ struct ConsistentDelayFunctor { ...@@ -53,18 +53,18 @@ struct ConsistentDelayFunctor {
}; };
struct ConstIntervalFunctor { struct ConstIntervalFunctor {
const milliseconds constInterval; const microseconds constInterval;
explicit ConstIntervalFunctor(milliseconds interval) explicit ConstIntervalFunctor(microseconds interval)
: constInterval(interval) { : constInterval(interval) {
if (interval < milliseconds::zero()) { if (interval < microseconds::zero()) {
throw std::invalid_argument( throw std::invalid_argument(
"FunctionScheduler: " "FunctionScheduler: "
"time interval must be non-negative"); "time interval must be non-negative");
} }
} }
milliseconds operator()() const { microseconds operator()() const {
return constInterval; return constInterval;
} }
}; };
...@@ -73,25 +73,25 @@ struct PoissonDistributionFunctor { ...@@ -73,25 +73,25 @@ struct PoissonDistributionFunctor {
std::default_random_engine generator; std::default_random_engine generator;
std::poisson_distribution<int> poissonRandom; std::poisson_distribution<int> poissonRandom;
explicit PoissonDistributionFunctor(double meanPoissonMs) explicit PoissonDistributionFunctor(microseconds meanPoissonUsec)
: poissonRandom(meanPoissonMs) { : poissonRandom(meanPoissonUsec.count()) {
if (meanPoissonMs < 0.0) { if (meanPoissonUsec.count() < 0) {
throw std::invalid_argument( throw std::invalid_argument(
"FunctionScheduler: " "FunctionScheduler: "
"Poisson mean interval must be non-negative"); "Poisson mean interval must be non-negative");
} }
} }
milliseconds operator()() { microseconds operator()() {
return milliseconds(poissonRandom(generator)); return microseconds(poissonRandom(generator));
} }
}; };
struct UniformDistributionFunctor { struct UniformDistributionFunctor {
std::default_random_engine generator; std::default_random_engine generator;
std::uniform_int_distribution<milliseconds::rep> dist; std::uniform_int_distribution<microseconds::rep> dist;
UniformDistributionFunctor(milliseconds minInterval, milliseconds maxInterval) UniformDistributionFunctor(microseconds minInterval, microseconds maxInterval)
: generator(Random::rand32()), : generator(Random::rand32()),
dist(minInterval.count(), maxInterval.count()) { dist(minInterval.count(), maxInterval.count()) {
if (minInterval > maxInterval) { if (minInterval > maxInterval) {
...@@ -99,15 +99,15 @@ struct UniformDistributionFunctor { ...@@ -99,15 +99,15 @@ struct UniformDistributionFunctor {
"FunctionScheduler: " "FunctionScheduler: "
"min time interval must be less or equal than max interval"); "min time interval must be less or equal than max interval");
} }
if (minInterval < milliseconds::zero()) { if (minInterval < microseconds::zero()) {
throw std::invalid_argument( throw std::invalid_argument(
"FunctionScheduler: " "FunctionScheduler: "
"time interval must be non-negative"); "time interval must be non-negative");
} }
} }
milliseconds operator()() { microseconds operator()() {
return milliseconds(dist(generator)); return microseconds(dist(generator));
} }
}; };
...@@ -122,30 +122,30 @@ FunctionScheduler::~FunctionScheduler() { ...@@ -122,30 +122,30 @@ FunctionScheduler::~FunctionScheduler() {
void FunctionScheduler::addFunction( void FunctionScheduler::addFunction(
Function<void()>&& cb, Function<void()>&& cb,
milliseconds interval, microseconds interval,
StringPiece nameID, StringPiece nameID,
milliseconds startDelay) { microseconds startDelay) {
addFunctionInternal( addFunctionInternal(
std::move(cb), std::move(cb),
ConstIntervalFunctor(interval), ConstIntervalFunctor(interval),
nameID.str(), nameID.str(),
to<std::string>(interval.count(), "ms"), to<std::string>(interval.count(), "us"),
startDelay, startDelay,
false /*runOnce*/); false /*runOnce*/);
} }
void FunctionScheduler::addFunction( void FunctionScheduler::addFunction(
Function<void()>&& cb, Function<void()>&& cb,
milliseconds interval, microseconds interval,
const LatencyDistribution& latencyDistr, const LatencyDistribution& latencyDistr,
StringPiece nameID, StringPiece nameID,
milliseconds startDelay) { microseconds startDelay) {
if (latencyDistr.isPoisson) { if (latencyDistr.isPoisson) {
addFunctionInternal( addFunctionInternal(
std::move(cb), std::move(cb),
PoissonDistributionFunctor(latencyDistr.poissonMean), PoissonDistributionFunctor(latencyDistr.poissonMean),
nameID.str(), nameID.str(),
to<std::string>(latencyDistr.poissonMean, "ms (Poisson mean)"), to<std::string>(latencyDistr.poissonMean.count(), "us (Poisson mean)"),
startDelay, startDelay,
false /*runOnce*/); false /*runOnce*/);
} else { } else {
...@@ -156,10 +156,10 @@ void FunctionScheduler::addFunction( ...@@ -156,10 +156,10 @@ void FunctionScheduler::addFunction(
void FunctionScheduler::addFunctionOnce( void FunctionScheduler::addFunctionOnce(
Function<void()>&& cb, Function<void()>&& cb,
StringPiece nameID, StringPiece nameID,
milliseconds startDelay) { microseconds startDelay) {
addFunctionInternal( addFunctionInternal(
std::move(cb), std::move(cb),
ConstIntervalFunctor(milliseconds::zero()), ConstIntervalFunctor(microseconds::zero()),
nameID.str(), nameID.str(),
"once", "once",
startDelay, startDelay,
...@@ -168,30 +168,30 @@ void FunctionScheduler::addFunctionOnce( ...@@ -168,30 +168,30 @@ void FunctionScheduler::addFunctionOnce(
void FunctionScheduler::addFunctionUniformDistribution( void FunctionScheduler::addFunctionUniformDistribution(
Function<void()>&& cb, Function<void()>&& cb,
milliseconds minInterval, microseconds minInterval,
milliseconds maxInterval, microseconds maxInterval,
StringPiece nameID, StringPiece nameID,
milliseconds startDelay) { microseconds startDelay) {
addFunctionInternal( addFunctionInternal(
std::move(cb), std::move(cb),
UniformDistributionFunctor(minInterval, maxInterval), UniformDistributionFunctor(minInterval, maxInterval),
nameID.str(), nameID.str(),
to<std::string>( to<std::string>(
"[", minInterval.count(), " , ", maxInterval.count(), "] ms"), "[", minInterval.count(), " , ", maxInterval.count(), "] us"),
startDelay, startDelay,
false /*runOnce*/); false /*runOnce*/);
} }
void FunctionScheduler::addFunctionConsistentDelay( void FunctionScheduler::addFunctionConsistentDelay(
Function<void()>&& cb, Function<void()>&& cb,
milliseconds interval, microseconds interval,
StringPiece nameID, StringPiece nameID,
milliseconds startDelay) { microseconds startDelay) {
addFunctionInternal( addFunctionInternal(
std::move(cb), std::move(cb),
ConsistentDelayFunctor(interval), ConsistentDelayFunctor(interval),
nameID.str(), nameID.str(),
to<std::string>(interval.count(), "ms"), to<std::string>(interval.count(), "us"),
startDelay, startDelay,
false /*runOnce*/); false /*runOnce*/);
} }
...@@ -201,7 +201,7 @@ void FunctionScheduler::addFunctionGenericDistribution( ...@@ -201,7 +201,7 @@ void FunctionScheduler::addFunctionGenericDistribution(
IntervalDistributionFunc&& intervalFunc, IntervalDistributionFunc&& intervalFunc,
const std::string& nameID, const std::string& nameID,
const std::string& intervalDescr, const std::string& intervalDescr,
milliseconds startDelay) { microseconds startDelay) {
addFunctionInternal( addFunctionInternal(
std::move(cb), std::move(cb),
std::move(intervalFunc), std::move(intervalFunc),
...@@ -216,7 +216,7 @@ void FunctionScheduler::addFunctionGenericNextRunTimeFunctor( ...@@ -216,7 +216,7 @@ void FunctionScheduler::addFunctionGenericNextRunTimeFunctor(
NextRunTimeFunc&& fn, NextRunTimeFunc&& fn,
const std::string& nameID, const std::string& nameID,
const std::string& intervalDescr, const std::string& intervalDescr,
milliseconds startDelay) { microseconds startDelay) {
addFunctionInternal( addFunctionInternal(
std::move(cb), std::move(cb),
std::move(fn), std::move(fn),
...@@ -232,7 +232,7 @@ void FunctionScheduler::addFunctionToHeapChecked( ...@@ -232,7 +232,7 @@ void FunctionScheduler::addFunctionToHeapChecked(
RepeatFuncNextRunTimeFunc&& fn, RepeatFuncNextRunTimeFunc&& fn,
const std::string& nameID, const std::string& nameID,
const std::string& intervalDescr, const std::string& intervalDescr,
milliseconds startDelay, microseconds startDelay,
bool runOnce) { bool runOnce) {
if (!cb) { if (!cb) {
throw std::invalid_argument( throw std::invalid_argument(
...@@ -243,7 +243,7 @@ void FunctionScheduler::addFunctionToHeapChecked( ...@@ -243,7 +243,7 @@ void FunctionScheduler::addFunctionToHeapChecked(
"FunctionScheduler: " "FunctionScheduler: "
"interval distribution or next run time function must be set"); "interval distribution or next run time function must be set");
} }
if (startDelay < milliseconds::zero()) { if (startDelay < microseconds::zero()) {
throw std::invalid_argument( throw std::invalid_argument(
"FunctionScheduler: start delay must be non-negative"); "FunctionScheduler: start delay must be non-negative");
} }
...@@ -277,7 +277,7 @@ void FunctionScheduler::addFunctionInternal( ...@@ -277,7 +277,7 @@ void FunctionScheduler::addFunctionInternal(
NextRunTimeFunc&& fn, NextRunTimeFunc&& fn,
const std::string& nameID, const std::string& nameID,
const std::string& intervalDescr, const std::string& intervalDescr,
milliseconds startDelay, microseconds startDelay,
bool runOnce) { bool runOnce) {
return addFunctionToHeapChecked( return addFunctionToHeapChecked(
std::move(cb), std::move(fn), nameID, intervalDescr, startDelay, runOnce); std::move(cb), std::move(fn), nameID, intervalDescr, startDelay, runOnce);
...@@ -288,7 +288,7 @@ void FunctionScheduler::addFunctionInternal( ...@@ -288,7 +288,7 @@ void FunctionScheduler::addFunctionInternal(
IntervalDistributionFunc&& fn, IntervalDistributionFunc&& fn,
const std::string& nameID, const std::string& nameID,
const std::string& intervalDescr, const std::string& intervalDescr,
milliseconds startDelay, microseconds startDelay,
bool runOnce) { bool runOnce) {
return addFunctionToHeapChecked( return addFunctionToHeapChecked(
std::move(cb), std::move(fn), nameID, intervalDescr, startDelay, runOnce); std::move(cb), std::move(fn), nameID, intervalDescr, startDelay, runOnce);
...@@ -465,7 +465,7 @@ void FunctionScheduler::run() { ...@@ -465,7 +465,7 @@ void FunctionScheduler::run() {
} }
auto sleepTime = functions_.back()->getNextRunTime() - now; auto sleepTime = functions_.back()->getNextRunTime() - now;
if (sleepTime < milliseconds::zero()) { if (sleepTime < microseconds::zero()) {
// We need to run this function now // We need to run this function now
runOneFunction(lock, now); runOneFunction(lock, now);
runningCondvar_.notify_all(); runningCondvar_.notify_all();
......
...@@ -80,9 +80,9 @@ class FunctionScheduler { ...@@ -80,9 +80,9 @@ class FunctionScheduler {
*/ */
struct LatencyDistribution { struct LatencyDistribution {
bool isPoisson; bool isPoisson;
double poissonMean; std::chrono::microseconds poissonMean;
LatencyDistribution(bool poisson, double mean) LatencyDistribution(bool poisson, std::chrono::microseconds mean)
: isPoisson(poisson), poissonMean(mean) {} : isPoisson(poisson), poissonMean(mean) {}
}; };
...@@ -99,9 +99,9 @@ class FunctionScheduler { ...@@ -99,9 +99,9 @@ class FunctionScheduler {
*/ */
void addFunction( void addFunction(
Function<void()>&& cb, Function<void()>&& cb,
std::chrono::milliseconds interval, std::chrono::microseconds interval,
StringPiece nameID = StringPiece(), StringPiece nameID = StringPiece(),
std::chrono::milliseconds startDelay = std::chrono::milliseconds(0)); std::chrono::microseconds startDelay = std::chrono::microseconds(0));
/* /*
* Add a new function to the FunctionScheduler with a specified * Add a new function to the FunctionScheduler with a specified
...@@ -109,10 +109,10 @@ class FunctionScheduler { ...@@ -109,10 +109,10 @@ class FunctionScheduler {
*/ */
void addFunction( void addFunction(
Function<void()>&& cb, Function<void()>&& cb,
std::chrono::milliseconds interval, std::chrono::microseconds interval,
const LatencyDistribution& latencyDistr, const LatencyDistribution& latencyDistr,
StringPiece nameID = StringPiece(), StringPiece nameID = StringPiece(),
std::chrono::milliseconds startDelay = std::chrono::milliseconds(0)); std::chrono::microseconds startDelay = std::chrono::microseconds(0));
/** /**
* Adds a new function to the FunctionScheduler to run only once. * Adds a new function to the FunctionScheduler to run only once.
...@@ -120,7 +120,7 @@ class FunctionScheduler { ...@@ -120,7 +120,7 @@ class FunctionScheduler {
void addFunctionOnce( void addFunctionOnce(
Function<void()>&& cb, Function<void()>&& cb,
StringPiece nameID = StringPiece(), StringPiece nameID = StringPiece(),
std::chrono::milliseconds startDelay = std::chrono::milliseconds(0)); std::chrono::microseconds startDelay = std::chrono::microseconds(0));
/** /**
* Add a new function to the FunctionScheduler with the time * Add a new function to the FunctionScheduler with the time
...@@ -129,10 +129,10 @@ class FunctionScheduler { ...@@ -129,10 +129,10 @@ class FunctionScheduler {
*/ */
void addFunctionUniformDistribution( void addFunctionUniformDistribution(
Function<void()>&& cb, Function<void()>&& cb,
std::chrono::milliseconds minInterval, std::chrono::microseconds minInterval,
std::chrono::milliseconds maxInterval, std::chrono::microseconds maxInterval,
StringPiece nameID, StringPiece nameID,
std::chrono::milliseconds startDelay); std::chrono::microseconds startDelay);
/** /**
* Add a new function to the FunctionScheduler whose start times are attempted * Add a new function to the FunctionScheduler whose start times are attempted
...@@ -143,15 +143,15 @@ class FunctionScheduler { ...@@ -143,15 +143,15 @@ class FunctionScheduler {
*/ */
void addFunctionConsistentDelay( void addFunctionConsistentDelay(
Function<void()>&& cb, Function<void()>&& cb,
std::chrono::milliseconds interval, std::chrono::microseconds interval,
StringPiece nameID = StringPiece(), StringPiece nameID = StringPiece(),
std::chrono::milliseconds startDelay = std::chrono::milliseconds(0)); std::chrono::microseconds startDelay = std::chrono::microseconds(0));
/** /**
* A type alias for function that is called to determine the time * A type alias for function that is called to determine the time
* interval for the next scheduled run. * interval for the next scheduled run.
*/ */
using IntervalDistributionFunc = Function<std::chrono::milliseconds()>; using IntervalDistributionFunc = Function<std::chrono::microseconds()>;
/** /**
* A type alias for function that returns the next run time, given the current * A type alias for function that returns the next run time, given the current
* run time and the current start time. * run time and the current start time.
...@@ -174,7 +174,7 @@ class FunctionScheduler { ...@@ -174,7 +174,7 @@ class FunctionScheduler {
IntervalDistributionFunc&& intervalFunc, IntervalDistributionFunc&& intervalFunc,
const std::string& nameID, const std::string& nameID,
const std::string& intervalDescr, const std::string& intervalDescr,
std::chrono::milliseconds startDelay); std::chrono::microseconds startDelay);
/** /**
* Like addFunctionGenericDistribution, adds a new function to the * Like addFunctionGenericDistribution, adds a new function to the
...@@ -186,7 +186,7 @@ class FunctionScheduler { ...@@ -186,7 +186,7 @@ class FunctionScheduler {
NextRunTimeFunc&& fn, NextRunTimeFunc&& fn,
const std::string& nameID, const std::string& nameID,
const std::string& intervalDescr, const std::string& intervalDescr,
std::chrono::milliseconds startDelay); std::chrono::microseconds startDelay);
/** /**
* Cancels the function with the specified name, so it will no longer be run. * Cancels the function with the specified name, so it will no longer be run.
...@@ -239,7 +239,7 @@ class FunctionScheduler { ...@@ -239,7 +239,7 @@ class FunctionScheduler {
NextRunTimeFunc nextRunTimeFunc; NextRunTimeFunc nextRunTimeFunc;
std::chrono::steady_clock::time_point nextRunTime; std::chrono::steady_clock::time_point nextRunTime;
std::string name; std::string name;
std::chrono::milliseconds startDelay; std::chrono::microseconds startDelay;
std::string intervalDescr; std::string intervalDescr;
bool runOnce; bool runOnce;
...@@ -248,7 +248,7 @@ class FunctionScheduler { ...@@ -248,7 +248,7 @@ class FunctionScheduler {
IntervalDistributionFunc&& intervalFn, IntervalDistributionFunc&& intervalFn,
const std::string& nameID, const std::string& nameID,
const std::string& intervalDistDescription, const std::string& intervalDistDescription,
std::chrono::milliseconds delay, std::chrono::microseconds delay,
bool once) bool once)
: RepeatFunc( : RepeatFunc(
std::move(cback), std::move(cback),
...@@ -263,7 +263,7 @@ class FunctionScheduler { ...@@ -263,7 +263,7 @@ class FunctionScheduler {
NextRunTimeFunc&& nextRunTimeFn, NextRunTimeFunc&& nextRunTimeFn,
const std::string& nameID, const std::string& nameID,
const std::string& intervalDistDescription, const std::string& intervalDistDescription,
std::chrono::milliseconds delay, std::chrono::microseconds delay,
bool once) bool once)
: cb(std::move(cback)), : cb(std::move(cback)),
nextRunTimeFunc(std::move(nextRunTimeFn)), nextRunTimeFunc(std::move(nextRunTimeFn)),
...@@ -329,7 +329,7 @@ class FunctionScheduler { ...@@ -329,7 +329,7 @@ class FunctionScheduler {
RepeatFuncNextRunTimeFunc&& fn, RepeatFuncNextRunTimeFunc&& fn,
const std::string& nameID, const std::string& nameID,
const std::string& intervalDescr, const std::string& intervalDescr,
std::chrono::milliseconds startDelay, std::chrono::microseconds startDelay,
bool runOnce); bool runOnce);
void addFunctionInternal( void addFunctionInternal(
...@@ -337,14 +337,14 @@ class FunctionScheduler { ...@@ -337,14 +337,14 @@ class FunctionScheduler {
NextRunTimeFunc&& fn, NextRunTimeFunc&& fn,
const std::string& nameID, const std::string& nameID,
const std::string& intervalDescr, const std::string& intervalDescr,
std::chrono::milliseconds startDelay, std::chrono::microseconds startDelay,
bool runOnce); bool runOnce);
void addFunctionInternal( void addFunctionInternal(
Function<void()>&& cb, Function<void()>&& cb,
IntervalDistributionFunc&& fn, IntervalDistributionFunc&& fn,
const std::string& nameID, const std::string& nameID,
const std::string& intervalDescr, const std::string& intervalDescr,
std::chrono::milliseconds startDelay, std::chrono::microseconds startDelay,
bool runOnce); bool runOnce);
// Return true if the current function is being canceled // Return true if the current function is being canceled
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment