UNPKG

@remote.it/core

Version:

Core remote.it JavasScript/TypeScript library

124 lines (108 loc) 3.55 kB
import { ConfigFile } from './ConfigFile' import { FileWatcher } from './FileWatcher' import { ProcessManagerMessage } from './ProcessManager' import { ServiceProcessManager } from './ServiceProcessManager' import { SChannelListener } from './SChannelListener' import { TargetProcessManager } from './TargetProcessManager' import { UDPEventBroadcaster } from './UDPEventBroadcaster' import { Logger } from './Logger' const SERVICE_EVENTS: ProcessManagerMessage[] = [ 'adding', 'added', 'starting', 'started', 'restarting', 'restarted', 'stopping', 'stopped', ] const TARGET_EVENTS: ProcessManagerMessage[] = [ 'adding', 'added', 'starting', 'started', 'restarting', 'restarted', 'stopping', 'stopped', ] export class ProcessSupervisor { config: ConfigFile target: TargetProcessManager services: ServiceProcessManager broadcaster: UDPEventBroadcaster constructor(public configPath: string, public broadcastPort: number = 55000) { this.broadcaster = this.configureUDPEventBroadcaster() Logger.info('watching file:', { configPath }) this.config = new ConfigFile(configPath) this.target = this.manageTargetProcess() this.services = this.manageServiceProcesses() this.watchConfigFile() this.listenToSChannel() Logger.info('process supervisor started') } private configureUDPEventBroadcaster() { const broadcaster = new UDPEventBroadcaster(this.broadcastPort) broadcaster.broadcast('started:' + this.broadcastPort) return broadcaster } private manageTargetProcess() { const target = new TargetProcessManager() TARGET_EVENTS.map(e => target.on(e, uid => this.broadcaster.broadcast(`target/${e}/${uid}`)) ) target.update(this.config.target) return target } private manageServiceProcesses() { const services = new ServiceProcessManager() SERVICE_EVENTS.map(e => services.on(e, uid => this.broadcaster.broadcast(`service/${e}/${uid}`)) ) services.update(this.config.services) return services } private watchConfigFile() { const watcher = new FileWatcher(this.configPath) watcher.on('ready', path => Logger.info('watcher ready', { path })) watcher.on('created', path => Logger.info('file created', { path })) watcher.on('updated', () => { this.services.update(this.config.services) this.target.update(this.config.target) // initiators.update(config.initiators) }) watcher.on('removed', path => Logger.info('file removed', { path })) watcher.on('error', error => Logger.error('watcher error', { error })) } private listenToSChannel() { const schannel = new SChannelListener() schannel.on('ready', () => { Logger.info('schannel listener ready') this.broadcastStatus() }) schannel.on('error', error => Logger.info('schannel listener error:', { error }) ) schannel.on('message', message => { Logger.info('schannel listener message:', { message }) if (message === 'status') this.broadcastStatus() }) schannel.on('closed', () => Logger.info('schannel listener closed')) schannel.listen() } private broadcastStatus() { this.broadcaster.broadcast( 'status:' + JSON.stringify({ target: this.target.processes.map(p => ({ pid: p.process.pid, uid: p.config.uid, })), services: this.services.processes.map(p => ({ pid: p.process.pid, uid: p.config.uid, })), }) ) } }