npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

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