UNPKG

domotz-remote-pawn

Version:

Domotz Agent

186 lines (163 loc) 6.67 kB
/** This file is part of Domotz Agent. * Copyright (C) 2016 Domotz Ltd * * Domotz Agent is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Domotz Agent is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>. **/ /** * * Created by Iacopo Papalini <ipapalini@domotz.com> on 10/09/15. */ const MODULE_NAME = 'SPEED_TEST'; const KILL_CHILD_TIMEOUT = 300000; var lockSeed = Math.random(); var speedTest = function (message, resourceLocator) { const md5 = resourceLocator.utils.random.md5; const time = resourceLocator.utils.time; const mutex = resourceLocator.utils.mutex; const fork = resourceLocator.utils.proc.fork; const join = resourceLocator.path.join; const engineClient = resourceLocator.engineRequest; const ndtServers = resourceLocator.networkTools.ndtServers; const speedTest = resourceLocator.networkTools.speedTest; const ooklaServers = resourceLocator.networkTools.ooklaServers; const configuration = resourceLocator.configuration; const cid = message.correlationId || 'From API'; const serverId = message.payload.server_id; const nonInteractive = message.non_interactive; var modulePath = join(__dirname, '..', '..', 'network_tools', 'ooklaSpeedTest.js'); var call = internal() ? callInternalTest : callExternalTest; var lockId = md5(lockSeed.toString()); function lock() { return mutex.lock(MODULE_NAME, lockId); } function unlock() { mutex.unlock(MODULE_NAME, lockId); } var results = { stats: { start: new Date(), end: null, elapsed_milliseconds: null }, speedTest: {} }; function copyResults(ndtInfo) { results.stats.end = new Date(); results.stats.elapsed_milliseconds = time.getDiff(results.stats); results.speedTest = speedTest.ndtInfoIntoDTO(ndtInfo); return speedTest.filterItems(ndtInfo); } function processData(data, cb) { if (data.blacklist && data.blacklist.length > 0) { console.warn("%s - (%s): Blacklist servers => %s", MODULE_NAME, cid, JSON.stringify(data.blacklist)); ooklaServers.blacklistServers(data.blacklist); } if (!data.error) { if (data.server) { /* store it as preferred server to perform the interactive speed test */ ooklaServers.setServerAsPreferred(data.server); } console.debug("%s - (%s): Speed test success", MODULE_NAME, cid); var items = copyResults(data.result); cb(results); engineClient.sendWithPromise('/network/speed-test', 'POST', items); } else { console.debug("%s - (%s): Speed test failure => %s", MODULE_NAME, cid, data.error); cb(data.error, data.error); } } function callExternalTest(msg, cb) { var child = fork(modulePath, [], {silent: false}); var killChildTimeout = setTimeout(function () { console.info("%s - (%s) killing child process by timeout", MODULE_NAME, cid); child.kill(); unlock(); }, KILL_CHILD_TIMEOUT); child.send(msg); child.on('message', function (data) { clearTimeout(killChildTimeout); processData(data, cb); child.kill(); unlock(); }); } function callInternalTest(msg, cb) { var ooklaSpeedTest = require(modulePath); ooklaSpeedTest.main(msg, function(data) { processData(data, cb); unlock(); }); } return { describe: function () { return cid + " - " + MODULE_NAME; }, execute: function (callback) { if (!lock()) { var msg = MODULE_NAME + ' - (' + cid + '): Another Speed test is currently running'; console.warn(msg); return callback(null, { status: 409, message: msg }); } if (!ooklaEnabled(configuration)) {// NDT test ndtServers.findById(serverId) .then(speedTest.performSpeedTest) .then(copyResults) .then(function (items) { callback(results); return engineClient.sendWithPromise('/network/speed-test', 'POST', items); }) .catch(function (err) { callback(null, err); }).finally(function () { unlock(); }); } else if (nonInteractive) { console.info("%s (%s): Not interactive mode, selecting N closest servers", MODULE_NAME, cid); ooklaServers.getNearestServers() .then(function (serverList) { console.info("%s - (%s): Nearest Server: %s", MODULE_NAME, cid, JSON.stringify(serverList)); var msg = { bestServer: null, serverList: serverList }; call(msg, callback); }); } else { console.info("%s - (%s): interactive mode, searching for %s", MODULE_NAME, cid, serverId); ooklaServers.findById(serverId) .then(function (server) { console.info("%s - (%s): found server: %s", MODULE_NAME, cid, JSON.stringify(server)); var msg = {bestServer: server, serverList: null}; call(msg, callback); }); } } }; }; module.exports.command = speedTest; function internal() { var env = process.env; return (env.DPLATFORM === 'openwrt' || env.DARCHITECTURE === 'x64'); } function ooklaEnabled(configuration) { return (typeof configuration.enable_ookla === 'undefined') ? true : configuration.enable_ookla; }