[mod] recall of FAILURE state periodically

This commit is contained in:
2020-05-08 11:40:25 +02:00
parent 9ebf9d94fe
commit 4bed33d66f
8 changed files with 43 additions and 22 deletions

View File

@@ -1,5 +1,6 @@
connectionTimeout: 10000 # 10" connectionTimeout: 10000 # 10"
waitingDelay: 60000 # 1' waitingDelay: 5000 # 5"
recallDelay: 60000
ws2pServers: ws2pServers:
- address: ws://g1-test.cgeek.fr:22001 - address: ws://g1-test.cgeek.fr:22001
expectedPubkey: 3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj expectedPubkey: 3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj

View File

@@ -44,18 +44,18 @@ export const mail = {
} }
}, },
onDisconnect: (conf: Conf, target: string, message = `Connection closed for ${target}`, getErrorMessage: () => string = () => '', getHtml: (waitingDelay: number) => string = (waitingDelay: number) => ` onDisconnect: (conf: Conf, target: string, message = `Connection closed for ${target}`, getErrorMessage: () => string = () => '', getHtml: (waitingDelay: number, recallDelay: number) => string = (waitingDelay: number, recallDelay: number) => `
<p> <p>
Connection from [${os.hostname}] to ${target} was lost on ${moment().format('dd-MM-YYYY HH:mm:ss')}. Connection from [${os.hostname}] to ${target} was lost on ${moment().format('dd-MM-YYYY HH:mm:ss')}.
</p> </p>
<p> <p>
Waiting ${(waitingDelay / 1000).toFixed(0)} seconds before trying to reconnect. Waiting ${(waitingDelay / 1000).toFixed(0)} seconds before trying to reconnect (${(recallDelay / 1000).toFixed(0)} seconds for recall).
</p> </p>
${getErrorMessage()} ${getErrorMessage()}
`) => { `) => {
return async (waitingDelay: number, cc?: string) => { return async (waitingDelay: number, recallDelay: number, cc?: string) => {
console.log('Waiting %s seconds...', (waitingDelay / 1000).toFixed(0)) console.log('Waiting %s seconds...', (waitingDelay / 1000).toFixed(0))
await sendMail(conf.mail, `[dw] [${os.hostname}] ${message}`, getHtml(waitingDelay), cc) await sendMail(conf.mail, `[dw] [${os.hostname}] ${message}`, getHtml(waitingDelay, recallDelay), cc)
} }
}, },

View File

@@ -1,6 +1,7 @@
export interface Conf { export interface Conf {
connectionTimeout: number connectionTimeout: number
waitingDelay: number waitingDelay: number
recallDelay: number
ws2pServers: ConfWS2P[] ws2pServers: ConfWS2P[]
bmaServers: ConfBMA[] bmaServers: ConfBMA[]
dprobeHeartbeats: ConfDprobeHeartbeat[] dprobeHeartbeats: ConfDprobeHeartbeat[]

View File

@@ -1,26 +1,26 @@
export class Watcher { export class Watcher {
private _state: 'INIT'|'OK'|'FAILURE'|'RECOVERED' private _state: WatcherState
private _stateChanged: boolean private _stateChanged: boolean
private _stateChangedLastTime: number
private _error?: any private _error?: any
constructor(public readonly name: string) { constructor(
this._stateChanged = false public readonly name: string,
this._state = "INIT" private recallDelay: number
) {
this.changeToState("INIT")
} }
public stateOK() { public stateOK() {
this._stateChanged = this._state !== "OK" this.changeToState("OK")
this._state = "OK"
} }
public stateRecovered() { public stateRecovered() {
this._stateChanged = this._state !== "RECOVERED" this.changeToState("RECOVERED")
this._state = "RECOVERED"
} }
public stateFailure(error: any) { public stateFailure(error: any) {
this._stateChanged = this._state !== "FAILURE" this.changeToState("FAILURE")
this._state = "FAILURE"
this._error = error this._error = error
} }
@@ -42,4 +42,19 @@ export class Watcher {
} }
return this._error.message || this._error return this._error.message || this._error
} }
private changeToState(newState: WatcherState) {
this._stateChanged = this._state !== newState
this._state = newState
if (this._stateChanged) {
this._stateChangedLastTime = Date.now()
}
else if (Date.now() - this._stateChangedLastTime > this.recallDelay) {
// Same state for long enough time
this._stateChanged = true
this._stateChangedLastTime = Date.now()
}
}
} }
type WatcherState = 'INIT'|'OK'|'FAILURE'|'RECOVERED'

View File

@@ -5,13 +5,14 @@ export function watcherLoop(
connect: () => Promise<void>, connect: () => Promise<void>,
onConnectionClosed: () => Promise<void>, onConnectionClosed: () => Promise<void>,
waitingDelay: number, waitingDelay: number,
recallDelay: number,
onStart: () => Promise<void>, onStart: () => Promise<void>,
onDisconnection: (waitingDelay: number, error: any) => Promise<void>, onDisconnection: (waitingDelay: number, recallDelay: number, error: any) => Promise<void>,
onRestart: () => Promise<void>, onRestart: () => Promise<void>,
onRestartSuccess: () => Promise<void>, onRestartSuccess: () => Promise<void>,
): Watcher { ): Watcher {
let watcher: Watcher = new Watcher(name) let watcher: Watcher = new Watcher(name, recallDelay)
let hasStarted = false let hasStarted = false
;(async () => { ;(async () => {
@@ -48,7 +49,7 @@ export function watcherLoop(
// Wait before reconnecting // Wait before reconnecting
if (watcher.stateChanged) { if (watcher.stateChanged) {
// Notify only if state changed since // Notify only if state changed since
await onDisconnection(waitingDelay, watcher.error) await onDisconnection(waitingDelay, recallDelay, watcher.error)
} }
await new Promise(resolve => setTimeout(resolve, waitingDelay)) await new Promise(resolve => setTimeout(resolve, waitingDelay))
i++ i++

View File

@@ -45,18 +45,19 @@ export function urlWatcher(conf: Conf, checkValidity: (data: any) => Promise<Url
() => nodeDownPromise, () => nodeDownPromise,
conf.waitingDelay, conf.waitingDelay,
conf.recallDelay,
mail.onEstablished(conf, urlConf.address, getOkTitle()), mail.onEstablished(conf, urlConf.address, getOkTitle()),
// When a disconnection is detected // When a disconnection is detected
(waitingDelay: number, error?: any) => { (waitingDelay: number, recallDelay, error?: any) => {
let koTitle: string|undefined let koTitle: string|undefined
let koMessage: (() => string)|undefined let koMessage: (() => string)|undefined
if (error && error instanceof UrlWatcherError) { if (error && error instanceof UrlWatcherError) {
koTitle = getKoTitle() koTitle = getKoTitle()
koMessage = () => `<p>${error.errorMessage}</p>` koMessage = () => `<p>${error.errorMessage}</p>`
} }
return mail.onDisconnect(conf, urlConf.address, koTitle, koMessage)(waitingDelay) return mail.onDisconnect(conf, urlConf.address, koTitle, koMessage)(waitingDelay, recallDelay)
}, },
async () => { async () => {

View File

@@ -62,16 +62,17 @@ export function webDiffWatcher(conf: Conf) {
() => nodeDownPromise, () => nodeDownPromise,
conf.waitingDelay, conf.waitingDelay,
conf.recallDelay,
() => mail.onEstablished(conf, target, 'webdiff successfully started')(webDiffConf.cc), () => mail.onEstablished(conf, target, 'webdiff successfully started')(webDiffConf.cc),
// When a disconnection is detected // When a disconnection is detected
(waitingDelay: number) => mail.onDisconnect(conf, target, 'Diff detected', undefined, (waitingDelay: number) => ` (waitingDelay: number, recallDelay: number) => mail.onDisconnect(conf, target, 'Diff detected', undefined, (waitingDelay: number) => `
${htmlDiff} ${htmlDiff}
<p> <p>
Waiting ${(waitingDelay / 1000).toFixed(0)} seconds before trying to reconnect. Waiting ${(waitingDelay / 1000).toFixed(0)} seconds before trying to reconnect.
</p> </p>
`)(waitingDelay, webDiffConf.cc), `)(waitingDelay, recallDelay, webDiffConf.cc),
async () => { async () => {
console.log('Trying to connect to %s', target) console.log('Trying to connect to %s', target)

View File

@@ -43,6 +43,7 @@ export function ws2pWatcher(conf: Conf) {
() => c.closed, () => c.closed,
conf.waitingDelay, conf.waitingDelay,
conf.recallDelay,
mail.onEstablished(conf, target), mail.onEstablished(conf, target),