UNPKG

pull-drain-gently

Version:

Like pull.drain, but respects CPU load

191 lines (164 loc) 4.17 kB
var pull = require('pull-stream'); var test = require('tape'); var usage = require('cpu-percentage'); var fs = require('fs'); var drainGently = require('./index'); function delay() { return pull.asyncMap(function (e, cb) { setTimeout(function () { cb(null, e); }); }); } test('like pull.drain: abort on drain', function (t) { var c = 100; var drain = drainGently( function () { if (c < 0) throw new Error('stream should have aborted'); if (!--c) return false; //drain.abort() }, function () { t.end(); }, ); pull(pull.infinite(), drain); }); test('like pull.drain: abort on drain - async', function (t) { var c = 100; var drain = drainGently( function () { if (c < 0) throw new Error('stream should have aborted'); if (!--c) return drain.abort(); }, function () { t.end(); }, ); pull(pull.infinite(), delay(), drain); }); test('like pull.drain: abort on drain - sync', function (t) { var c = 100; var drain = drainGently( function () { if (c < 0) throw new Error('stream should have aborted'); if (!--c) return drain.abort(); }, function () { t.end(); }, ); pull(pull.infinite(), drain); }); test('like pull.drain: abort on drain - async, out of cb', function (t) { t.plan(2); var c = 0, ERR = new Error('test ABORT'); var drain = drainGently( function () { --c; }, function (err) { t.ok(c < 0); t.equal(err, ERR); t.end(); }, ); pull(pull.infinite(), delay(), drain); setTimeout(function () { drain.abort(ERR); }, 100); }); test('supports drainGently()', function (t) { pull(pull.count(7), drainGently()); setTimeout(() => { t.end(); }, 50); }); test('supports drainGently(null, done)', function (t) { t.plan(1); pull( pull.count(7), drainGently(null, () => { t.pass('all good'); t.end(); }), ); }); test('supports drainGently(opts)', function (t) { pull(pull.count(7), drainGently({ceiling: 90, wait: 90})); setTimeout(() => { t.end(); }, 50); }); test('supports drainGently(opts, null)', function (t) { pull(pull.count(7), drainGently({ceiling: 90, wait: 90}, null)); setTimeout(() => { t.end(); }, 50); }); test('respects `maxPause` opt', function (t) { t.plan(1); t.timeoutAfter(8000); const ceiling = 0.01; // super low threshold, most likely never met const maxPause = 50; // ms pull( pull.count(200), pull.asyncMap((x, cb) => fs.readFile('./package.json', cb)), pull.map((contents) => Buffer.from(contents.toString('hex').toUpperCase()) .toString('base64') .toLowerCase() .substr(0, 20), ), drainGently({ceiling, maxPause, wait: 16}, null, () => { t.pass('all data points processed'); t.end(); }), ); }); test('heavy processing is below the prescribed CPU 90% ceiling', function (t) { t.plan(1); const ceiling = 90; const start = usage(); pull( pull.count(20000), pull.asyncMap((x, cb) => fs.readFile('./package.json', cb)), pull.map((contents) => Buffer.from(contents.toString('hex').toUpperCase()) .toString('base64') .toLowerCase() .substr(0, 20), ), drainGently( {ceiling, wait: 40}, () => {}, () => { const stats = usage(start); console.log(usage(start)); t.true(stats.percent < ceiling + 3, 'CPU usage was approx. 90%'); t.end(); }, ), ); }); test('heavy processing is below the prescribed CPU 50% ceiling', function (t) { t.plan(1); const ceiling = 50; const start = usage(); pull( pull.count(8000), pull.asyncMap((x, cb) => fs.readFile('./package.json', cb)), pull.map((contents) => Buffer.from(contents.toString('hex').toUpperCase()) .toString('base64') .toLowerCase() .substr(0, 20), ), drainGently({ceiling, wait: 40}, null, () => { const stats = usage(start); console.log(usage(start)); t.true(stats.percent < ceiling + 3, 'CPU usage was approx. 50%'); t.end(); }), ); });