UNPKG

domotz-remote-pawn

Version:

Domotz Agent

139 lines (120 loc) 5.12 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/>. * * * This module has the responsibility to coordinate both the delta and the full IP devices * discovery. * It calls the InterfacesBindingStorage to update the interfaces binding discovered by the * BindingDiscoverer. Then it sends the results to the engine. * * Created by Iacopo Papalini <iacopo@domotz.com> on 18/05/16. */ const MODULE_NAME = 'IP_DISCOVERY'; const RETRY_TRIALS = 5; function getRetryInterval(configuration) { var discovery = configuration.discovery; var retryInterval = (discovery && discovery.retry_interval) ? discovery.retry_interval : 1000; return retryInterval; } module.exports.factory = function (q, configuration, event, bindingDiscoverer, interfacesBindingStorage, engineReportingStrategy) { "use strict"; var retryInterval = getRetryInterval(configuration); var performing = false; var iteration = 0; function performDiscovery() { if (performing) { console.warn("%s - (%d): Avoiding double run of IP network devices discovery", MODULE_NAME, iteration); return; } iteration++; performing = true; console.verbose("%s - (%d): Performing IP network devices discovery", MODULE_NAME, iteration); return interfacesBindingStorage.assureInitialized(). then(interfacesBindingStorage.staleAll). then(setIteration). then(bindingDiscoverer.discoverAll). then(setFreshDiscoveredBindings). then(retryOnStaleBindings(RETRY_TRIALS)). then(engineReportingStrategy.reportDiscovery). then(interfacesBindingStorage.purgeStale). then(event.endFastDeviceDiscovery). catch(errorHandler). finally(function () { performing = false; }); } function setIteration() { bindingDiscoverer.setIteration(iteration); } function retryOnStaleBindings(count) { return function () { var deferred = q.defer(); function _retry() { var stale = interfacesBindingStorage.listStale(); if (count === 0 || stale.length === 0) { console.info("%s - (%d): : Exiting retry loop, devices still stale: %d", MODULE_NAME, iteration, stale.length); return deferred.resolve(); } count--; var ips = stale.map(function(e) {return e.ip;}); var arpPingRetryPromise = bindingDiscoverer.discover(ips, false) .then(setFreshDiscoveredBindings); var pingRetryPromise = q.delay(retryInterval) //delay 1s .then(function () { return bindingDiscoverer.discover(ips, true); }) .then(setFreshDiscoveredBindings); console.info('%s - (%d): Retry Loop: %d. IPs: %s', MODULE_NAME, iteration, RETRY_TRIALS - count, JSON.stringify(ips)); return q.all([pingRetryPromise, arpPingRetryPromise]) .then(_retry); } q.nextTick(_retry); return deferred.promise; }; } function setFreshDiscoveredBindings(bindings) { for (var interface_index in bindings) { if (bindings.hasOwnProperty(interface_index)) { var interface_info = bindings[interface_index]; for (var mac in interface_info) { if (interface_info.hasOwnProperty(mac)) { var addresses = interface_info[mac]; for (var i = 0; i < addresses.length; i++) { var entry = addresses[i]; interfacesBindingStorage.setFresh(mac, entry.ip, entry.host_name); } } } } } } function errorHandler(err) { console.error("%s - (%d): Discovery error: %s", MODULE_NAME, iteration, err.message); console.error(err.stack); } return { performDiscovery: performDiscovery }; };