[enh] Auto-restart
This commit is contained in:
16
app.yml
16
app.yml
@@ -1,11 +1,25 @@
|
|||||||
|
currency: g1-test # Ensure we connect to the correct currency
|
||||||
salt: test
|
salt: test
|
||||||
passwd: test
|
passwd: test
|
||||||
|
connectionTimeout: 10000
|
||||||
|
reconnectionDelays:
|
||||||
|
- 5000
|
||||||
|
- 10000
|
||||||
|
- 15000
|
||||||
|
- 30000
|
||||||
|
- 60000 # 1'
|
||||||
|
- 300000 # 5'
|
||||||
|
- 900000 # 15'
|
||||||
|
- 3600000 # 1h
|
||||||
|
- 7200000 # 2h
|
||||||
|
- 21600000 # 6h
|
||||||
|
- 43200000 # 12h
|
||||||
ws2pServers:
|
ws2pServers:
|
||||||
- address: ws://g1-test.cgeek.fr:20900
|
- address: ws://g1-test.cgeek.fr:20900
|
||||||
expectedPubkey: 2ny7YAdmzReQxAayyJZsyVYwYhVyax2thKcGknmQy5nQ
|
expectedPubkey: 2ny7YAdmzReQxAayyJZsyVYwYhVyax2thKcGknmQy5nQ
|
||||||
|
|
||||||
mail:
|
mail:
|
||||||
enabled: true
|
enabled: false
|
||||||
host: smtp.sparkpostmail.com
|
host: smtp.sparkpostmail.com
|
||||||
port: 587
|
port: 587
|
||||||
auth: LOGIN
|
auth: LOGIN
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ export interface Conf {
|
|||||||
currency: string
|
currency: string
|
||||||
salt: string
|
salt: string
|
||||||
passwd: string
|
passwd: string
|
||||||
connectionTimeout: 10000
|
connectionTimeout: number
|
||||||
|
reconnectionDelays: number[]
|
||||||
ws2pServers: ConfServers[]
|
ws2pServers: ConfServers[]
|
||||||
mail: ConfMail
|
mail: ConfMail
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {Key} from 'duniter/app/lib/common-libs/crypto/keyring'
|
|||||||
import {Scrypt} from 'duniter/app/modules/keypair/lib/scrypt'
|
import {Scrypt} from 'duniter/app/modules/keypair/lib/scrypt'
|
||||||
import {sendMail} from './sendMail'
|
import {sendMail} from './sendMail'
|
||||||
import {moment} from 'duniter/app/lib/common-libs/moment'
|
import {moment} from 'duniter/app/lib/common-libs/moment'
|
||||||
|
import {processHandler} from './processHandler'
|
||||||
|
|
||||||
export async function dwatch(confFile: string) {
|
export async function dwatch(confFile: string) {
|
||||||
|
|
||||||
@@ -17,36 +18,69 @@ export async function dwatch(confFile: string) {
|
|||||||
|
|
||||||
await Promise.all(conf.ws2pServers.map(async wserver => {
|
await Promise.all(conf.ws2pServers.map(async wserver => {
|
||||||
|
|
||||||
const localAuth = new WS2PPubkeyLocalAuth(conf.currency, keypair, "", async () => true)
|
await processHandler(
|
||||||
const remoteAuth = new WS2PPubkeyRemoteAuth(conf.currency, keypair, async () => true)
|
() => {
|
||||||
|
|
||||||
const c = WS2PConnection.newConnectionToAddress(
|
const localAuth = new WS2PPubkeyLocalAuth(conf.currency, keypair, "", async () => true)
|
||||||
1,
|
const remoteAuth = new WS2PPubkeyRemoteAuth(conf.currency, keypair, async () => true)
|
||||||
wserver.address,
|
|
||||||
new MessageHandler(),
|
return WS2PConnection.newConnectionToAddress(
|
||||||
localAuth,
|
1,
|
||||||
remoteAuth,
|
wserver.address,
|
||||||
undefined,
|
new MessageHandler(),
|
||||||
{
|
localAuth,
|
||||||
connectionTimeout: conf.connectionTimeout,
|
remoteAuth,
|
||||||
requestTimeout: 0 // No request anyway
|
undefined,
|
||||||
|
{
|
||||||
|
connectionTimeout: conf.connectionTimeout,
|
||||||
|
requestTimeout: 0 // No request anyway
|
||||||
|
},
|
||||||
|
wserver.expectedKey
|
||||||
|
)
|
||||||
},
|
},
|
||||||
wserver.expectedKey
|
|
||||||
)
|
|
||||||
|
|
||||||
await c.connectAsInitiator()
|
conf.reconnectionDelays,
|
||||||
|
|
||||||
c.closed.then(async () => {
|
async (c: WS2PConnection) => {
|
||||||
console.log('Connection closed')
|
console.log('Connection established')
|
||||||
await sendMail(conf.mail, '[dwatcher] Connection closed', `
|
await sendMail(conf.mail, '[dwatcher] Connection established', `
|
||||||
|
<p>
|
||||||
|
Connection to ${c.pubkey} established on ${moment().format('DD-MM-YYYY HH:mm:ss')}.
|
||||||
|
</p>
|
||||||
|
`)
|
||||||
|
},
|
||||||
|
|
||||||
|
// When a disconnection is detected
|
||||||
|
async (c: WS2PConnection, waitingDelay) => {
|
||||||
|
console.log('Connection closed')
|
||||||
|
console.log('Waiting %s seconds...', waitingDelay)
|
||||||
|
await sendMail(conf.mail, '[dwatcher] Connection closed', `
|
||||||
|
<p>
|
||||||
|
Connection to ${c.pubkey} was lost on ${moment().format('dd-MM-YYYY HH:mm:ss')}.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Waiting ${(waitingDelay / 1000).toFixed(0)} seconds before trying to reconnect.
|
||||||
|
</p>
|
||||||
|
`)
|
||||||
|
},
|
||||||
|
|
||||||
|
async (c: WS2PConnection) => {
|
||||||
|
console.log('Trying to connect to %s', c.pubkey)
|
||||||
|
},
|
||||||
|
|
||||||
|
async (c: WS2PConnection) => {
|
||||||
|
console.log('Connection recovered')
|
||||||
|
await sendMail(conf.mail, '[dwatcher] Connection recovered', `
|
||||||
<p>
|
<p>
|
||||||
Connection to ${c.pubkey} was lost on ${moment().format('dd-MM-YYYY HH:mm:ss')}.
|
Connection to ${c.pubkey} was lost on ${moment().format('dd-MM-YYYY HH:mm:ss')}.
|
||||||
</p>
|
</p>
|
||||||
`)
|
`)
|
||||||
})
|
},
|
||||||
|
|
||||||
await c.connected
|
async (e) => {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
console.log('Connected to %s', c.pubkey)
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
52
src/lib/processHandler.ts
Normal file
52
src/lib/processHandler.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import {WS2PConnection} from 'duniter/app/modules/ws2p/lib/WS2PConnection'
|
||||||
|
|
||||||
|
export async function processHandler(
|
||||||
|
getConnection: () => WS2PConnection,
|
||||||
|
reconnectionDelays: number[],
|
||||||
|
onStart: (c: WS2PConnection) => Promise<void>,
|
||||||
|
onDisconnection: (c: WS2PConnection, waitingDelay: number) => Promise<void>,
|
||||||
|
onRestart: (c: WS2PConnection) => Promise<void>,
|
||||||
|
onRestartSuccess: (c: WS2PConnection) => Promise<void>,
|
||||||
|
onError: (e: Error) => Promise<void>,
|
||||||
|
) {
|
||||||
|
|
||||||
|
let hasStarted = false
|
||||||
|
let connection = getConnection()
|
||||||
|
let connecting = connection.connectAsInitiator()
|
||||||
|
|
||||||
|
;(async () => {
|
||||||
|
|
||||||
|
let connected = false
|
||||||
|
let i = 0
|
||||||
|
while (!connected) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (hasStarted) {
|
||||||
|
await onRestart(connection)
|
||||||
|
connection = getConnection()
|
||||||
|
connecting = connection.connectAsInitiator()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connection trial
|
||||||
|
await connecting
|
||||||
|
|
||||||
|
if (!hasStarted) {
|
||||||
|
hasStarted = true
|
||||||
|
await onStart(connection)
|
||||||
|
} else {
|
||||||
|
await onRestartSuccess(connection)
|
||||||
|
}
|
||||||
|
|
||||||
|
await connection.closed
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
await onError(e)
|
||||||
|
}
|
||||||
|
// Wait before reconnecting
|
||||||
|
const waitingDelay = reconnectionDelays[Math.min(reconnectionDelays.length - 1, i)]
|
||||||
|
await onDisconnection(connection, waitingDelay)
|
||||||
|
await new Promise(resolve => setTimeout(resolve, waitingDelay))
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user