Commit a92b878a authored by Sven Over's avatar Sven Over Committed by Facebook Github Bot 8

folly::FunctionScheduler: replace std::function w/ folly::Function

Summary:By using folly::Function instead of std::function to internally store
functions in FunctionScheduler, this diff allows users to pass
non-copyable lambdas to FunctionScheduler::addFunction.

All exisiting unit tests still pass. Also, passing std::function to
addFunction still works, as the std::function will be implicitly
converted (i.e. wrapped) in a folly::Function. However, this implies
a performance penalty.

Reviewed By: fugalh

Differential Revision: D3092944

fb-gh-sync-id: 1e8081e70d4717025f2eadbb6b6da173460d4373
fbshipit-source-id: 1e8081e70d4717025f2eadbb6b6da173460d4373
parent aafcc64b
...@@ -92,46 +92,44 @@ FunctionScheduler::~FunctionScheduler() { ...@@ -92,46 +92,44 @@ FunctionScheduler::~FunctionScheduler() {
shutdown(); shutdown();
} }
void FunctionScheduler::addFunction(const std::function<void()>& cb, void FunctionScheduler::addFunction(Function<void()>&& cb,
milliseconds interval, milliseconds interval,
StringPiece nameID, StringPiece nameID,
milliseconds startDelay) { milliseconds startDelay) {
addFunctionGenericDistribution( addFunctionGenericDistribution(
cb, std::move(cb),
IntervalDistributionFunc(ConstIntervalFunctor(interval)), ConstIntervalFunctor(interval),
nameID.str(), nameID.str(),
to<std::string>(interval.count(), "ms"), to<std::string>(interval.count(), "ms"),
startDelay); startDelay);
} }
void FunctionScheduler::addFunction(const std::function<void()>& cb, void FunctionScheduler::addFunction(Function<void()>&& cb,
milliseconds interval, milliseconds interval,
const LatencyDistribution& latencyDistr, const LatencyDistribution& latencyDistr,
StringPiece nameID, StringPiece nameID,
milliseconds startDelay) { milliseconds startDelay) {
if (latencyDistr.isPoisson) { if (latencyDistr.isPoisson) {
addFunctionGenericDistribution( addFunctionGenericDistribution(
cb, std::move(cb),
IntervalDistributionFunc( PoissonDistributionFunctor(latencyDistr.poissonMean),
PoissonDistributionFunctor(latencyDistr.poissonMean)),
nameID.str(), nameID.str(),
to<std::string>(latencyDistr.poissonMean, "ms (Poisson mean)"), to<std::string>(latencyDistr.poissonMean, "ms (Poisson mean)"),
startDelay); startDelay);
} else { } else {
addFunction(cb, interval, nameID, startDelay); addFunction(std::move(cb), interval, nameID, startDelay);
} }
} }
void FunctionScheduler::addFunctionUniformDistribution( void FunctionScheduler::addFunctionUniformDistribution(
const std::function<void()>& cb, Function<void()>&& cb,
milliseconds minInterval, milliseconds minInterval,
milliseconds maxInterval, milliseconds maxInterval,
StringPiece nameID, StringPiece nameID,
milliseconds startDelay) { milliseconds startDelay) {
addFunctionGenericDistribution( addFunctionGenericDistribution(
cb, std::move(cb),
IntervalDistributionFunc( 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(), "] ms"),
...@@ -139,8 +137,8 @@ void FunctionScheduler::addFunctionUniformDistribution( ...@@ -139,8 +137,8 @@ void FunctionScheduler::addFunctionUniformDistribution(
} }
void FunctionScheduler::addFunctionGenericDistribution( void FunctionScheduler::addFunctionGenericDistribution(
const std::function<void()>& cb, Function<void()>&& cb,
const IntervalDistributionFunc& intervalFunc, IntervalDistributionFunc&& intervalFunc,
const std::string& nameID, const std::string& nameID,
const std::string& intervalDescr, const std::string& intervalDescr,
milliseconds startDelay) { milliseconds startDelay) {
...@@ -173,7 +171,13 @@ void FunctionScheduler::addFunctionGenericDistribution( ...@@ -173,7 +171,13 @@ void FunctionScheduler::addFunctionGenericDistribution(
} }
addFunctionToHeap( addFunctionToHeap(
l, RepeatFunc(cb, intervalFunc, nameID, intervalDescr, startDelay)); l,
RepeatFunc(
std::move(cb),
std::move(intervalFunc),
nameID,
intervalDescr,
startDelay));
} }
bool FunctionScheduler::cancelFunction(StringPiece nameID) { bool FunctionScheduler::cancelFunction(StringPiece nameID) {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#pragma once #pragma once
#include <folly/Function.h>
#include <folly/Range.h> #include <folly/Range.h>
#include <chrono> #include <chrono>
#include <condition_variable> #include <condition_variable>
...@@ -92,7 +93,7 @@ class FunctionScheduler { ...@@ -92,7 +93,7 @@ class FunctionScheduler {
* Throws an exception on error. In particular, each function must have a * Throws an exception on error. In particular, each function must have a
* unique name--two functions cannot be added with the same name. * unique name--two functions cannot be added with the same name.
*/ */
void addFunction(const std::function<void()>& cb, void addFunction(Function<void()>&& cb,
std::chrono::milliseconds interval, std::chrono::milliseconds interval,
StringPiece nameID = StringPiece(), StringPiece nameID = StringPiece(),
std::chrono::milliseconds startDelay = std::chrono::milliseconds startDelay =
...@@ -103,7 +104,7 @@ class FunctionScheduler { ...@@ -103,7 +104,7 @@ class FunctionScheduler {
* LatencyDistribution * LatencyDistribution
*/ */
void addFunction( void addFunction(
const std::function<void()>& cb, Function<void()>&& cb,
std::chrono::milliseconds interval, std::chrono::milliseconds interval,
const LatencyDistribution& latencyDistr, const LatencyDistribution& latencyDistr,
StringPiece nameID = StringPiece(), StringPiece nameID = StringPiece(),
...@@ -114,7 +115,7 @@ class FunctionScheduler { ...@@ -114,7 +115,7 @@ class FunctionScheduler {
* interval being distributed uniformly within the given interval * interval being distributed uniformly within the given interval
* [minInterval, maxInterval]. * [minInterval, maxInterval].
*/ */
void addFunctionUniformDistribution(const std::function<void()>& cb, void addFunctionUniformDistribution(Function<void()>&& cb,
std::chrono::milliseconds minInterval, std::chrono::milliseconds minInterval,
std::chrono::milliseconds maxInterval, std::chrono::milliseconds maxInterval,
StringPiece nameID, StringPiece nameID,
...@@ -124,7 +125,7 @@ class FunctionScheduler { ...@@ -124,7 +125,7 @@ class FunctionScheduler {
* 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 = std::function<std::chrono::milliseconds()>; using IntervalDistributionFunc = Function<std::chrono::milliseconds()>;
/** /**
* Add a new function to the FunctionScheduler. The scheduling interval * Add a new function to the FunctionScheduler. The scheduling interval
...@@ -136,8 +137,8 @@ class FunctionScheduler { ...@@ -136,8 +137,8 @@ class FunctionScheduler {
* @see FunctionScheduler::addFunctionJitterInterval). * @see FunctionScheduler::addFunctionJitterInterval).
*/ */
void addFunctionGenericDistribution( void addFunctionGenericDistribution(
const std::function<void()>& cb, Function<void()>&& cb,
const 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::milliseconds startDelay);
...@@ -186,20 +187,20 @@ class FunctionScheduler { ...@@ -186,20 +187,20 @@ class FunctionScheduler {
private: private:
struct RepeatFunc { struct RepeatFunc {
std::function<void()> cb; Function<void()> cb;
IntervalDistributionFunc intervalFunc; IntervalDistributionFunc intervalFunc;
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::milliseconds startDelay;
std::string intervalDescr; std::string intervalDescr;
RepeatFunc(const std::function<void()>& cback, RepeatFunc(Function<void()>&& cback,
const 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::milliseconds delay)
: cb(cback), : cb(std::move(cback)),
intervalFunc(intervalFn), intervalFunc(std::move(intervalFn)),
nextRunTime(), nextRunTime(),
name(nameID), name(nameID),
startDelay(delay), startDelay(delay),
...@@ -217,7 +218,7 @@ class FunctionScheduler { ...@@ -217,7 +218,7 @@ class FunctionScheduler {
} }
void cancel() { void cancel() {
// Simply reset cb to an empty function. // Simply reset cb to an empty function.
cb = std::function<void()>(); cb = {};
} }
bool isValid() const { return bool(cb); } bool isValid() const { return bool(cb); }
}; };
......
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