Skip to content

Commit

Permalink
Merge branch 'adjustableCpuThrottle' into cpuUsageThrottle
Browse files Browse the repository at this point in the history
  • Loading branch information
retrohacker committed Sep 8, 2017
2 parents 2c4eb42 + f730170 commit ac8a551
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
9 changes: 9 additions & 0 deletions docs/api/plugins.md
Expand Up @@ -506,6 +506,15 @@ Params:
* `halfLife` - When we sample the CPU usage on an interval, we create a series of data points. We take these points and calculate a moving average. The halfLife indicates how quickly a point "decays" to half it's value in the moving average. The lower the halfLife, the more impact newer data points have on the average. If you want to be extremely responsive to spikes in CPU usage, set this to a lower value. If you want your process to put more emphasis on recent historical CPU usage when determininng whether it should shed load, set this to a higher value. The unit is in ms. The default is to set this to the same value as interval.
* `err` - A restify error used as a response when the cpu usage limit is exceeded
You can also update the plugin during runtime using the `.update()` function. This function accepts the same `opts` object as a constructor.
```js
var plugin = restify.plugins.cpuUsageThrottle(options);
server.pre(plugin);

plugin.update({ limit: .4, halfLife: 5000 });
```
## Conditional Request Handler
```js
Expand Down
51 changes: 51 additions & 0 deletions lib/plugins/cpuUsageThrottle.js
Expand Up @@ -178,6 +178,57 @@ function cpuUsageThrottle (opts) {
// Expose internal plugin state for introspection
onRequest.state = self;

/**
* cpuUsageThrottle.update
*
* Allow the plugin's configuration to be updated during runtime.
*
* @param {Object} opts The opts object for reconfiguring this plugin, it
* follows the same format as the constructor for this plugin.
*/
onRequest.update = function update(newOpts) {
assert.object(newOpts, 'newOpts');
assert.optionalNumber(newOpts.limit, 'newOpts.limit');
assert.optionalNumber(newOpts.max, 'newOpts.max');
assert.optionalNumber(newOpts.interval, 'newOpts.interval');
assert.optionalNumber(newOpts.halfLife, 'newOpts.halfLife');

if (newOpts.err !== undefined && newOpts.err !== null) {
assert.ok((new newOpts.err()) instanceof errors.HttpError,
'newOpts.err must be an error');
assert.optionalNumber(newOpts.err.statusCode,
'newOpts.err.statusCode');
self._err = newOpts.err;
}

if (newOpts.limit !== undefined) {
self._limit = newOpts.limit;
}

if (newOpts.max !== undefined) {
self._max = newOpts.max;
}

if (newOpts.interval !== undefined) {
self._interval = newOpts.interval;
}

if (newOpts.halfLife !== undefined) {
self._halfLife = newOpts.halfLife;
// update our ewma with the new halfLife, we use the previous known
// state as the initial state for our new halfLife in liue of
// having access to true historical data.
self._ewma = new EWMA(self._halfLife, self._cpu);
}

// Ensure new values are still valid
assert.ok(self._max > self._limit, 'limit must be less than max');

// Update _reject with the new settings
self._reject =
(self._cpu - self._limit) / (self._max - self._limit);
};

return onRequest;
}

Expand Down
23 changes: 23 additions & 0 deletions test/plugins/cpuUsageThrottle.test.js
Expand Up @@ -69,6 +69,29 @@ describe('cpuUsageThrottle', function () {
plugin({}, {}, next);
});

it('Unit: Update should update state', function (done) {
var opts = {
max: 1,
limit: 0.9,
halfLife: 50,
interval: 50
};
var plugin = cpuUsageThrottle(opts);
opts = {
max: 0.5,
limit: 0.1,
halfLife: 1000,
interval: 1000
};
plugin.update(opts);
assert.equal(plugin.state._limit, opts.limit, 'opts.limit');
assert.equal(plugin.state._max, opts.max, 'opts.max');
assert.equal(plugin.state._halfLife, opts.halfLife, 'opts.halfLife');
assert.equal(plugin.state._interval, opts.interval, 'opts.interval');
plugin.close();
done();
});

it('Integration: Should shed load', function (done) {
var server = restify.createServer();
var client = {
Expand Down

0 comments on commit ac8a551

Please sign in to comment.