Exemplo n.º 1
0
        internal async Task <ServerNode> GetCurrentSessionNode(RequestExecutor requestExecutor)
        {
            (int Index, ServerNode Node)result;

            switch (requestExecutor.Conventions.LoadBalanceBehavior)
            {
            case LoadBalanceBehavior.UseSessionContext:
                if (_canUseLoadBalanceBehavior)
                {
                    result = await requestExecutor.GetNodeBySessionId(SessionId).ConfigureAwait(false);

                    return(result.Node);
                }
                break;
            }

            switch (requestExecutor.Conventions.ReadBalanceBehavior)
            {
            case ReadBalanceBehavior.None:
                result = await requestExecutor.GetPreferredNode().ConfigureAwait(false);

                break;

            case ReadBalanceBehavior.RoundRobin:
                result = await requestExecutor.GetNodeBySessionId(SessionId).ConfigureAwait(false);

                break;

            case ReadBalanceBehavior.FastestNode:
                result = await requestExecutor.GetFastestNode().ConfigureAwait(false);

                break;

            default:
                throw new ArgumentOutOfRangeException(requestExecutor.Conventions.ReadBalanceBehavior.ToString());
            }

            return(result.Node);
        }
Exemplo n.º 2
0
        private async Task DoWork(string nodeTag)
        {
            try
            {
                var task = nodeTag == null || _requestExecutor.Conventions.DisableTopologyUpdates
                    ? _requestExecutor.GetPreferredNode()
                    : _requestExecutor.GetRequestedNode(nodeTag);

                (_nodeIndex, _serverNode) = await task.ConfigureAwait(false);
            }
            catch (OperationCanceledException e)
            {
                NotifyAboutError(e);
                _tcs.TrySetCanceled();
                return;
            }
            catch (Exception e)
            {
                ConnectionStatusChanged?.Invoke(this, EventArgs.Empty);
                NotifyAboutError(e);
                _tcs.TrySetException(e);
                return;
            }

            var wasConnected = false;

            while (_cts.IsCancellationRequested == false)
            {
                try
                {
                    if (Connected == false)
                    {
                        _url = new Uri($"{_serverNode.Url}/databases/{_database}/changes"
                                       .ToLower()
                                       .ToWebSocketPath(), UriKind.Absolute);

                        await _client.ConnectAsync(_url, _cts.Token).ConfigureAwait(false);

                        wasConnected = true;
                        Interlocked.Exchange(ref _immediateConnection, 1);

                        foreach (var counter in _counters)
                        {
                            counter.Value.Set(counter.Value.OnConnect());
                        }

                        ConnectionStatusChanged?.Invoke(this, EventArgs.Empty);
                    }

                    await ProcessChanges().ConfigureAwait(false);
                }
                catch (OperationCanceledException) when(_cts.Token.IsCancellationRequested)
                {
                    // disposing
                    return;
                }
                catch (ChangeProcessingException)
                {
                    continue;
                }
                catch (Exception e)
                {
                    //We don't report this error since we can automatically recover from it and we can't
                    // recover from the OnError accessing the faulty WebSocket.
                    try
                    {
                        if (wasConnected)
                        {
                            ConnectionStatusChanged?.Invoke(this, EventArgs.Empty);
                        }

                        wasConnected = false;
                        try
                        {
                            _serverNode = await _requestExecutor.HandleServerNotResponsive(_url.AbsoluteUri, _serverNode, _nodeIndex, e).ConfigureAwait(false);
                        }
                        catch (DatabaseDoesNotExistException databaseDoesNotExistException)
                        {
                            e = databaseDoesNotExistException;
                            throw;
                        }
                        catch (Exception)
                        {
                            //We don't want to stop observe for changes if server down. we will wait for one to be up
                        }

                        if (ReconnectClient() == false)
                        {
                            return;
                        }
                    }
                    catch
                    {
                        // we couldn't reconnect
                        NotifyAboutError(e);
                        _tcs.TrySetException(e);
                        throw;
                    }
                }
                finally
                {
                    foreach (var confirmation in _confirmations)
                    {
                        confirmation.Value.TrySetCanceled();
                    }
                    _confirmations.Clear();
                }

                try
                {
                    await TimeoutManager.WaitFor(TimeSpan.FromSeconds(1), _cts.Token).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    return;
                }
            }
        }
Exemplo n.º 3
0
        private async Task DoWork()
        {
            try
            {
                await _requestExecutor.GetPreferredNode().ConfigureAwait(false);
            }
            catch (OperationCanceledException e)
            {
                NotifyAboutError(e);
                return;
            }
            catch (ChangeProcessingException e)
            {
                NotifyAboutError(e);
                return;
            }
            catch (Exception e)
            {
                ConnectionStatusChanged?.Invoke(this, EventArgs.Empty);
                NotifyAboutError(e);
                return;
            }

            var url = new Uri($"{_requestExecutor.Url}/databases/{_database}/changes"
                              .ToLower()
                              .ToWebSocketPath(), UriKind.Absolute);

            while (_cts.IsCancellationRequested == false)
            {
                try
                {
                    if (Connected == false)
                    {
                        await _client.ConnectAsync(url, _cts.Token).ConfigureAwait(false);

                        Interlocked.Exchange(ref _immediateConnection, 1);

                        foreach (var counter in _counters)
                        {
                            counter.Value.Set(counter.Value.OnConnect());
                        }

                        ConnectionStatusChanged?.Invoke(this, EventArgs.Empty);
                    }

                    await ProcessChanges().ConfigureAwait(false);
                }
                catch (OperationCanceledException e)
                {
                    NotifyAboutError(e);
                    return;
                }
                catch (ChangeProcessingException)
                {
                    continue;
                }
                catch (Exception e)
                {
                    //We don't report this error since we can automatically recover from it and we can't
                    // recover from the OnError accessing the faulty WebSocket.
                    try
                    {
                        ConnectionStatusChanged?.Invoke(this, EventArgs.Empty);

                        if (ReconnectClient() == false)
                        {
                            return;
                        }
                    }
                    catch
                    {
                        // we couldn't reconnect
                        NotifyAboutError(e);
                        throw;
                    }
                }
                finally
                {
                    foreach (var confirmation in _confirmations)
                    {
                        confirmation.Value.TrySetCanceled();
                    }
                    _confirmations.Clear();
                }

                try
                {
                    await TimeoutManager.WaitFor(TimeSpan.FromSeconds(1), _cts.Token).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    return;
                }
            }
        }
Exemplo n.º 4
0
        private async Task DoWork()
        {
            try
            {
                await _requestExecutor.GetPreferredNode().ConfigureAwait(false);
            }
            catch (OperationCanceledException e)
            {
                NotifyAboutError(e);
                return;
            }
            catch (ChangeProcessingException e)
            {
                NotifyAboutError(e);
                return;
            }
            catch (Exception e)
            {
                ConnectionStatusChanged?.Invoke(this, EventArgs.Empty);
                NotifyAboutError(e);
                return;
            }

            var url = new Uri($"{_requestExecutor.Url}/databases/{_database}/changes"
                              .ToLower()
                              .ToWebSocketPath(), UriKind.Absolute);

            while (_cts.IsCancellationRequested == false)
            {
                try
                {
                    if (Connected == false)
                    {
                        await _client.ConnectAsync(url, _cts.Token).ConfigureAwait(false);

                        ConnectionStatusChanged?.Invoke(this, EventArgs.Empty);
                    }

                    await ProcessChanges().ConfigureAwait(false);
                }
                catch (OperationCanceledException e)
                {
                    NotifyAboutError(e);
                    return;
                }
                catch (ChangeProcessingException e)
                {
                    NotifyAboutError(e);
                    continue;
                }
                catch (Exception e)
                {
                    if (_cts.IsCancellationRequested)
                    {
                        return;
                    }

                    using (_client)
                        _client = CreateClientWebSocket(_requestExecutor);

                    ConnectionStatusChanged?.Invoke(this, EventArgs.Empty);

                    NotifyAboutError(e);
                }
                finally
                {
                    foreach (var confirmation in _confirmations)
                    {
                        confirmation.Value.TrySetCanceled();
                    }
                    _confirmations.Clear();
                }

                try
                {
                    await TimeoutManager.WaitFor(TimeSpan.FromSeconds(1), _cts.Token).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    return;
                }
            }
        }