From f0a98ba6850f30bd27409abf69c75b51a8b28e50 Mon Sep 17 00:00:00 2001 From: cgeek Date: Thu, 30 Apr 2020 15:19:58 +0200 Subject: [PATCH] [state]: watchers return a state --- src/dwatcher.ts | 5 ++-- src/lib/dwatch.ts | 17 +++++++------ src/lib/types/conf.ts | 1 + src/lib/types/state.ts | 24 ++++++++++++++++--- src/lib/watcherLoop.ts | 12 +++++++--- src/lib/watchers/abstract/url-watcher.ts | 6 +++-- src/lib/watchers/bma/bma-watcher.ts | 3 ++- .../dprobe/dprobe-heartbeat-watcher.ts | 2 +- src/lib/watchers/webdiff/webdiff-watcher.ts | 3 ++- src/lib/watchers/ws2p/ws2p-watcher.ts | 3 ++- tsconfig.json | 3 ++- 11 files changed, 57 insertions(+), 22 deletions(-) diff --git a/src/dwatcher.ts b/src/dwatcher.ts index a2171d1..732cf5c 100644 --- a/src/dwatcher.ts +++ b/src/dwatcher.ts @@ -1,6 +1,7 @@ import * as minimist from 'minimist' import * as path from 'path' import {dwatch} from './lib/dwatch' +import {Watcher} from "./lib/types/state"; process.on('uncaughtException', (err) => { // Dunno why this specific exception is not caught @@ -20,9 +21,9 @@ process.on('unhandledRejection', (err) => { console.log('Starting...') try { - await dwatch(argv.conf || path.join(__dirname, '../app.yml')) + const watchers: Watcher[] = await dwatch(argv.conf || path.join(__dirname, '../app.yml')) } catch (e) { + // webappServe(watchers) console.error(e) } })() - diff --git a/src/lib/dwatch.ts b/src/lib/dwatch.ts index 6da0e56..8a15d0f 100644 --- a/src/lib/dwatch.ts +++ b/src/lib/dwatch.ts @@ -5,16 +5,19 @@ import {ws2pWatcher} from "./watchers/ws2p/ws2p-watcher"; import {bmaWatcher} from "./watchers/bma/bma-watcher"; import {dprobeHeartbeat} from './watchers/dprobe/dprobe-heartbeat-watcher' import {webDiffWatcher} from "./watchers/webdiff/webdiff-watcher"; -import {ServiceState} from "./types/state"; +import {Watcher} from "./types/state"; export async function dwatch(confFile: string) { const yml = fs.readFileSync(confFile, 'utf8') const conf = yaml.load(yml) as Conf - const states: ServiceState[] = [] - const watchers: () => Promise<> - await Promise.all((conf.ws2pServers || []).map(ws2pWatcher(conf))) - await Promise.all((conf.bmaServers || []).map(bmaWatcher(conf))) - await Promise.all((conf.dprobeHeartbeats || []).map(dprobeHeartbeat(conf))) - await Promise.all((conf.webDiffServers || []).map(webDiffWatcher(conf))) + const watchers: Watcher[] = []; + (await Promise.all((conf.ws2pServers || []).map(ws2pWatcher(conf)))).forEach(w => watchers.push(w)); + (await Promise.all((conf.bmaServers || []).map(bmaWatcher(conf)))).forEach(w => watchers.push(w)); + (await Promise.all((conf.dprobeHeartbeats || []).map(dprobeHeartbeat(conf)))).forEach(w => watchers.push(w)); + (await Promise.all((conf.webDiffServers || []).map(webDiffWatcher(conf)))).forEach(w => watchers.push(w)); + return watchers } + +// (await Promise.all((conf.headServers || []).map(headWatcher(conf)))).forEach(w => watchers.push(w)); +// (await Promise.all((conf.wwMeta || []).map(jsonWatcher(conf)))).forEach(w => watchers.push(w)); \ No newline at end of file diff --git a/src/lib/types/conf.ts b/src/lib/types/conf.ts index c5ca0e4..7af98b5 100644 --- a/src/lib/types/conf.ts +++ b/src/lib/types/conf.ts @@ -17,6 +17,7 @@ export interface ConfWS2P { } export interface ConfURL { + name: string address: string frequency: number } diff --git a/src/lib/types/state.ts b/src/lib/types/state.ts index 34b30cb..98b7762 100644 --- a/src/lib/types/state.ts +++ b/src/lib/types/state.ts @@ -1,3 +1,21 @@ -export interface ServiceState { - state: 'INIT'|'OK'|'FAILURE' -} \ No newline at end of file +export class Watcher { + private state: 'INIT'|'OK'|'FAILURE'|'RECOVERED' + private failureMessage?: string + + constructor(public readonly name: string) { + this.state = "INIT" + } + + public stateOK() { + this.state = "OK" + } + + public stateRecovered() { + this.state = "RECOVERED" + } + + public stateFailure(error: string) { + this.state = "FAILURE" + this.failureMessage = error + } +} diff --git a/src/lib/watcherLoop.ts b/src/lib/watcherLoop.ts index 53c89f1..a2858aa 100644 --- a/src/lib/watcherLoop.ts +++ b/src/lib/watcherLoop.ts @@ -1,6 +1,7 @@ -import {ServiceState} from "./types/state"; +import {Watcher} from "./types/state"; export function watcherLoop( + name: string, connect: () => Promise, onConnectionClosed: () => Promise, reconnectionDelays: number[], @@ -9,9 +10,9 @@ export function watcherLoop( onRestart: () => Promise, onRestartSuccess: () => Promise, onError: (e: Error) => Promise, -): ServiceState { +): Watcher { - let state: ServiceState = { state: 'INIT' } + let watcher: Watcher = new Watcher(name) let hasStarted = false ;(async () => { @@ -31,8 +32,10 @@ export function watcherLoop( if (!hasStarted) { hasStarted = true await onStart() + watcher.stateOK() } else { await onRestartSuccess() + watcher.stateRecovered() } // We reset the delay of reconnection @@ -42,6 +45,7 @@ export function watcherLoop( } catch (e) { await onError(e) + watcher.stateFailure(e && e.message || e) } // Wait before reconnecting const waitingDelay = reconnectionDelays[Math.min(reconnectionDelays.length - 1, i)] @@ -50,4 +54,6 @@ export function watcherLoop( i++ } })() + + return watcher } diff --git a/src/lib/watchers/abstract/url-watcher.ts b/src/lib/watchers/abstract/url-watcher.ts index 9df5c34..c55cb70 100644 --- a/src/lib/watchers/abstract/url-watcher.ts +++ b/src/lib/watchers/abstract/url-watcher.ts @@ -2,15 +2,17 @@ import {watcherLoop} from "../../watcherLoop"; import {Conf, ConfURL} from "../../types/conf"; import Axios from "axios"; import {mail} from "../../mail"; +import {Watcher} from "../../types/state"; export function urlWatcher(conf: Conf, checkValidity: (data: any) => Promise) { - return async (urlConf: ConfURL) => { + return async (urlConf: ConfURL): Promise => { let nodeDownRes: () => void let nodeDownPromise: Promise = new Promise(res => nodeDownRes = res) - await watcherLoop( + return watcherLoop( + urlConf.name, async () => { let interval: NodeJS.Timer; const res = await Axios.get(urlConf.address) diff --git a/src/lib/watchers/bma/bma-watcher.ts b/src/lib/watchers/bma/bma-watcher.ts index 66e0b4d..3bbf9af 100644 --- a/src/lib/watchers/bma/bma-watcher.ts +++ b/src/lib/watchers/bma/bma-watcher.ts @@ -8,12 +8,13 @@ export function bmaWatcher(conf: Conf) { return async (bmaServer: ConfBMA) => { - await urlWatcher(conf, async (data) => { + return urlWatcher(conf, async (data) => { const block = data as { medianTime: number } if (bmaServer.maxLate && moment().unix() - block.medianTime > bmaServer.maxLate) { throw 'Server is late' } })({ + name: `BMA ${bmaServer.address}`, address: bmaServer.address + URL_PATH, frequency: bmaServer.frequency }) diff --git a/src/lib/watchers/dprobe/dprobe-heartbeat-watcher.ts b/src/lib/watchers/dprobe/dprobe-heartbeat-watcher.ts index c85b578..77f48a1 100644 --- a/src/lib/watchers/dprobe/dprobe-heartbeat-watcher.ts +++ b/src/lib/watchers/dprobe/dprobe-heartbeat-watcher.ts @@ -6,7 +6,7 @@ export function dprobeHeartbeat(conf: Conf) { return async (dconf: ConfDprobeHeartbeat) => { - await urlWatcher(conf, async (data) => { + return urlWatcher(conf, async (data) => { const last = moment(data, 'YYYY-MM-DD HH:mm:ss\n') const past = moment().diff(last) if (past > dconf.lastBeat) { diff --git a/src/lib/watchers/webdiff/webdiff-watcher.ts b/src/lib/watchers/webdiff/webdiff-watcher.ts index ad5d77c..1c14bce 100644 --- a/src/lib/watchers/webdiff/webdiff-watcher.ts +++ b/src/lib/watchers/webdiff/webdiff-watcher.ts @@ -39,7 +39,8 @@ export function webDiffWatcher(conf: Conf) { } } - await watcherLoop( + return watcherLoop( + `webdiff ${target}`, async () => { const data1 = await Axios.get(webDiffConf.file1) const data2 = await Axios.get(webDiffConf.file2) diff --git a/src/lib/watchers/ws2p/ws2p-watcher.ts b/src/lib/watchers/ws2p/ws2p-watcher.ts index 4ac53f3..a73e9dc 100644 --- a/src/lib/watchers/ws2p/ws2p-watcher.ts +++ b/src/lib/watchers/ws2p/ws2p-watcher.ts @@ -16,7 +16,8 @@ export function ws2pWatcher(conf: Conf) { const keypair = new Key(keys.pub, keys.sec) const target = `${wserver.address} (${wserver.expectedPubkey.substr(0, 8)})` - await watcherLoop( + return watcherLoop( + `WS2P ${wserver.address}`, async () => { const localAuth = new WS2PPubkeyLocalAuth(wserver.currency, keypair, "", async () => true) diff --git a/tsconfig.json b/tsconfig.json index e66cf50..5927488 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,8 @@ "noImplicitThis": true, "noImplicitAny": true, "noImplicitReturns": true, - "experimentalDecorators": true + "experimentalDecorators": true, + "skipLibCheck": true }, "include": [ "src/*",