[enh] add url watcher + add optional maxLate parameter for BMA watcher
This commit is contained in:
8
app.yml
8
app.yml
@@ -21,6 +21,14 @@ ws2pServers:
|
|||||||
bmaServers:
|
bmaServers:
|
||||||
- address: https://g1-test.cgeek.fr
|
- address: https://g1-test.cgeek.fr
|
||||||
frequency: 60000 # 1'
|
frequency: 60000 # 1'
|
||||||
|
- address: http://remuniter.cgeek.fr:16120
|
||||||
|
frequency: 60000 # 1'
|
||||||
|
maxLate: 14400000 # 4h'
|
||||||
|
|
||||||
|
dprobeHeartbeats:
|
||||||
|
- address: https://wotwizard.cgeek.fr/dprobe.heartbeat.txt
|
||||||
|
frequency: 60000 # 1'
|
||||||
|
lastBeat: 300000 # 5'
|
||||||
|
|
||||||
mail:
|
mail:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import * as yaml from 'js-yaml';
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import {ws2pWatcher} from "./watchers/ws2p/ws2p-watcher";
|
import {ws2pWatcher} from "./watchers/ws2p/ws2p-watcher";
|
||||||
import {bmaWatcher} from "./watchers/bma/bma-watcher";
|
import {bmaWatcher} from "./watchers/bma/bma-watcher";
|
||||||
|
import {dprobeHeartbeat} from './watchers/dprobe/dprobe-heartbeat-watcher'
|
||||||
|
|
||||||
export async function dwatch(confFile: string) {
|
export async function dwatch(confFile: string) {
|
||||||
|
|
||||||
@@ -11,4 +12,5 @@ export async function dwatch(confFile: string) {
|
|||||||
|
|
||||||
await Promise.all((conf.ws2pServers || []).map(ws2pWatcher(conf)))
|
await Promise.all((conf.ws2pServers || []).map(ws2pWatcher(conf)))
|
||||||
await Promise.all((conf.bmaServers || []).map(bmaWatcher(conf)))
|
await Promise.all((conf.bmaServers || []).map(bmaWatcher(conf)))
|
||||||
|
await Promise.all((conf.dprobeHeartbeats || []).map(dprobeHeartbeat(conf)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ export interface Conf {
|
|||||||
reconnectionDelays: number[]
|
reconnectionDelays: number[]
|
||||||
ws2pServers: ConfWS2P[]
|
ws2pServers: ConfWS2P[]
|
||||||
bmaServers: ConfBMA[]
|
bmaServers: ConfBMA[]
|
||||||
|
dprobeHeartbeats: ConfDprobeHeartbeat[]
|
||||||
mail: ConfMail
|
mail: ConfMail
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,11 +15,19 @@ export interface ConfWS2P {
|
|||||||
currency: string
|
currency: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConfBMA {
|
export interface ConfURL {
|
||||||
address: string
|
address: string
|
||||||
frequency: number
|
frequency: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ConfBMA extends ConfURL {
|
||||||
|
maxLate?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConfDprobeHeartbeat extends ConfURL{
|
||||||
|
lastBeat: number
|
||||||
|
}
|
||||||
|
|
||||||
export interface ConfMail {
|
export interface ConfMail {
|
||||||
enabled: boolean
|
enabled: boolean
|
||||||
host: string
|
host: string
|
||||||
|
|||||||
54
src/lib/watchers/abstract/url-watcher.ts
Normal file
54
src/lib/watchers/abstract/url-watcher.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import {watcherLoop} from "../../watcherLoop";
|
||||||
|
import {Conf, ConfURL} from "../../types/conf";
|
||||||
|
import Axios from "axios";
|
||||||
|
import {mail} from "../../mail";
|
||||||
|
|
||||||
|
export function urlWatcher(conf: Conf, checkValidity: (data: any) => Promise<void>) {
|
||||||
|
|
||||||
|
return async (urlConf: ConfURL) => {
|
||||||
|
|
||||||
|
let nodeDownRes: () => void
|
||||||
|
let nodeDownPromise: Promise<void> = new Promise(res => nodeDownRes = res)
|
||||||
|
|
||||||
|
await watcherLoop(
|
||||||
|
async () => {
|
||||||
|
let interval: NodeJS.Timer;
|
||||||
|
const res = await Axios.get(urlConf.address)
|
||||||
|
await checkValidity(res.data)
|
||||||
|
interval = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
const res = await Axios.get(urlConf.address)
|
||||||
|
await checkValidity(res.data)
|
||||||
|
} catch (e) {
|
||||||
|
if (interval) {
|
||||||
|
clearInterval(interval)
|
||||||
|
}
|
||||||
|
nodeDownRes()
|
||||||
|
// Re-create down promise for future connection trial
|
||||||
|
nodeDownPromise = new Promise(res => nodeDownRes = res)
|
||||||
|
}
|
||||||
|
}, urlConf.frequency)
|
||||||
|
},
|
||||||
|
|
||||||
|
() => nodeDownPromise,
|
||||||
|
|
||||||
|
conf.reconnectionDelays,
|
||||||
|
|
||||||
|
mail.onEstablished(conf, urlConf.address),
|
||||||
|
|
||||||
|
// When a disconnection is detected
|
||||||
|
mail.onDisconnect(conf, urlConf.address),
|
||||||
|
|
||||||
|
async () => {
|
||||||
|
console.log('Trying to connect to %s', urlConf.address)
|
||||||
|
},
|
||||||
|
|
||||||
|
mail.onRestartSuccess(conf, urlConf.address),
|
||||||
|
|
||||||
|
async (e) => {
|
||||||
|
console.error(e.message || e)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import {watcherLoop} from "../../watcherLoop";
|
|
||||||
import {Conf, ConfBMA} from "../../types/conf";
|
import {Conf, ConfBMA} from "../../types/conf";
|
||||||
import Axios from "axios";
|
import {urlWatcher} from '../abstract/url-watcher'
|
||||||
import {mail} from "../../mail";
|
import {moment} from 'duniter/app/lib/common-libs/moment'
|
||||||
|
|
||||||
export function bmaWatcher(conf: Conf) {
|
export function bmaWatcher(conf: Conf) {
|
||||||
|
|
||||||
@@ -9,43 +8,14 @@ export function bmaWatcher(conf: Conf) {
|
|||||||
|
|
||||||
return async (bmaServer: ConfBMA) => {
|
return async (bmaServer: ConfBMA) => {
|
||||||
|
|
||||||
let nodeDownRes: () => void
|
await urlWatcher(conf, async (data) => {
|
||||||
let nodeDownPromise: Promise<void> = new Promise(res => nodeDownRes = res)
|
const block = data as { medianTime: number }
|
||||||
|
if (bmaServer.maxLate && moment().unix() - block.medianTime > bmaServer.maxLate) {
|
||||||
await watcherLoop(
|
throw 'Server is late'
|
||||||
async () => {
|
|
||||||
await Axios.get(bmaServer.address + URL_PATH)
|
|
||||||
let interval = setInterval(async () => {
|
|
||||||
try {
|
|
||||||
await Axios.get(bmaServer.address + URL_PATH)
|
|
||||||
} catch (e) {
|
|
||||||
clearInterval(interval)
|
|
||||||
nodeDownRes()
|
|
||||||
// Re-create down promise for future connection trial
|
|
||||||
nodeDownPromise = new Promise(res => nodeDownRes = res)
|
|
||||||
}
|
}
|
||||||
}, bmaServer.frequency)
|
})({
|
||||||
},
|
address: bmaServer.address + URL_PATH,
|
||||||
|
frequency: bmaServer.frequency
|
||||||
() => nodeDownPromise,
|
})
|
||||||
|
|
||||||
conf.reconnectionDelays,
|
|
||||||
|
|
||||||
mail.onEstablished(conf, bmaServer.address),
|
|
||||||
|
|
||||||
// When a disconnection is detected
|
|
||||||
mail.onDisconnect(conf, bmaServer.address),
|
|
||||||
|
|
||||||
async () => {
|
|
||||||
console.log('Trying to connect to %s', bmaServer.address)
|
|
||||||
},
|
|
||||||
|
|
||||||
mail.onRestartSuccess(conf, bmaServer.address),
|
|
||||||
|
|
||||||
async (e) => {
|
|
||||||
console.error(e.message)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/lib/watchers/dprobe/dprobe-heartbeat-watcher.ts
Normal file
17
src/lib/watchers/dprobe/dprobe-heartbeat-watcher.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import {Conf, ConfDprobeHeartbeat} from "../../types/conf";
|
||||||
|
import {urlWatcher} from '../abstract/url-watcher'
|
||||||
|
import {moment} from 'duniter/app/lib/common-libs/moment'
|
||||||
|
|
||||||
|
export function dprobeHeartbeat(conf: Conf) {
|
||||||
|
|
||||||
|
return async (dconf: ConfDprobeHeartbeat) => {
|
||||||
|
|
||||||
|
await urlWatcher(conf, async (data) => {
|
||||||
|
const last = moment(data, 'YYYY-MM-DD HH:mm:ss\n')
|
||||||
|
const past = moment().diff(last)
|
||||||
|
if (past > dconf.lastBeat) {
|
||||||
|
throw 'Delay is over'
|
||||||
|
}
|
||||||
|
})(dconf)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user