private async Task <Server[]> GetServersAsync(CancellationToken cancellationToken)
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            return(await Task.Run(async() =>
            {
                var servers = new ConcurrentBag <Server>();

                try
                {
                    var populationTasks = new List <Task>();

                    var registryInstances = LocalServers.LookupRegistryInstances();

                    foreach (var(hive, instances) in registryInstances)
                    {
                        foreach (var instance in instances)
                        {
                            populationTasks.Add(PopulateLocalServerAsync(servers, hive, instance, cancellationToken));
                        }
                    }

                    await Task.WhenAll(populationTasks).ConfigureAwait(false);
                }
                catch (TaskCanceledException)
                {
                    _logger?.LogDebug($"[{LoggingExtensions.CurrentFunction()}] Cancelled");
                }

                return servers.Distinct().ToArray();
            }, cancellationToken).ConfigureAwait(false));
        }
        private Task PopulateLocalServerAsync(ConcurrentBag <Server> servers, RegistryKey hive, string instance, CancellationToken cancellationToken)
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            return(Task.Run(() =>
            {
                try
                {
                    var localServer = new LocalServer();

                    localServer.Populate(hive, instance);

                    var server = localServer.ToServer();

                    servers.Add(server);

                    OnLocalServerDiscovered?.Invoke(this, localServer);
                    OnServerDiscovered?.Invoke(this, server);
                }
                catch (TaskCanceledException)
                {
                    _logger?.LogDebug($"[{LoggingExtensions.CurrentFunction()}] Cancelled");
                }
            }, cancellationToken));
        }
        public async Task <Server[]> DiscoverAsync(CancellationToken cancellationToken)
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            Server[] servers = null;

            discoveryCancellationTokenSource?.Cancel();
            discoveryCancellationTokenSource = new();

            _logger?.LogInformation("Network discovery started");

            discoveryCancellationTokenSource.CancelAfter(Configuration.Timeout);

            using (var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(discoveryCancellationTokenSource.Token, cancellationToken))
            {
                var linkedCancellationToken = linkedCancellationTokenSource.Token;

                _ = BroadcastAsync(linkedCancellationToken).ConfigureAwait(false);

                servers = await ListenAsync(linkedCancellationToken).ConfigureAwait(false);
            }

            _logger?.LogInformation("Network discovery ended");

            discoveryCancellationTokenSource.Cancel();

            return(servers);
        }
        private async Task <Server[]> ListenAsync(CancellationToken cancellationToken)
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            var servers = new ConcurrentBag <Server>();

            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    var result = await client.ReceiveAsync().WithCancellation(cancellationToken).ConfigureAwait(false);

                    _ = ProcessResponse(servers, result.Buffer, result.RemoteEndPoint, cancellationToken).ConfigureAwait(false);
                }
                catch (TaskCanceledException)
                {
                    _logger?.LogDebug($"[{LoggingExtensions.CurrentFunction()}] Cancelled");
                }
                catch (Exception ex)
                {
                    _logger?.LogError(ex, "Error occured while receiving responses");

                    if (Configuration.ReceiveExceptionAction is Architecture.ExceptionActions.LogAndThrow)
                    {
                        throw;
                    }
                }
            }

            return(servers.Distinct().ToArray());
        }
        public void Stop()
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            _logger?.LogInformation("Local discovery cancelled");

            discoveryCancellationTokenSource?.Cancel();
        }
Exemple #6
0
        public void Stop()
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            _logger?.LogInformation("Discovery cancelled");

            networkDiscovery?.Stop();
            localDiscovery?.Stop();
        }
Exemple #7
0
        public async Task <Server[]> DiscoverLocalServers(CancellationToken cancellationToken)
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            localDiscovery = new(_logger);
            localDiscovery.OnLocalServerDiscovered += OnLocalServerDiscovered;
            localDiscovery.OnServerDiscovered      += OnServerDiscovered;

            return(await localDiscovery.DiscoverAsync(cancellationToken).ConfigureAwait(false));;
        }
Exemple #8
0
        public async Task <Server[]> DiscoverNetworkServers(CancellationToken cancellationToken, NetworkConfiguration configuration = null)
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            networkDiscovery = new(_logger, configuration);
            networkDiscovery.OnNetworkServerDiscovered += OnNetworkServerDiscovered;
            networkDiscovery.OnServerDiscovered        += OnServerDiscovered;

            return(await networkDiscovery.DiscoverAsync(cancellationToken).ConfigureAwait(false));;
        }
Exemple #9
0
        public async Task <Server[]> DiscoverServers(CancellationToken cancellationToken, NetworkConfiguration configuration = null)
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            _logger?.LogInformation("Discovery started");

            var networkTask = DiscoverNetworkServers(cancellationToken, configuration);
            var localTask   = DiscoverLocalServers(cancellationToken);

            var results = await Task.WhenAll <Server[]>(networkTask, localTask);

            _logger?.LogInformation("Discovery ended");

            return(results.Where(s => s != null).SelectMany(s => s).Distinct().ToArray());
        }
        public NetworkDiscovery(ILogger logger = default, NetworkConfiguration configuration = default)
        {
            _logger = logger;

            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            if (configuration == null)
            {
                configuration = new();
            }

            Configuration = configuration;

            client = new()
            {
                EnableBroadcast = true
            };
        }
        private async Task BroadcastAsync(CancellationToken cancellationToken)
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    await client.SendAsync(Architecture.CLNT_BCAST_EX, Architecture.CLNT_BCAST_EX.Length, new IPEndPoint(IPAddress.Broadcast, Configuration.Port)).WithCancellation(cancellationToken).ConfigureAwait(false);
                }
                catch (TaskCanceledException)
                {
                    _logger?.LogDebug($"[{LoggingExtensions.CurrentFunction()}] Cancelled");
                }
                catch (Exception ex)
                {
                    _logger?.LogError(ex, "Error occured while sending discovery requests");

                    if (Configuration.SendExceptionAction is Architecture.ExceptionActions.LogAndThrow)
                    {
                        throw;
                    }
                }

                if (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        await Task.Delay(Configuration.ResendDelay, cancellationToken).ConfigureAwait(false);
                    }
                    catch (TaskCanceledException)
                    {
                        _logger?.LogDebug($"[{LoggingExtensions.CurrentFunction()}] Cancelled");
                    }
                    catch { }
                }
            }
        }
        public async Task <Server[]> DiscoverAsync(CancellationToken cancellationToken)
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            Server[] servers = default;

            discoveryCancellationTokenSource?.Cancel();
            discoveryCancellationTokenSource = new();

            _logger?.LogInformation("Local discovery started");

            using (var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(discoveryCancellationTokenSource.Token, cancellationToken))
            {
                var linkedCancellationToken = linkedCancellationTokenSource.Token;

                servers = await GetServersAsync(linkedCancellationToken).ConfigureAwait(false);
            }

            _logger?.LogInformation("Local discovery ended");

            discoveryCancellationTokenSource.Cancel();

            return(servers);
        }
        private Task ProcessResponse(ConcurrentBag <Server> servers, byte[] buffer, IPEndPoint responder, CancellationToken cancellationToken)
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            return(Task.Run(() =>
            {
                try
                {
                    var response = SQL.Network.NetworkServerResponse.Parse(buffer, responder);
                    if (response == null)
                    {
                        return;
                    }

                    var networkServers = SQL.Network.NetworkServers.Parse(response);
                    if (networkServers.Count == 0)
                    {
                        return;
                    }

                    foreach (var networkServer in networkServers)
                    {
                        var server = networkServer.ToServer();

                        servers.Add(server);

                        OnNetworkServerDiscovered?.Invoke(this, networkServer);
                        OnServerDiscovered?.Invoke(this, server);
                    }
                }
                catch (TaskCanceledException)
                {
                    _logger?.LogDebug($"[{LoggingExtensions.CurrentFunction()}] Cancelled");
                }
            }, cancellationToken));
        }
        public LocalDiscovery(ILogger logger)
        {
            _logger = logger;

            _logger?.LogDebug(LoggingExtensions.CurrentFunction());
        }