UNPKG

domotz-remote-pawn

Version:

Domotz Agent

167 lines (150 loc) 6.32 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 q = require('q'); module.exports.factory = function ( event, bindingDiscoverer, interfacesBinding, engineReportingStrategy, discoveryRetry, host, log, diagnostic, telemetry, utils, settingsManager, resourceLocator ) { 'use strict'; var performing = false; var iteration = 0; var initialTime = 0; var telemetry_chunk_size = settingsManager.getSetting('configuration.settings.telemetry.discovery.report_chunk_size', 10); var myConsole = log.decorateLogs(); function checkStall() { var missedDiscoveryCounter = diagnostic.getMissedDiscoveryCounter(); var skipped_discovery_threshold = settingsManager.getSetting('configuration.settings.discovery.skipped_threshold', 18); if (missedDiscoveryCounter >= skipped_discovery_threshold) { myConsole.error('(%d): Discovery stopped for %d cycles, restart the agent', iteration, missedDiscoveryCounter); setTimeout(utils.proc.gracefulShutdown, 1000); } } var runningIteration = null; function performDiscovery() { diagnostic.incDiscoveryIterationCounter(); if (performing) { diagnostic.incMissedDiscoveryCounter(); myConsole.warn( 'Avoiding double run of IP network devices discovery skipped %d cycles; running iteration=%s', diagnostic.getMissedDiscoveryCounter(), runningIteration ); checkStall(); return; } diagnostic.resetMissedDiscoveryCounter(); iteration++; var iterConsole = log.decorateLogs('iter.' + String(iteration), myConsole); performing = true; runningIteration = iteration; iterConsole.info('START OF IP network devices discovery'); function finished(step) { return function (param) { initialTime = telemetry.updateTelemetry('discovery', step, initialTime); iterConsole.verbose('%s finished', step); return param; }; } function discoveryRetryOnStaleDevices() { var deferred = q.defer(); discoveryRetry.retryOnStaleBindingsForAllInterfaces(function () { deferred.resolve(); }); return deferred.promise; } function checkEmergencyInterfaceEnabled() { var emergencyNetworkRestore = resourceLocator.emergencyNetworkRestore; var deferred = q.defer(); if (emergencyNetworkRestore.isEmergencyInterfaceEnabled()) { myConsole.info('Emergency interface is enable - skip Discovery'); deferred.reject({ message: 'Emergency interface is enable - skip Discovery', stack: null }); } else { deferred.resolve(); } return deferred.promise; } initialTime = new Date().getTime(); return interfacesBinding .assureInitialized() .then(checkEmergencyInterfaceEnabled) .then(finished('checkEmergencyInterfaceEnabled')) .then(interfacesBinding.staleAll) .then(setIteration) .then(host.resolveExternalHosts) .then(bindingDiscoverer.assureInterfaces) .then(bindingDiscoverer.discoverAll) .then(finished('bindingDiscoverer.discoverAll')) .then(interfacesBinding.setFreshDiscoveredBindings) .then(finished('interfacesBinding.setFreshDiscoveredBinding')) .then(discoveryRetryOnStaleDevices) .then(finished('discoveryRetry.retryOnStaleBindings')) .then(engineReportingStrategy.reportDiscovery) .then(finished('engineReportingStrategy.reportDiscovery')) .then(interfacesBinding.purgeStale) .then(finished('interfacesBinding.purgeStale')) .then(interfacesBinding.saveLastSnapshot) .then(finished('interfacesBinding.saveLastSnapshot')) .then(event.endFastDeviceDiscovery) .then(finished('event.endFastDeviceDiscovery')) .catch(errorHandler) .finally(function () { iterConsole.info('END OF IP network devices discovery '); performing = false; diagnostic.incActualDiscoveryCounter(); telemetry.incTelemetryCounter('discovery'); if(telemetry.getTelemetryCounter('discovery') >= telemetry_chunk_size) { telemetry.reportTelemetry('discovery'); } }); } function setIteration() { host.setIteration(iteration); bindingDiscoverer.setIteration(iteration); discoveryRetry.setIteration(iteration); engineReportingStrategy.setIteration(iteration); } function errorHandler(err) { myConsole.error('Iteration %s, Discovery error: %s', iteration, err.message); if (err.code && err.code === 'DISCOVERY_EMPTY') { myConsole.error("All discovery commands failed"); return; } myConsole.error(err.stack); } return { performDiscovery: performDiscovery, }; };