observer added, database added to improve fault tolerance, config fixed, ping added, port allocation improved, session observer added, multiple checks added, run process improved, process running check added, fault tolerance improved
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
const {coordinator_url} = require('../../config')
|
||||
const request = require('request')
|
||||
const max_response_timeout = 1000
|
||||
|
||||
const close_session = async (session_id) => {
|
||||
var options = {
|
||||
url: coordinator_url + '/session_server/session_closed',
|
||||
method: "POST",
|
||||
timeout: max_response_timeout,
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
json: {
|
||||
session_id: session_id
|
||||
}
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
request(options,
|
||||
async function(err, answer, data) {
|
||||
if (err || answer.statusCode != 200) {
|
||||
resolve(false)
|
||||
} else {
|
||||
resolve(true)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
close_session
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
const portfinder = require('portfinder')
|
||||
const {webrtc_port_begin, session_limit} = require('../../config')
|
||||
|
||||
const min_available_port = 2000
|
||||
const max_available_port = 65535
|
||||
|
||||
const get_port_in_range = async (first, last) => {
|
||||
//could be singleton problem
|
||||
portfinder.setBasePort(first)
|
||||
portfinder.setHighestPort(last)
|
||||
try {
|
||||
var port = await portfinder.getPortPromise()
|
||||
return port
|
||||
} catch(err) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const get_webrtc_port = async () => {
|
||||
var port = await get_port_in_range(webrtc_port_begin, webrtc_port_begin + session_limit - 1)
|
||||
return port
|
||||
}
|
||||
|
||||
const get_app_port = async () => {
|
||||
const port_range_size_before_webrtc = webrtc_port_begin - min_available_port
|
||||
const port_range_after_webrtc = max_available_port - (webrtc_port_begin + session_limit)
|
||||
|
||||
var port
|
||||
if (port_range_size_before_webrtc > port_range_after_webrtc) {
|
||||
port = await get_port_in_range(min_available_port, webrtc_port_begin - 1)
|
||||
} else {
|
||||
port = await get_port_in_range(webrtc_port_begin + session_limit, max_available_port)
|
||||
}
|
||||
return port
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
get_webrtc_port,
|
||||
get_app_port
|
||||
}
|
||||
|
||||
// class port {
|
||||
// constructor(value) {
|
||||
// this.#value = value
|
||||
// this.#free = true
|
||||
// }
|
||||
// get_value() {
|
||||
// return this.#value
|
||||
// }
|
||||
// set_free() {
|
||||
// this.#free = true
|
||||
// }
|
||||
// set_busy() {
|
||||
// this.#free = false
|
||||
// }
|
||||
// is_free() {
|
||||
// return this.#free
|
||||
// }
|
||||
// #value
|
||||
// #free
|
||||
// }
|
||||
|
||||
// class port_alloc {
|
||||
// constructor(port_begin, count) {
|
||||
// this.#ports = new Array()
|
||||
// for (var i = port_begin; i < port_begin + count; ++i) {
|
||||
// this.#ports.push(new port(i))
|
||||
// }
|
||||
// }
|
||||
// get() {
|
||||
// for (var i in this.#ports) {
|
||||
// if (this.#ports[i].is_free()) {
|
||||
// this.#ports[i].set_busy()
|
||||
// return this.#ports[i].get_value()
|
||||
// }
|
||||
// }
|
||||
// throw new Error('no free ports')
|
||||
// }
|
||||
// free(busy_port) {
|
||||
// for (var i in this.#ports) {
|
||||
// if (this.#ports[i].get_value() == busy_port) {
|
||||
// this.#ports[i].set_free()
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// #ports
|
||||
// }
|
||||
@@ -0,0 +1,78 @@
|
||||
const {spawn, fork} = require('node:child_process')
|
||||
const is_running = require('is-running')
|
||||
const config = require('../../config')
|
||||
const webrtc_server_path = config.webrtc_server_path
|
||||
const app_args_static = config.app_args.static
|
||||
const app_port_arg = config.app_args.runtime.port
|
||||
const fs = require('fs')
|
||||
|
||||
const is_proc_running = (pid) => {
|
||||
return is_running(pid)
|
||||
}
|
||||
|
||||
const is_proc_running_async = async (pid, check_time) => {
|
||||
var timeout_count = 0
|
||||
var check_times = 10
|
||||
|
||||
while (true) {
|
||||
++timeout_count
|
||||
if (!is_proc_running(pid)) {
|
||||
return false
|
||||
}
|
||||
if (timeout_count > check_times) {
|
||||
return true
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, check_time / check_times))
|
||||
}
|
||||
}
|
||||
|
||||
const run_webrtc = async (webrtc_port, app_port) => {
|
||||
if (!fs.existsSync(webrtc_server_path)) {
|
||||
return null
|
||||
}
|
||||
|
||||
var webrtc_proc
|
||||
try {
|
||||
webrtc_proc = fork(webrtc_server_path, [webrtc_port.toString(), app_port.toString()], {
|
||||
detached: true
|
||||
})
|
||||
} catch (err) {
|
||||
return null
|
||||
}
|
||||
|
||||
//var proc_status = await is_proc_running_async(webrtc_proc.pid, 500)
|
||||
|
||||
return (webrtc_proc) ? webrtc_proc.pid : null
|
||||
}
|
||||
|
||||
const run_app = async (app_path, app_port) => {
|
||||
var app_proc
|
||||
try {
|
||||
app_proc = spawn(app_path, [].concat(app_args_static,
|
||||
[app_port_arg + app_port.toString()]), {
|
||||
detached: true
|
||||
})
|
||||
} catch (err) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (app_proc) ? app_proc.pid : null
|
||||
|
||||
}
|
||||
|
||||
const kill_proc = (pid) => {
|
||||
if (process.platform === 'win32') {
|
||||
spawn('taskkill', ['/pid', pid, '/f', '/t'])
|
||||
}
|
||||
else {
|
||||
process.kill(pid)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
run_webrtc,
|
||||
run_app,
|
||||
is_proc_running,
|
||||
is_proc_running_async,
|
||||
kill_proc
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
const run_process = require('../modules/run_process')
|
||||
const database = require('../database/database')
|
||||
const {is_proc_running, kill_proc} = require('./run_process')
|
||||
const coordinator = require('./coordinator')
|
||||
|
||||
const observer_timeout = 100
|
||||
|
||||
const start_observer = () => {
|
||||
check()
|
||||
setTimeout(() => start_observer(), observer_timeout)
|
||||
}
|
||||
|
||||
// check sessions in parallel
|
||||
const check_sessions = async (sessions) => {
|
||||
|
||||
await Promise.all(sessions.map(async (session) => {
|
||||
var webrtc_running = is_proc_running(session.webrtc_pid)
|
||||
var app_running = is_proc_running(session.app_pid)
|
||||
|
||||
if (webrtc_running && app_running) {
|
||||
return
|
||||
}
|
||||
|
||||
// if something running kill process and skip remove from database
|
||||
if (!webrtc_running && !app_running) {
|
||||
var close_session_result = await coordinator.close_session(session.session_id)
|
||||
if (close_session_result) {
|
||||
database.remove_running_session(session.session_id)
|
||||
}
|
||||
} else {
|
||||
kill_proc(session.webrtc_pid)
|
||||
kill_proc(session.app_pid)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
const check = async () => {
|
||||
var sessions = await database.get_running_sessions()
|
||||
|
||||
if (!sessions) {
|
||||
return
|
||||
}
|
||||
|
||||
check_sessions(sessions)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
start_observer
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
const titles = require('../../titles.json')
|
||||
const fs = require('fs')
|
||||
|
||||
const get_app_path = (title) => {
|
||||
var path
|
||||
titles.forEach((current_title) => {
|
||||
if (current_title.title == title) {
|
||||
if (fs.existsSync(current_title.path)) {
|
||||
path = current_title.path
|
||||
} else {
|
||||
console.log(`file not exists ${current_title.path}`)
|
||||
}
|
||||
}
|
||||
})
|
||||
return (path) ? path : null
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
get_app_path
|
||||
}
|
||||
Reference in New Issue
Block a user