tunnel in child process

This commit is contained in:
hatim boufnichel 2021-04-16 23:01:33 +02:00
parent 58f3e343f4
commit b65bdc771b
2 changed files with 71 additions and 34 deletions

View file

@ -6,7 +6,6 @@
* Module dependencies. * Module dependencies.
*/ */
const server = program => { const server = program => {
const localtunnel = require('localtunnel')
const Http = require('http') const Http = require('http')
const Express = require('express') const Express = require('express')
const Crypto = require('crypto') const Crypto = require('crypto')
@ -15,6 +14,9 @@ const server = program => {
const Path = require('path') const Path = require('path')
const { Logger: CommonLogger } = require('shock-common') const { Logger: CommonLogger } = require('shock-common')
const binaryParser = require('socket.io-msgpack-parser') const binaryParser = require('socket.io-msgpack-parser')
const { fork } = require('child_process')
const EventEmitter = require('events')
const ECC = require('../utils/ECC') const ECC = require('../utils/ECC')
const LightningServices = require('../utils/lightningServices') const LightningServices = require('../utils/lightningServices')
const Encryption = require('../utils/encryptionStore') const Encryption = require('../utils/encryptionStore')
@ -54,6 +56,31 @@ const server = program => {
require('../utils/server-utils')(module) require('../utils/server-utils')(module)
logger.info('Mainnet Mode:', !!program.mainnet) logger.info('Mainnet Mode:', !!program.mainnet)
const tunnelTimeout = 5000
let latestAliveTunnel = 0
let tunnelHealthInterval = null
const tunnelHealthManager = new EventEmitter()
tunnelHealthManager.on('fork', ({ params, cb }) => {
if (latestAliveTunnel !== 0 && latestAliveTunnel < tunnelTimeout) {
return
}
clearInterval(tunnelHealthInterval)
tunnelHealthInterval = setInterval(() => {
if (Date.now() - latestAliveTunnel > tunnelTimeout) {
console.log('oh no! tunnel is dead, will restart it now')
tunnelHealthManager.emit('fork', { params, cb })
}
}, 2000)
const forked = fork('src/tunnel.js')
forked.on('message', msg => {
//console.log('Message from child', msg);
if (msg && msg.type === 'info') {
cb(msg.tunnel)
}
latestAliveTunnel = Date.now()
})
forked.send(params)
})
if (process.env.DISABLE_SHOCK_ENCRYPTION === 'true') { if (process.env.DISABLE_SHOCK_ENCRYPTION === 'true') {
logger.error('Encryption Mode: false') logger.error('Encryption Mode: false')
@ -203,10 +230,6 @@ const server = program => {
// eslint-disable-next-line consistent-return // eslint-disable-next-line consistent-return
const startServer = async () => { const startServer = async () => {
/**
* @type {localtunnel.Tunnel}
*/
let tunnelRef = null
try { try {
LightningServices.setDefaults(program) LightningServices.setDefaults(program)
if (!LightningServices.isInitialized()) { if (!LightningServices.isInitialized()) {
@ -284,8 +307,9 @@ const server = program => {
} else { } else {
logger.info('Creating new tunnel... ') logger.info('Creating new tunnel... ')
} }
const tunnel = await localtunnel(tunnelOpts) tunnelHealthManager.emit('fork', {
tunnelRef = tunnel params: tunnelOpts,
cb: async tunnel => {
logger.info('Tunnel created! connect to: ' + tunnel.url) logger.info('Tunnel created! connect to: ' + tunnel.url)
const dataToQr = JSON.stringify({ const dataToQr = JSON.stringify({
internalIP: tunnel.url, internalIP: tunnel.url,
@ -312,6 +336,8 @@ const server = program => {
]) ])
} }
} }
})
}
const storePersistentRandomField = async ({ fieldName, length = 16 }) => { const storePersistentRandomField = async ({ fieldName, length = 16 }) => {
const randomField = await Storage.getItem(fieldName) const randomField = await Storage.getItem(fieldName)
@ -443,9 +469,6 @@ const server = program => {
} catch (err) { } catch (err) {
logger.error({ exception: err, message: err.message, code: err.code }) logger.error({ exception: err, message: err.message, code: err.code })
logger.info('Restarting server in 30 seconds...') logger.info('Restarting server in 30 seconds...')
if (tunnelRef) {
tunnelRef.close()
}
await wait(30) await wait(30)
startServer() startServer()
return false return false

14
src/tunnel.js Normal file
View file

@ -0,0 +1,14 @@
const localtunnel = require('localtunnel')
process.on('message', async (tunnelOpts) => {
console.log('Message from parent:', tunnelOpts);
const tunnel = await localtunnel(tunnelOpts)
process.send({ type: 'info', tunnel:{
url:tunnel.url,
token:tunnel.token,
clientId:tunnel.clientId,
} });
});
setInterval(() => {
process.send({ type: "ping" });
}, 1000);