scheduled-throttle
v0.4.1
Published
Function will only execute once until it passes a certain time of day (backed by Redis).
Downloads
6
Readme
#Scheduled Throttle
A throttled function will only execute once until it passes a certain time of day (backed by Redis).
##Install
npm install scheduled-throttle
##Example
Check out the following example written in ES6. Hopefully you're familiar with coroutines/generators/Bluebird! :)
var REDIS_KEYS_EXPIRE = 1000000;
var scheduledThrottle = require('scheduled-throttle');
var assert = require('assert');
var Bluebird = require('bluebird');
var throttler = scheduledThrottle.create({
client: redisClient, // required
key: 'foo:1', // required - Redis key name
timezone: '+0900', // required
localChangeTimes: [ // required
'0400',
'1430'
],
inactivityExpire: REDIS_KEYS_EXPIRE, // optional - in seconds
// if not set, the relevant Redis keys never expire
serialize: function (numberResult) { // optional
// If not set, a default serializer is used (which is basically a JSON.stringify()
// that can handle undefined). Redis can only store strings, so everything needs
// to be converted to and from a string.
return String(numberResult);
},
deserialize: function (stringStored) { // optional - similar to the serialize
// If not set, a default deserializer is used (which is basically a JSON.parse()
// that can handle undefined)
return JSON.parse(stringStored);
}
}));
throttler = Bluebird.promisifyAll(throttler);
var obj = {
a: 2,
throttledFn: throttler.throttle(function (x, cb) { // callback should be a nodeback
console.log('executed');
cb(null, x + this.a);
})
};
obj = Bluebird.promisifyAll(obj);
Bluebird.coroutine(function* () {
yield throttler.clearAsync(); // "clear" method - clears out all relevant Redis keys
var result = yield obj.throttledFnAsync(1);
// 'executed' is printed because of console.log() above
assert.strictEqual(result, 1 + 2);
var will = yield throttler.willExecuteAsync();
// will not execute until either 04:00 or 14:30 (local time)
assert.strictEqual(result, false);
// also, after REDIS_KEYS_EXPIRE seconds,
// relevant Redis keys will be cleared out, as if throttler.clear() is called
var result2 = yield obj.throttledFnAsync(1);
assert.strictEqual(result2, scheduledThrottle.THROTTLED);
})();
Now check out the "preserveResult" option:
var throttler = Bluebird.promisifyAll(scheduledThrottle.create({
client: redisClient,
key: TEST_KEY_NAME,
timezone: '+0900',
localChangeTimes: ['0400'],
preserveResult: true /*** NOTICE THIS OPTION! ***/
}));
var c = {u: 1, v: '1'};
var throttledFn = throttler.throttle(function (cb) { cb(null, c); });
var throttledFnAsync = Bluebird.promisify(throttledFn);
Bluebird.coroutine(function* () {
var result = yield throttledFnAsync();
assert.strictEqual(result, c);
var result2 = yield throttledFnAsync();
assert.deepEqual(result2, c); // previous result has been kept along and is returned
assert.notStrictEqual(result2, scheduledThrottle.THROTTLED); // instead of THROTTLED
})();
##Error within the function being throttled
When there is an error (not necessarily an Error
object) is thrown inside the function being throttled,
the throttler will stop the process immediately and no changes will occur with Redis.
const throttledFnAsync = Bluebird.promisify(throttler2.throttle(cb => cb(new Error('intentional'))));
try {
yield throttledFnAsync();
} catch (err) {
assert.strictEqual(err.message, 'intentional');
try {
yield throttledFnAsync(); // should throw again
} catch (err) {
assert.strictEqual(err.message, 'intentional');
}
}
##Pretending a Time of Day
For testing purposes, you may want to pretend it's a certain time of day right now. In such cases, simply pass a Date
object as the first argument of .throttle()
or .willExecute()
:
var throttler = scheduledThrottle.create({
(other options...),
timezone: '+0900',
localChangeTimes: ['0400']
}));
var simulatedThrottledFn = throttler.throttle(new Date('2013-03-01T04:01:00+0900'), function (cb) {
// will simulate as if it is 04:01 right now
});
##Test
Test is written in ES6, so 6to5 is used for transpilation.
npm install
npm test