示例#1
0
        private void ReconnectTo(NodeEndPoints endPoints)
        {
            IPEndPoint endPoint = _settings.UseSslConnection
                                ? endPoints.SecureTcpEndPoint ?? endPoints.TcpEndPoint
                                : endPoints.TcpEndPoint;

            if (endPoint == null)
            {
                CloseConnection("No end point is specified while trying to reconnect.");
                return;
            }

            if (_state != ConnectionState.Connected || _connection.RemoteEndPoint.Equals(endPoint))
            {
                return;
            }

            var msg = string.Format(
                "EventStoreConnection '{0}': going to reconnect to [{1}]. Current endpoint: [{2}, L{3}].",
                _esConnection.ConnectionName, endPoint, _connection.RemoteEndPoint, _connection.LocalEndPoint);

            if (_settings.VerboseLogging)
            {
                _settings.Log.Info(msg);
            }
            CloseTcpConnection(msg);

            _state           = ConnectionState.Connecting;
            _connectingPhase = ConnectingPhase.EndPointDiscovery;
            EstablishTcpConnection(endPoints);
        }
示例#2
0
        private void TcpConnectionClosed(TcpPackageConnection connection)
        {
            if (_state == ConnectionState.Init)
            {
                throw new Exception();
            }
            if (_state == ConnectionState.Closed || _connection != connection)
            {
                LogDebug(
                    "IGNORED (_state: {0}, _conn.ID: {1:B}, conn.ID: {2:B}): TCP connection to [{3}, L{4}] closed.",
                    _state, _connection == null ? Guid.Empty : _connection.ConnectionId, connection.ConnectionId,
                    connection.RemoteEndPoint, connection.LocalEndPoint);
                return;
            }
            var wasConnected = Interlocked.CompareExchange(ref _wasConnected, 0, 1) == 1;

            _state           = ConnectionState.Connecting;
            _connectingPhase = ConnectingPhase.Reconnecting;

            LogDebug("TCP connection to [{0}, L{1}, {2:B}] closed.", connection.RemoteEndPoint,
                     connection.LocalEndPoint, connection.ConnectionId);

            _subscriptions.PurgeSubscribedAndDroppedSubscriptions(_connection.ConnectionId);
            _reconnInfo = new ReconnectionInfo(_reconnInfo.ReconnectionAttempt, _stopwatch.Elapsed);

            if (wasConnected)
            {
                RaiseDisconnected(connection.RemoteEndPoint);
            }
        }
示例#3
0
        private void TcpConnectionEstablished(TcpPackageConnection connection)
        {
            if (_state != ConnectionState.Connecting || _connection != connection || connection.IsClosed)
            {
                LogDebug(
                    "IGNORED (_state {0}, _conn.Id {1:B}, conn.Id {2:B}, conn.closed {3}): TCP connection to [{4}, L{5}] established.",
                    _state, _connection == null ? Guid.Empty : _connection.ConnectionId, connection.ConnectionId,
                    connection.IsClosed, connection.RemoteEndPoint, connection.LocalEndPoint);
                return;
            }

            LogDebug("TCP connection to [{0}, L{1}, {2:B}] established.", connection.RemoteEndPoint,
                     connection.LocalEndPoint, connection.ConnectionId);
            _heartbeatInfo = new HeartbeatInfo(_packageNumber, true, _stopwatch.Elapsed);

            if (_settings.DefaultUserCredentials != null)
            {
                _connectingPhase = ConnectingPhase.Authentication;

                _authInfo = new AuthInfo(Guid.NewGuid(), _stopwatch.Elapsed);
                _connection.EnqueueSend(new TcpPackage(TcpCommand.Authenticate,
                                                       TcpFlags.Authenticated,
                                                       _authInfo.CorrelationId,
                                                       _settings.DefaultUserCredentials.Username,
                                                       _settings.DefaultUserCredentials.Password,
                                                       null));
            }
            else
            {
                GoToIdentifyState();
            }
        }
示例#4
0
        private void DiscoverEndPoint(TaskCompletionSource <object> completionTask)
        {
            LogDebug("DiscoverEndPoint");

            if (_state != ConnectionState.Connecting)
            {
                return;
            }
            if (_connectingPhase != ConnectingPhase.Reconnecting)
            {
                return;
            }

            _connectingPhase = ConnectingPhase.EndPointDiscovery;

            _endPointDiscoverer.DiscoverAsync(_connection != null ? _connection.RemoteEndPoint : null).ContinueWith(
                t => {
                if (t.IsFaulted)
                {
                    EnqueueMessage(
                        new CloseConnectionMessage("Failed to resolve TCP end point to which to connect.",
                                                   t.Exception));
                    completionTask?.SetException(
                        new CannotEstablishConnectionException("Cannot resolve target end point.", t.Exception));
                }
                else
                {
                    EnqueueMessage(new EstablishTcpConnectionMessage(t.Result));
                    completionTask?.SetResult(null);
                }
            });
        }
        private void StartConnection(TaskCompletionSource <object> task, IEndPointDiscoverer endPointDiscoverer)
        {
            Ensure.NotNull(task, "task");
            Ensure.NotNull(endPointDiscoverer, "endPointDiscoverer");

            LogDebug("StartConnection");

            switch (_state)
            {
            case ConnectionState.Init: {
                _endPointDiscoverer = endPointDiscoverer;
                _state           = ConnectionState.Connecting;
                _connectingPhase = ConnectingPhase.Reconnecting;
                DiscoverEndPoint(task);
                break;
            }

            case ConnectionState.Connecting:
            case ConnectionState.Connected: {
                task.SetException(new InvalidOperationException(
                                      string.Format("EventStoreConnection '{0}' is already active.", _esConnection.ConnectionName)));
                break;
            }

            case ConnectionState.Closed:
                task.SetException(new ObjectDisposedException(_esConnection.ConnectionName));
                break;

            default:
                task.SetException(new Exception(string.Format("Unknown state: {0}", _state)));
                break;
            }
        }
        private void GoToIdentifyState()
        {
            Ensure.NotNull(_connection, "_connection");
            _connectingPhase = ConnectingPhase.Identification;

            _identifyInfo = new IdentifyInfo(Guid.NewGuid(), _stopwatch.Elapsed);
            var dto = new ClientMessage.IdentifyClient(ClientVersion, _esConnection.ConnectionName);

            _connection.EnqueueSend(new TcpPackage(TcpCommand.IdentifyClient, _identifyInfo.CorrelationId, dto.Serialize()));
        }
        private void EstablishTcpConnection(NodeEndPoints endPoints)
        {
            var endPoint = _compatibilityMode.IsAutoCompatibilityModeEnabled() || _settings.UseSslConnection
                                ? endPoints.SecureTcpEndPoint ?? endPoints.TcpEndPoint
                                : endPoints.TcpEndPoint;

            if (endPoint == null)
            {
                CloseConnection("No end point to node specified.");
                return;
            }

            LogDebug("EstablishTcpConnection to [{0}]", endPoint);

            if (_state != ConnectionState.Connecting)
            {
                LogDebug("EstablishTcpConnection to [{0}] skipped because expected state 'Connecting', was '{1}'",
                         endPoint, _state);
                return;
            }

            if (_connectingPhase != ConnectingPhase.EndPointDiscovery)
            {
                LogDebug(
                    "EstablishTcpConnection to [{0}] skipped because expected connecting phase 'EndPointDiscovery', was '{1}'",
                    endPoint, _connectingPhase);
                return;
            }

            var useSsl = _compatibilityMode.IsAutoCompatibilityModeEnabled()
                                ? endPoints.SecureTcpEndPoint != null
                                : _settings.UseSslConnection;

            _connectingPhase = ConnectingPhase.ConnectionEstablishing;
            _connection      = new TcpPackageConnection(
                _settings.Log,
                endPoint,
                Guid.NewGuid(),
                useSsl,
                _settings.ValidateServer,
                _settings.ClientConnectionTimeout,
                (connection, package) => EnqueueMessage(new HandleTcpPackageMessage(connection, package)),
                (connection, exc) => EnqueueMessage(new TcpConnectionErrorMessage(connection, exc)),
                connection => EnqueueMessage(new TcpConnectionEstablishedMessage(connection)),
                (connection, error) => EnqueueMessage(new TcpConnectionClosedMessage(connection, error)));

            _connection.StartReceiving();
        }
        private void GoToIdentifyState()
        {
            Ensure.NotNull(_connection, "_connection");
            _connectingPhase = ConnectingPhase.Identification;

            _identifyInfo = new IdentifyInfo(Guid.NewGuid(), _stopwatch.Elapsed);
            var dto = new ClientMessage.IdentifyClient(ClientVersion, _esConnection.ConnectionName);

            if (_settings.VerboseLogging)
            {
                _settings.Log.Debug(
                    $"IdentifyClient; Client Version: {ClientVersion}, ConnectionName: {_esConnection.ConnectionName}, ");
            }

            _connection.EnqueueSend(new TcpPackage(TcpCommand.IdentifyClient, _identifyInfo.CorrelationId,
                                                   dto.Serialize()));
        }
示例#9
0
        private void GoToConnectedState()
        {
            Ensure.NotNull(_connection, "_connection");

            _state           = ConnectionState.Connected;
            _connectingPhase = ConnectingPhase.Connected;

            Interlocked.CompareExchange(ref _wasConnected, 1, 0);

            RaiseConnectedEvent(_connection.RemoteEndPoint);

            if (_stopwatch.Elapsed - _lastTimeoutsTimeStamp >= _settings.OperationTimeoutCheckPeriod)
            {
                _operations.CheckTimeoutsAndRetry(_connection);
                _subscriptions.CheckTimeoutsAndRetry(_connection);
                _lastTimeoutsTimeStamp = _stopwatch.Elapsed;
            }
        }
示例#10
0
        private void GoToConnectedState()
        {
            Ensure.NotNull(_connection, "_connection");

            _state           = ConnectionState.Connected;
            _connectingPhase = ConnectingPhase.Connected;

            if (_settings.Connected != null)
            {
                _settings.Connected(_esConnection, _connection.RemoteEndPoint);
            }

            if (_stopwatch.Elapsed - _lastTimeoutsTimeStamp >= _settings.OperationTimeoutCheckPeriod)
            {
                _operations.CheckTimeoutsAndRetry(_connection);
                _subscriptions.CheckTimeoutsAndRetry(_connection);
                _lastTimeoutsTimeStamp = _stopwatch.Elapsed;
            }
        }
示例#11
0
        private void EstablishTcpConnection(NodeEndPoints endPoints)
        {
            var endPoint = _settings.UseSslConnection
                                ? endPoints.SecureTcpEndPoint ?? endPoints.TcpEndPoint
                                : endPoints.TcpEndPoint;

            if (endPoint == null)
            {
                CloseConnection("No end point to node specified.");
                return;
            }

            LogDebug("EstablishTcpConnection to [{0}]", endPoint);

            if (_state != ConnectionState.Connecting)
            {
                return;
            }
            if (_connectingPhase != ConnectingPhase.EndPointDiscovery)
            {
                return;
            }

            _connectingPhase = ConnectingPhase.ConnectionEstablishing;
            _connection      = new TcpPackageConnection(
                _settings.Log,
                endPoint,
                Guid.NewGuid(),
                _settings.UseSslConnection,
                _settings.TargetHost,
                _settings.ValidateServer,
                _settings.ClientConnectionTimeout,
                (connection, package) => EnqueueMessage(new HandleTcpPackageMessage(connection, package)),
                (connection, exc) => EnqueueMessage(new TcpConnectionErrorMessage(connection, exc)),
                connection => EnqueueMessage(new TcpConnectionEstablishedMessage(connection)),
                (connection, error) => EnqueueMessage(new TcpConnectionClosedMessage(connection, error)));
            _connection.StartReceiving();
        }
        private void ReconnectTo(NodeEndPoints endPoints)
        {
            IPEndPoint endPoint = _settings.UseSslConnection
                                          ? endPoints.SecureTcpEndPoint ?? endPoints.TcpEndPoint
                                          : endPoints.TcpEndPoint;
            if (endPoint == null)
            {
                CloseConnection("No end point is specified while trying to reconnect.");
                return;
            }

            if (_state != ConnectionState.Connected || _connection.RemoteEndPoint.Equals(endPoint))
                return;

            var msg = string.Format("EventStoreConnection '{0}': going to reconnect to [{1}]. Current endpoint: [{2}, L{3}].",
                                    _esConnection.ConnectionName, endPoint, _connection.RemoteEndPoint, _connection.LocalEndPoint);
            if (_settings.VerboseLogging) _settings.Log.Info(msg);
            CloseTcpConnection(msg);

            _state = ConnectionState.Connecting;
            _connectingPhase = ConnectingPhase.EndPointDiscovery;
            EstablishTcpConnection(endPoints);
        }
        private void GoToConnectedState()
        {
            Ensure.NotNull(_connection, "_connection");

            _state = ConnectionState.Connected;
            _connectingPhase = ConnectingPhase.Connected;

            Interlocked.CompareExchange(ref _wasConnected, 1, 0);

            RaiseConnectedEvent(_connection.RemoteEndPoint);

            if (_stopwatch.Elapsed - _lastTimeoutsTimeStamp >= _settings.OperationTimeoutCheckPeriod)
            {
                _operations.CheckTimeoutsAndRetry(_connection);
                _subscriptions.CheckTimeoutsAndRetry(_connection);
                _lastTimeoutsTimeStamp = _stopwatch.Elapsed;
            }
        }
        private void TcpConnectionEstablished(TcpPackageConnection connection)
        {
            if (_state != ConnectionState.Connecting || _connection != connection || connection.IsClosed)
            {
                LogDebug("IGNORED (_state {0}, _conn.Id {1:B}, conn.Id {2:B}, conn.closed {3}): TCP connection to [{4}, L{5}] established.", 
                         _state, _connection == null ? Guid.Empty : _connection.ConnectionId, connection.ConnectionId, 
                         connection.IsClosed, connection.RemoteEndPoint, connection.LocalEndPoint);
                return;
            }

            LogDebug("TCP connection to [{0}, L{1}, {2:B}] established.", connection.RemoteEndPoint, connection.LocalEndPoint, connection.ConnectionId);
            _heartbeatInfo = new HeartbeatInfo(_packageNumber, true, _stopwatch.Elapsed);

            if (_settings.DefaultUserCredentials != null)
            {
                _connectingPhase = ConnectingPhase.Authentication;

                _authInfo = new AuthInfo(Guid.NewGuid(), _stopwatch.Elapsed);
                _connection.EnqueueSend(new TcpPackage(TcpCommand.Authenticate,
                                                       TcpFlags.Authenticated,
                                                       _authInfo.CorrelationId,
                                                       _settings.DefaultUserCredentials.Username,
                                                       _settings.DefaultUserCredentials.Password, 
                                                       null));
            }
            else
            {
                GoToConnectedState();
            }
        }
        private void TcpConnectionClosed(TcpPackageConnection connection)
        {
            if (_state == ConnectionState.Init) throw new Exception();
            if (_state == ConnectionState.Closed || _connection != connection)
            {
                LogDebug("IGNORED (_state: {0}, _conn.ID: {1:B}, conn.ID: {2:B}): TCP connection to [{3}, L{4}] closed.", 
                         _state, _connection == null ? Guid.Empty : _connection.ConnectionId,  connection.ConnectionId, 
                         connection.RemoteEndPoint, connection.LocalEndPoint);
                return;
            }

            _state = ConnectionState.Connecting;
            _connectingPhase = ConnectingPhase.Reconnecting;

            LogDebug("TCP connection to [{0}, L{1}, {2:B}] closed.", connection.RemoteEndPoint, connection.LocalEndPoint, connection.ConnectionId);

            _subscriptions.PurgeSubscribedAndDroppedSubscriptions(_connection.ConnectionId);
            _reconnInfo = new ReconnectionInfo(_reconnInfo.ReconnectionAttempt, _stopwatch.Elapsed);

            if (Interlocked.CompareExchange(ref _wasConnected, 0, 1) == 1)
            {
                RaiseDisconnected(connection.RemoteEndPoint);
            }
        }
        private void EstablishTcpConnection(NodeEndPoints endPoints)
        {
            var endPoint = _settings.UseSslConnection ? endPoints.SecureTcpEndPoint ?? endPoints.TcpEndPoint : endPoints.TcpEndPoint;
            if (endPoint == null)
            {
                CloseConnection("No end point to node specified.");
                return;
            }

            LogDebug("EstablishTcpConnection to [{0}]", endPoint);

            if (_state != ConnectionState.Connecting) return;
            if (_connectingPhase != ConnectingPhase.EndPointDiscovery) return;

            _connectingPhase = ConnectingPhase.ConnectionEstablishing;
            _connection = new TcpPackageConnection(
                    _settings.Log,
                    endPoint,
                    Guid.NewGuid(),
                    _settings.UseSslConnection,
                    _settings.TargetHost,
                    _settings.ValidateServer,
                    _settings.ClientConnectionTimeout,
                    (connection, package) => EnqueueMessage(new HandleTcpPackageMessage(connection, package)),
                    (connection, exc) => EnqueueMessage(new TcpConnectionErrorMessage(connection, exc)),
                    connection => EnqueueMessage(new TcpConnectionEstablishedMessage(connection)),
                    (connection, error) => EnqueueMessage(new TcpConnectionClosedMessage(connection, error)));
            _connection.StartReceiving();
        }
        private void DiscoverEndPoint(TaskCompletionSource<object> completionTask)
        {
            LogDebug("DiscoverEndPoint");

            if (_state != ConnectionState.Connecting) return;
            if (_connectingPhase != ConnectingPhase.Reconnecting) return;

            _connectingPhase = ConnectingPhase.EndPointDiscovery;

            _endPointDiscoverer.DiscoverAsync(_connection != null ? _connection.RemoteEndPoint : null).ContinueWith(t =>
            {
                if (t.IsFaulted)
                {
                    EnqueueMessage(new CloseConnectionMessage("Failed to resolve TCP end point to which to connect.", t.Exception));
                    if (completionTask != null)
                        completionTask.SetException(new CannotEstablishConnectionException("Couldn't resolve target end point.", t.Exception));
                }
                else
                {
                    EnqueueMessage(new EstablishTcpConnectionMessage(t.Result));
                    if (completionTask != null)
                        completionTask.SetResult(null);
                }
            });
        }
        private void StartConnection(TaskCompletionSource<object> task, IEndPointDiscoverer endPointDiscoverer)
        {
            Ensure.NotNull(task, "task");
            Ensure.NotNull(endPointDiscoverer, "endPointDiscoverer");

            LogDebug("StartConnection");

            switch (_state)
            {
                case ConnectionState.Init:
                {
                    _endPointDiscoverer = endPointDiscoverer;
                    _state = ConnectionState.Connecting;
                    _connectingPhase = ConnectingPhase.Reconnecting;
                    DiscoverEndPoint(task);
                    break;
                }
                case ConnectionState.Connecting:
                case ConnectionState.Connected:
                {
                    task.SetException(new InvalidOperationException(
                        string.Format("EventStoreConnection '{0}' is already active.", _esConnection.ConnectionName)));
                    break;
                }
                case ConnectionState.Closed:
                    task.SetException(new ObjectDisposedException(_esConnection.ConnectionName));
                    break;
                default: throw new Exception(string.Format("Unknown state: {0}", _state));
            }
        }
        private void GoToConnectedState()
        {
            Ensure.NotNull(_connection, "_connection");

            _state = ConnectionState.Connected;
            _connectingPhase = ConnectingPhase.Connected;

            if (_settings.Connected != null)
                _settings.Connected(_esConnection, _connection.RemoteEndPoint);

            if (_stopwatch.Elapsed - _lastTimeoutsTimeStamp >= _settings.OperationTimeoutCheckPeriod)
            {
                _operations.CheckTimeoutsAndRetry(_connection);
                _subscriptions.CheckTimeoutsAndRetry(_connection);
                _lastTimeoutsTimeStamp = _stopwatch.Elapsed;
            }
        }