stream-flow-control
Version:
Stream Flow Control
88 lines (74 loc) • 2.57 kB
JavaScript
const {Readable} = require('stream');
const {Manager} = require('../manager/manager.js');
const uuid = require('uuid');
const {DataWrapper} = require('../wrapper/data_wrapper.js')
/**
* Flow the first message from multiple source streams and discard the rest.
*
* @extends Readable
*/
class FlowFirst extends Readable {
/**
* Create a FlowFirst stream
* @param {object} options Global options
* @param {string} [options.name] Name for this stream
* @param {Identify} options.identify Function that returns a message id to match
* @param {Condition} [options.criteria] Add an extra criteria for message to match. Return false to discard the message.
* @param {Process} [options.match] How messages are matched according to _options.identify_ function.
*/
constructor(options) {
options = {...options, objectMode: true};
super(options);
this.options = options;
/** @property Source streams */
this._sources = {};
this._readableState.sync = false;
this.type = 'FlowFirst';
if(this.options.name) Manager.set(this.type, this);
if(this.options.match && typeof this.options.match == 'function') this._match = this.options.match;
if(this.options.identify && typeof this.options.identify == 'function') this._identify = this.options.identify;
this._identities={};
//Delete used identities every 5 seconds
setInterval(()=>{
Object.keys(this._identities).forEach(key => {
const ts = Date.now() - 1000;
if(this._identities[key] < ts) delete this._identities[key];
});
}, 5000);
this.on('pipe', (src)=>{
src.on('data', (data)=>{
//console.log('hay data');
this._match(data);
});
this.on('pause', ()=>{
src.pause();
});
this.on('resume', ()=>{
src.resume();
});
});
}
_identify(data) {
throw 'METHOD NOT IMPLEMENTED _identify()';
}
_criteria(data) {
return true;
}
_match(data) {
if(!this._criteria(data)) return;
const id = this._identify(data);
if(!this._identities[id]) {
this._identities[id] = Date.now();
if(!this.push(data)) this.pause();
}
}
write(payload) {
}
end() {
this.push(null);
}
_read() {
this.resume();
}
}
module.exports.FlowFirst = FlowFirst;