import * as uuid from 'uuid' ; import { WatcherModel } from './model' ; import { Influx } from '../Influx/Influx' ; import { logger } from '../../logger' ; import { sleep , sendMail } from '../helpers' ; export enum WatcherStatus { RUNNING = 'RUNNING' , STOPPED = 'STOPPED' } export interface extends Document export interface IWatcherConfig { id ? : string ; type : string ; extra ? : any ; } export abstract class export abstract class Watcher { public id : string ; private status : WatcherStatus ; private influx : Influx ; private restart : number = 0 ; param { IWatcherConfig } conf param { boolean } persist memberof constructor ( public conf ) { this . id = conf . id || uuid . v1 ( ) ; this . status = WatcherStatus . STOPPED ; } abstract memberof public abstract async init ( ) ; abstract memberof public abstract async runWatcher ( ) ; abstract memberof public abstract async stopWatcher ( flushData ) ; public async run ( ) { this . status = WatcherStatus . RUNNING ; await this . save ( ) . catch ( error => logger . error ( error ) ) ; this . runWatcher ( ) . catch ( async ( error ) => { logger . error ( error ) ; try { if ( this . restart < 10 ) { this . restart += 1 ; await sleep ( 30 * 1000 ) ; logger . info ( `[Watcher] Try restarting (${ this . restart }/10) watcher ${ this . id }` ) ; await this . stop ( ) ; this . run ( ) . catch ( err => { throw err ; } ) ; } else { await this . stop ( ) ; sendMail ( `Watcher ${ this . id } stopped` ) ; logger . error ( `[Watcher] Stopping watcher ${ this . id } (can't restart it)` ) ; } } catch ( error ) { throw error ; } } ) ; } public async stop ( flushData = false ) { this . status = WatcherStatus . STOPPED ; await this . stopWatcher ( flushData ) ; await this . save ( ) ; } param { Influx } influx memberof public setInflux ( influx ) { this . influx = influx ; } returns { Influx } memberof public getInflux ( ) { if ( ! this . influx ) { throw new Error ( 'No Influx instance set for this watcher' ) ; } return this . influx ; } param { * } config memberof public async save ( ) { const { type , ... extra } = this . conf ; const watcher = { ... extra , id : this . id , type , status : this . status } ; await WatcherModel . findOneAndUpdate ( { id : this . id } , watcher , { upsert : true } ) ; } }