From 852d09fc551905352559f49294bf992b7afd48b8 Mon Sep 17 00:00:00 2001 From: vexorian Date: Sun, 22 Nov 2020 16:58:59 -0400 Subject: [PATCH 1/3] Implement graceful shutdown procedure. So far the only aspect that seems to need is is the xmltv writer, we want to make sure the xmltv is completely written before closing the app. #176 --- index.js | 9 +++++++++ package.json | 1 + src/xmltv.js | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index 79d90a3..36ea844 100644 --- a/index.js +++ b/index.js @@ -17,6 +17,7 @@ const constants = require('./src/constants') const ChannelDB = require("./src/dao/channel-db"); const FillerDB = require("./src/dao/filler-db"); const TVGuideService = require("./src/tv-guide-service"); +const onShutdown = require("node-graceful-shutdown").onShutdown; console.log( ` \\ @@ -209,3 +210,11 @@ function initDB(db, channelDB) { } } + +onShutdown("log" , [], async() => { + console.log("Received exit signal, attempting graceful shutdonw..."); +}); +onShutdown("xmltv-writer" , [], async() => { + await xmltv.shutdown(); +} ); + diff --git a/package.json b/package.json index 22d7a59..88b4c8f 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "node-ssdp": "^4.0.0", "request": "^2.88.2", "uuid": "^8.0.0", + "node-graceful-shutdown" : "1.1.0", "xml-writer": "^1.7.0" }, "bin": "dist/index.js", diff --git a/src/xmltv.js b/src/xmltv.js index d1596be..6d738b2 100644 --- a/src/xmltv.js +++ b/src/xmltv.js @@ -1,11 +1,29 @@ const XMLWriter = require('xml-writer') const fs = require('fs') -const helperFuncs = require('./helperFuncs') -const constants = require('./constants') -module.exports = { WriteXMLTV: WriteXMLTV } +module.exports = { WriteXMLTV: WriteXMLTV, shutdown: shutdown } -function WriteXMLTV(json, xmlSettings, throttle ) { +let isShutdown = false; +let isWorking = false; + +async function WriteXMLTV(json, xmlSettings, throttle ) { + if (isShutdown) { + return; + } + if (isWorking) { + console.log("Concurrent xmltv write attempt detected, skipping"); + return; + } + isWorking = true; + try { + await writePromise(json, xmlSettings, throttle); + } catch (err) { + console.error("Error writing xmltv", err); + } + isWorking = false; +} + +function writePromise(json, xmlSettings, throttle) { return new Promise((resolve, reject) => { let ws = fs.createWriteStream(xmlSettings.file) let xw = new XMLWriter(true, (str, enc) => ws.write(str, enc)) @@ -59,7 +77,9 @@ function _writeChannels(xw, channels) { async function _writePrograms(xw, channel, programs, throttle) { for (let i = 0; i < programs.length; i++) { - await throttle(); + if (! isShutdown) { + await throttle(); + } await _writeProgramme(channel, programs[i], xw); } } @@ -117,8 +137,25 @@ async function _writeProgramme(channel, program, xw) { function _createXMLTVDate(d) { return d.substring(0,19).replace(/[-T:]/g,"") + " +0000"; } -function _throttle() { +function wait(x) { return new Promise((resolve) => { - setTimeout(resolve, 0); + setTimeout(resolve, x); }); } + +async function shutdown() { + isShutdown = true; + console.log("Shutting down xmltv writer."); + if (isWorking) { + let s = "Wait for xmltv writer..."; + while (isWorking) { + console.log(s); + await wait(100); + s = "Still waiting for xmltv writer..."; + } + console.log("Write finished."); + } else { + console.log("xmltv writer had no pending jobs."); + } +} + From 1254928cd6a8ae9d5d94eca6c222ed2f4a6ec040 Mon Sep 17 00:00:00 2001 From: vexorian Date: Sun, 22 Nov 2020 19:16:51 -0400 Subject: [PATCH 2/3] Fix bug with the direct path bug fix --- src/plexTranscoder.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plexTranscoder.js b/src/plexTranscoder.js index 00663a1..11f3def 100644 --- a/src/plexTranscoder.js +++ b/src/plexTranscoder.js @@ -182,7 +182,7 @@ lang=en` try { return this.getVideoStats().videoDecision === "copy"; } catch (e) { - console.log("Error at decision:" + e); + console.log("Error at decision:", e); return false; } } @@ -199,7 +199,7 @@ lang=en` try { return this.getVideoStats().videoDecision === "copy" && this.getVideoStats().audioDecision === "copy"; } catch (e) { - console.log("Error at decision:" + e); + console.log("Error at decision:" , e); return false; } } @@ -245,7 +245,7 @@ lang=en` } }.bind(this) ) } catch (e) { - console.log("Error at decision:" + e); + console.log("Error at decision:" , e); } this.log("Current video stats:") @@ -313,7 +313,7 @@ lang=en` async getDecision(directPlay) { try { - this.getDecisionUnmanaged(directPlay); + await this.getDecisionUnmanaged(directPlay); } catch (err) { console.error(err); } From 110bd19a61d5a739cf4dbf817266d34647afc347 Mon Sep 17 00:00:00 2001 From: vexorian Date: Sun, 22 Nov 2020 19:17:41 -0400 Subject: [PATCH 3/3] Improve random number generation for picking the next filler to play. --- package.json | 1 + src/helperFuncs.js | 12 +++++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 88b4c8f..a5498d0 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "angular": "^1.7.9", "angular-router-browserify": "0.0.2", "angular-vs-repeat": "2.0.13", + "random-js" : "2.1.0", "axios": "^0.19.2", "body-parser": "^1.19.0", "diskdb": "^0.1.17", diff --git a/src/helperFuncs.js b/src/helperFuncs.js index d232f42..e1708ad 100644 --- a/src/helperFuncs.js +++ b/src/helperFuncs.js @@ -6,6 +6,9 @@ module.exports = { let channelCache = require('./channel-cache'); const SLACK = require('./constants').SLACK; +const randomJS = require("random-js"); +const Random = randomJS.Random; +const random = new Random( randomJS.MersenneTwister19937.autoSeed() ); function getCurrentProgramAndTimeElapsed(date, channel) { let channelStartTime = (new Date(channel.startTime)).getTime(); @@ -102,7 +105,7 @@ function createLineup(obj, channel, fillers, isFirst) { //it's boring and odd to tune into a channel and it's always //the start of a commercial. let more = Math.max(0, filler.duration - fillerstart - 15000 - SLACK); - fillerstart += Math.floor(more * Math.random() ); + fillerstart += random.integer(0, more); } lineup.push({ // just add the video, starting at 0, playing the entire duration type: 'commercial', @@ -152,12 +155,7 @@ function createLineup(obj, channel, fillers, isFirst) { } function weighedPick(a, total) { - if (a==total) { - return true; - } else { - let ran = Math.random(); - return ran * total < a; - } + return random.bool(a, total); } function pickRandomWithMaxDuration(channel, fillers, maxDuration) {