milliseconds interval,
StringPiece nameID,
milliseconds startDelay) {
- addFunctionGenericDistribution(
+ addFunctionInternal(
std::move(cb),
ConstIntervalFunctor(interval),
nameID.str(),
to<std::string>(interval.count(), "ms"),
- startDelay);
+ startDelay,
+ false /*runOnce*/);
}
void FunctionScheduler::addFunction(Function<void()>&& cb,
StringPiece nameID,
milliseconds startDelay) {
if (latencyDistr.isPoisson) {
- addFunctionGenericDistribution(
+ addFunctionInternal(
std::move(cb),
PoissonDistributionFunctor(latencyDistr.poissonMean),
nameID.str(),
to<std::string>(latencyDistr.poissonMean, "ms (Poisson mean)"),
- startDelay);
+ startDelay,
+ false /*runOnce*/);
} else {
addFunction(std::move(cb), interval, nameID, startDelay);
}
}
+void FunctionScheduler::addFunctionOnce(
+ Function<void()>&& cb,
+ StringPiece nameID,
+ milliseconds startDelay) {
+ addFunctionInternal(
+ std::move(cb),
+ ConstIntervalFunctor(milliseconds::zero()),
+ nameID.str(),
+ "once",
+ startDelay,
+ true /*runOnce*/);
+}
+
void FunctionScheduler::addFunctionUniformDistribution(
Function<void()>&& cb,
milliseconds minInterval,
milliseconds maxInterval,
StringPiece nameID,
milliseconds startDelay) {
- addFunctionGenericDistribution(
+ addFunctionInternal(
std::move(cb),
UniformDistributionFunctor(minInterval, maxInterval),
nameID.str(),
to<std::string>(
"[", minInterval.count(), " , ", maxInterval.count(), "] ms"),
- startDelay);
+ startDelay,
+ false /*runOnce*/);
}
void FunctionScheduler::addFunctionGenericDistribution(
const std::string& nameID,
const std::string& intervalDescr,
milliseconds startDelay) {
+ addFunctionInternal(
+ std::move(cb),
+ std::move(intervalFunc),
+ nameID,
+ intervalDescr,
+ startDelay,
+ false /*runOnce*/);
+}
+
+void FunctionScheduler::addFunctionInternal(
+ Function<void()>&& cb,
+ IntervalDistributionFunc&& intervalFunc,
+ const std::string& nameID,
+ const std::string& intervalDescr,
+ milliseconds startDelay,
+ bool runOnce) {
if (!cb) {
throw std::invalid_argument(
"FunctionScheduler: Scheduled function must be set");
std::move(intervalFunc),
nameID,
intervalDescr,
- startDelay));
+ startDelay,
+ runOnce));
}
bool FunctionScheduler::cancelFunction(StringPiece nameID) {
// We shouldn't reschedule it;
return;
}
+ if (currentFunction_->runOnce) {
+ // Don't reschedule if the function only needed to run once.
+ return;
+ }
// Clear currentFunction_
CHECK_EQ(currentFunction_, &func);
currentFunction_ = nullptr;
StringPiece nameID = StringPiece(),
std::chrono::milliseconds startDelay = std::chrono::milliseconds(0));
+ /**
+ * Adds a new function to the FunctionScheduler to run only once.
+ */
+ void addFunctionOnce(
+ Function<void()>&& cb,
+ StringPiece nameID = StringPiece(),
+ std::chrono::milliseconds startDelay = std::chrono::milliseconds(0));
+
/**
* Add a new function to the FunctionScheduler with the time
* interval being distributed uniformly within the given interval
std::string name;
std::chrono::milliseconds startDelay;
std::string intervalDescr;
+ bool runOnce;
- RepeatFunc(Function<void()>&& cback,
- IntervalDistributionFunc&& intervalFn,
- const std::string& nameID,
- const std::string& intervalDistDescription,
- std::chrono::milliseconds delay)
+ RepeatFunc(
+ Function<void()>&& cback,
+ IntervalDistributionFunc&& intervalFn,
+ const std::string& nameID,
+ const std::string& intervalDistDescription,
+ std::chrono::milliseconds delay,
+ bool once)
: cb(std::move(cback)),
intervalFunc(std::move(intervalFn)),
nextRunTime(),
name(nameID),
startDelay(delay),
- intervalDescr(intervalDistDescription) {}
+ intervalDescr(intervalDistDescription),
+ runOnce(once) {}
std::chrono::steady_clock::time_point getNextRunTime() const {
return nextRunTime;
void addFunctionToHeap(const std::unique_lock<std::mutex>& lock,
RepeatFunc&& func);
+ void addFunctionInternal(
+ Function<void()>&& cb,
+ IntervalDistributionFunc&& intervalFunc,
+ const std::string& nameID,
+ const std::string& intervalDescr,
+ std::chrono::milliseconds startDelay,
+ bool runOnce);
+
std::thread thread_;
// Mutex to protect our member variables.