UNPKG

docker-event-emitter

Version:

Subscribe to events from a dockerode instance in a meaningful way

122 lines (92 loc) 2.73 kB
const { Transform, Writable } = require('stream'); const { EventEmitter } = require('events'); const debug = require('debug')('docker-event-emitter'); class DockerEventEmitter extends EventEmitter { constructor(docker) { super(); this.docker = docker; this.running = false; this.eventsStream = null; this.transformStream = null; this.emitterStream = null; } async start() { debug('Starting events stream ...'); let { docker, running, eventsStream, transformStream, emitterStream, } = this; if (running) return this; running = true; transformStream = new Transform({ bufferStr: '', transform(chunk, enc, next) { const str = chunk.toString(); if (!str) return next(); this.bufferStr += str; if (/\n/.test(this.bufferStr)) { const events = this.bufferStr .split(/\n/) // WTF: ...something strange happens and undefined // is prepended to the string. Get rid of it .map(s => s.replace(/^undefined/, '')); for (let [i, json] of events.entries()) { if (i === events.length -1) { this.bufferStr = json; } else { try { this.push(json); } catch (err) { this.emit('error', err); } } } } next(); }, flush(done) { if (this.bufferStr) { try { JSON.parse(this.bufferStr); this.push(this.bufferStr); done(null, this.bufferStr); } catch (err) { done(err); } } }, }); emitterStream = new Writable({ write: (json, enc, next) => { const obj = JSON.parse(json); const { Type, Action } = obj; this.emit(Type, obj); this.emit(`${Type}.${Action}`, obj); this.emit('event', obj); next(); }, }); eventsStream = await docker.getEvents(); transformStream.pipe(emitterStream); eventsStream.pipe(transformStream); debug('Events stream running'); return this; } stop() { debug('Stopping events stream ...'); let { running, eventsStream, transformStream, emitterStream } = this; if (!running) return this; eventsStream.unpipe(emitterStream); transformStream.unpipe(emitterStream); eventsStream.destroy(); eventsStream = null; transformStream.destroy(); transformStream = null; emitterStream.destroy(); emitterStream = null; running = false; debug('Events stream halted'); return this; } } module.exports = DockerEventEmitter;