/// <summary>
        /// Performs the actual data aquisition.
        /// </summary>
        private void PerformDataAquisition()
        {
            IConfigurationSection hamnetDbConfig = this.configuration.GetSection(Program.RssiAquisitionServiceSectionKey);

            // detect if we're due to run and, if we are, record the start of the run
            using (var transaction = this.resultDatabaseContext.Database.BeginTransaction())
            {
                var status = resultDatabaseContext.Status;
                var nowItIs = DateTime.UtcNow;
                var sinceLastScan = nowItIs - status.LastRssiQueryStart;
                if ((sinceLastScan < this.refreshInterval - Hysteresis) && (status.LastRssiQueryStart <= status.LastRssiQueryEnd))
                {
                    this.logger.LogInformation($"SKIPPING: RSSI aquisition not yet due: Last aquisition started {status.LastRssiQueryStart} ({sinceLastScan} ago, hysteresis {Hysteresis}), configured interval {this.refreshInterval}");
                    return;
                }

                // we restart the timer so that in case we've been blocked by Mutexes etc. the interval really starts from scratch
                this.timer.Change(this.refreshInterval, this.refreshInterval);

                this.logger.LogInformation($"STARTING: Retrieving RSSI monitoring data as configured in HamnetDB - last run: Started {status.LastRssiQueryStart} ({sinceLastScan} ago)");

                status.LastRssiQueryStart = DateTime.UtcNow;

                resultDatabaseContext.SaveChanges();
                transaction.Commit();
            }

            Program.RequestStatistics.RssiPollings++;

            Dictionary<IHamnetDbSubnet, IHamnetDbHosts> pairsSlicedAccordingToConfiguration = this.hamnetDbPoller.FetchSubnetsWithHostsFromHamnetDb();

            this.logger.LogDebug($"SNMP querying {pairsSlicedAccordingToConfiguration.Count} entries");

            this.SendPrepareToDataHandlers();

            NetworkExcludeFile excludes = new NetworkExcludeFile(hamnetDbConfig);
            var excludeNets = excludes?.ParsedNetworks?.ToList();

            this.logger.LogDebug($"Launching {this.maxParallelQueries} parallel RSSI aquisition threads");

            Parallel.ForEach(pairsSlicedAccordingToConfiguration, new ParallelOptions { MaxDegreeOfParallelism = this.maxParallelQueries },
            pair =>
            {
                if ((excludeNets != null) && (excludeNets.Any(exclude => exclude.Equals(pair.Key.Subnet) || exclude.Contains(pair.Key.Subnet))))
                {
                    this.logger.LogInformation($"Skipping subnet {pair.Key.Subnet} due to exclude list");
                    return;
                }

                try
                {
                    this.QueryLinkOfSingleSubnet(pair);
                }
                catch (Exception ex)
                {
                    this.logger.LogError($"Exception caught and ignored in RSSI arallel data aquisition thread: {ex.ToString()}");
                }
            });

            this.SendFinishedToDataHandlers();

            // record the regular end of the run
            using (var transaction = this.resultDatabaseContext.Database.BeginTransaction())
            {
                var status = resultDatabaseContext.Status;

                status.LastRssiQueryEnd = DateTime.UtcNow;

                this.logger.LogInformation($"COMPLETED: Retrieving RSSI monitoring data as configured in HamnetDB at {status.LastRssiQueryEnd}, duration {status.LastRssiQueryEnd - status.LastRssiQueryStart}");

                resultDatabaseContext.SaveChanges();
                transaction.Commit();
            }
        }
        /// <summary>
        /// Performs the actual data aquisition.
        /// </summary>
        private void PerformDataAquisition()
        {
            IConfigurationSection hamnetDbConfig = this.configuration.GetSection(Program.BgpAquisitionServiceSectionKey);

            // detect if we're due to run and, if we are, record the start of the run
            using (var transaction = this.resultDatabaseContext.Database.BeginTransaction())
            {
                var status        = resultDatabaseContext.Status;
                var nowItIs       = DateTime.UtcNow;
                var sinceLastScan = nowItIs - status.LastBgpQueryStart;
                if ((sinceLastScan < this.refreshInterval - Hysteresis) && (status.LastBgpQueryStart <= status.LastBgpQueryEnd))
                {
                    this.logger.LogInformation($"SKIPPING: BGP aquisition not yet due: Last aquisition started {status.LastBgpQueryStart} ({sinceLastScan} ago, hysteresis {Hysteresis}), configured interval {this.refreshInterval}");
                    return;
                }

                // we restart the timer so that in case we've been blocked by Mutexes etc. the interval really starts from scratch
                this.timer.Change(this.refreshInterval, this.refreshInterval);

                this.logger.LogInformation($"STARTING: Retrieving BGP monitoring data as configured in HamnetDB - last run: Started {status.LastBgpQueryStart} ({sinceLastScan} ago)");

                status.LastBgpQueryStart = DateTime.UtcNow;

                resultDatabaseContext.SaveChanges();
                transaction.Commit();
            }

            Program.RequestStatistics.BgpPollings++;

            List <IHamnetDbHost> hostsSlicedAccordingToConfiguration = this.hamnetDbPoller.FetchBgpRoutersFromHamnetDb();

            this.logger.LogDebug($"API querying {hostsSlicedAccordingToConfiguration.Count} entries");

            this.SendPrepareToDataHandlers();

            NetworkExcludeFile excludes = new NetworkExcludeFile(hamnetDbConfig);
            var excludeNets             = excludes?.ParsedNetworks?.ToList();

            this.logger.LogDebug($"Launching {this.maxParallelQueries} parallel BGP aquisition threads");

            var filteredHosts = hostsSlicedAccordingToConfiguration
                                           // the following where is just a hack until HamnetDB has a flag clearly identifying routers that shall be queried for BGP
                                           // and have opened their API port to "monitoring" user.
                                .Where(hsatc => this.filterRegexList.Any(fr => fr.IsMatch(hsatc.Callsign)))
                                .ToList(); // for debugger

            Parallel.ForEach(
                filteredHosts,
                new ParallelOptions {
                MaxDegreeOfParallelism = this.maxParallelQueries
            },
                host =>
            {
                if ((excludeNets != null) && (excludeNets.Any(exclude => exclude.Contains(host.Address))))
                {
                    this.logger.LogInformation($"Skipping subnet {host.Address} due to exclude list");
                    return;
                }

                try
                {
                    this.QueryPeersForSingleHost(host);
                }
                catch (Exception ex)
                {
                    this.logger.LogError($"Exception caught and ignored in BGP parallel data aquisition thread: {ex.ToString()}");
                }
            });

            this.SendFinishedToDataHandlers();

            // record the regular end of the run
            using (var transaction = this.resultDatabaseContext.Database.BeginTransaction())
            {
                var status = resultDatabaseContext.Status;

                status.LastBgpQueryEnd = DateTime.UtcNow;

                this.logger.LogInformation($"COMPLETED: Retrieving BGP monitoring data as configured in HamnetDB at {status.LastBgpQueryEnd}, duration {status.LastBgpQueryEnd - status.LastBgpQueryStart}");

                resultDatabaseContext.SaveChanges();
                transaction.Commit();
            }
        }