diff --git a/CHANGELOG.md b/CHANGELOG.md index 17a3613c..850bd0fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ _This release is scheduled to be released on 2021-04-01._ - Fix socket.io backward compatibility with socket v2 clients - 3rd party module language loading if language is English - Fix e2e tests after spectron update +- Fix updatenotification creating zombie processes by setting a timeout for the git process - Fix weather module openweathermap not loading if lat and lon set without onecall. ## [2.14.0] - 2021-01-01 diff --git a/modules/default/updatenotification/node_helper.js b/modules/default/updatenotification/node_helper.js index a8b75c3e..e2e5617c 100644 --- a/modules/default/updatenotification/node_helper.js +++ b/modules/default/updatenotification/node_helper.js @@ -14,32 +14,32 @@ module.exports = NodeHelper.create({ start: function () {}, - configureModules: function (modules) { + configureModules: async function (modules) { // Push MagicMirror itself , biggest chance it'll show up last in UI and isn't overwritten // others will be added in front // this method returns promises so we can't wait for every one to resolve before continuing - simpleGits.push({ module: "default", git: SimpleGit(path.normalize(__dirname + "/../../../")) }); + simpleGits.push({ module: "default", git: this.createGit(path.normalize(__dirname + "/../../../")) }); - var promises = []; - - for (var moduleName in modules) { + for (let moduleName in modules) { if (!this.ignoreUpdateChecking(moduleName)) { // Default modules are included in the main MagicMirror repo - var moduleFolder = path.normalize(__dirname + "/../../" + moduleName); + let moduleFolder = path.normalize(__dirname + "/../../" + moduleName); try { Log.info("Checking git for module: " + moduleName); - let stat = fs.statSync(path.join(moduleFolder, ".git")); - promises.push(this.resolveRemote(moduleName, moduleFolder)); + // Throws error if file doesn't exist + fs.statSync(path.join(moduleFolder, ".git")); + // Fetch the git or throw error if no remotes + let git = await this.resolveRemote(moduleFolder); + // Folder has .git and has at least one git remote, watch this folder + simpleGits.unshift({ module: moduleName, git: git }); } catch (err) { - // Error when directory .git doesn't exist + // Error when directory .git doesn't exist or doesn't have any remotes // This module is not managed with git, skip continue; } } } - - return Promise.all(promises); }, socketNotificationReceived: function (notification, payload) { @@ -54,36 +54,36 @@ module.exports = NodeHelper.create({ } }, - resolveRemote: function (moduleName, moduleFolder) { - return new Promise((resolve, reject) => { - var git = SimpleGit(moduleFolder); - git.getRemotes(true, (err, remotes) => { - if (remotes.length < 1 || remotes[0].name.length < 1) { - // No valid remote for folder, skip - return resolve(); - } - // Folder has .git and has at least one git remote, watch this folder - simpleGits.unshift({ module: moduleName, git: git }); - resolve(); - }); - }); + resolveRemote: async function (moduleFolder) { + let git = this.createGit(moduleFolder); + let remotes = await git.getRemotes(true); + + if (remotes.length < 1 || remotes[0].name.length < 1) { + throw new Error("No valid remote for folder " + moduleFolder); + } + + return git; }, - performFetch: function () { - var self = this; - simpleGits.forEach((sg) => { - sg.git.fetch(["--dry-run"]).status((err, data) => { - data.module = sg.module; - if (!err) { - sg.git.log({ "-1": null }, (err, data2) => { - if (!err && data2.latest && "hash" in data2.latest) { - data.hash = data2.latest.hash; - self.sendSocketNotification("STATUS", data); - } + performFetch: async function () { + for (let sg of simpleGits) { + try { + let fetchData = await sg.git.fetch(["--dry-run"]).status(); + let logData = await sg.git.log({ "-1": null }); + + if (logData.latest && "hash" in logData.latest) { + this.sendSocketNotification("STATUS", { + module: sg.module, + behind: fetchData.behind, + current: fetchData.current, + hash: logData.latest.hash, + tracking: fetchData.tracking }); } - }); - }); + } catch (err) { + Log.error("Failed to fetch git data for " + sg.module + ": " + err); + } + } this.scheduleNextFetch(this.config.updateInterval); }, @@ -93,13 +93,17 @@ module.exports = NodeHelper.create({ delay = 60 * 1000; } - var self = this; + let self = this; clearTimeout(this.updateTimer); this.updateTimer = setTimeout(function () { self.performFetch(); }, delay); }, + createGit: function (folder) { + return SimpleGit({ baseDir: folder, timeout: { block: this.config.timeout } }); + }, + ignoreUpdateChecking: function (moduleName) { // Should not check for updates for default modules if (defaultModules.indexOf(moduleName) >= 0) { diff --git a/modules/default/updatenotification/updatenotification.js b/modules/default/updatenotification/updatenotification.js index 3de82f1c..c67205a7 100644 --- a/modules/default/updatenotification/updatenotification.js +++ b/modules/default/updatenotification/updatenotification.js @@ -8,7 +8,8 @@ Module.register("updatenotification", { defaults: { updateInterval: 10 * 60 * 1000, // every 10 minutes refreshInterval: 24 * 60 * 60 * 1000, // one day - ignoreModules: [] + ignoreModules: [], + timeout: 1000 }, suspended: false, diff --git a/package-lock.json b/package-lock.json index 4838431d..15382503 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5840,9 +5840,9 @@ "dev": true }, "simple-git": { - "version": "2.36.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.36.0.tgz", - "integrity": "sha512-EJNaUgGYzBnQiyEkNZgbQSg76agbEDqlgHDr8DAXqV8xWvcefydbipye7YXtHMGbbEK998dcFezS8qF0sepZ5Q==", + "version": "2.36.2", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.36.2.tgz", + "integrity": "sha512-orBEf65GfSiQMsYedbJXSiRNnIRvhbeE5rrxZuEimCpWxDZOav0KLy2IEiPi1YJCF+zaC2quiJF8A4TsxI9/tw==", "requires": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", diff --git a/package.json b/package.json index 84d4757b..0120b8c1 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "node-ical": "^0.12.8", "rrule": "^2.6.8", "rrule-alt": "^2.2.8", - "simple-git": "^2.35.2", + "simple-git": "^2.36.2", "socket.io": "^3.1.2", "valid-url": "^1.0.9" },