public Task<EventStoreSubscription> Subscribe(string streamId, bool resolveLinkTos, Action<ResolvedEvent> eventAppeared, Action subscriptionDropped)
        {
            var id = Guid.NewGuid();

            var eventStoreSubscription = new EventStoreSubscription(id, streamId, this, eventAppeared, subscriptionDropped);
            var subscriptionTaskPair = new SubscriptionTaskPair(eventStoreSubscription);
            if (!_subscriptions.TryAdd(id, subscriptionTaskPair))
                throw new Exception("Failed to add subscription. Concurrency failure.");

            var subscribe = new ClientMessage.SubscribeToStream(streamId, resolveLinkTos);
            var pkg = new TcpPackage(TcpCommand.SubscribeToStream, id, subscribe.Serialize());
            _connection.EnqueueSend(pkg.AsByteArray());

            return subscriptionTaskPair.TaskCompletionSource.Task;
        }
Ejemplo n.º 2
0
        public void not_authorized_with_empty_data_should_serialize_and_deserialize_correctly()
        {
            var corrId = Guid.NewGuid();
            var refPkg = new TcpPackage(TcpCommand.BadRequest, TcpFlags.None, corrId, null, null, new byte[0]);
            var bytes = refPkg.AsArraySegment();

            var pkg = TcpPackage.FromArraySegment(bytes);
            Assert.AreEqual(TcpCommand.BadRequest, pkg.Command);
            Assert.AreEqual(TcpFlags.None, pkg.Flags);
            Assert.AreEqual(corrId, pkg.CorrelationId);
            Assert.AreEqual(null, pkg.Login);
            Assert.AreEqual(null, pkg.Password);

            Assert.AreEqual(0, pkg.Data.Count);
        }
Ejemplo n.º 3
0
        public void authorized_with_data_should_serialize_and_deserialize_correctly()
        {
            var corrId = Guid.NewGuid();
            var refPkg = new TcpPackage(TcpCommand.BadRequest, TcpFlags.Authenticated, corrId, "login", "pa$$", new byte[] { 1, 2, 3 });
            var bytes = refPkg.AsArraySegment();

            var pkg = TcpPackage.FromArraySegment(bytes);
            Assert.AreEqual(TcpCommand.BadRequest, pkg.Command);
            Assert.AreEqual(TcpFlags.Authenticated, pkg.Flags);
            Assert.AreEqual(corrId, pkg.CorrelationId);
            Assert.AreEqual("login", pkg.Login);
            Assert.AreEqual("pa$$", pkg.Password);

            Assert.AreEqual(3, pkg.Data.Count);
            Assert.AreEqual(1, pkg.Data.Array[pkg.Data.Offset + 0]);
            Assert.AreEqual(2, pkg.Data.Array[pkg.Data.Offset + 1]);
            Assert.AreEqual(3, pkg.Data.Array[pkg.Data.Offset + 2]);
        }
        public InspectionResult InspectPackage(TcpPackage package)
        {
            try
            {
                if (package.Command == TcpCommand.DeniedToRoute)
                {
                    var route = package.Data.Deserialize<ClientMessage.DeniedToRoute>();
                    return new InspectionResult(InspectionDecision.Reconnect, data: route.ExternalTcpEndPoint);
                }
                if (package.Command != TcpCommand.TransactionStartCompleted)
                {
                    return new InspectionResult(InspectionDecision.NotifyError,
                                                new CommandNotExpectedException(TcpCommand.TransactionStartCompleted.ToString(),
                                                                                package.Command.ToString()));
                }

                var data = package.Data;
                var dto = data.Deserialize<ClientMessage.TransactionStartCompleted>();
                _result = dto;

                switch (dto.Result)
                {
                    case ClientMessage.OperationResult.Success:
                        return new InspectionResult(InspectionDecision.Succeed);
                    case ClientMessage.OperationResult.PrepareTimeout:
                    case ClientMessage.OperationResult.CommitTimeout:
                    case ClientMessage.OperationResult.ForwardTimeout:
                        return new InspectionResult(InspectionDecision.Retry);
                    case ClientMessage.OperationResult.WrongExpectedVersion:
                        var err = string.Format("Start transaction failed due to WrongExpectedVersion. Stream: {0}, Expected version: {1}, CorrID: {2}.",
                                                _stream,
                                                _expectedVersion,
                                                CorrelationId);
                        return new InspectionResult(InspectionDecision.NotifyError, new WrongExpectedVersionException(err));
                    case ClientMessage.OperationResult.StreamDeleted:
                        return new InspectionResult(InspectionDecision.NotifyError, new StreamDeletedException(_stream));
                    case ClientMessage.OperationResult.InvalidTransaction:
                        return new InspectionResult(InspectionDecision.NotifyError, new InvalidTransactionException());
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            catch (Exception e)
            {
                return new InspectionResult(InspectionDecision.NotifyError, e);
            }
        }
        public InspectionResult InspectPackage(TcpPackage package)
        {
            try
            {
                if (package.Command != TcpCommand.ReadAllEventsForwardCompleted)
                {
                    return new InspectionResult(InspectionDecision.NotifyError,
                                                new CommandNotExpectedException(TcpCommand.ReadAllEventsForwardCompleted.ToString(),
                                                                                package.Command.ToString()));
                }

                var data = package.Data;
                var dto = data.Deserialize<ClientMessages.ReadAllEventsForwardCompleted>();
                _result = dto;
                return new InspectionResult(InspectionDecision.Succeed);
            }
            catch (Exception e)
            {
                return new InspectionResult(InspectionDecision.NotifyError, e);
            }
        }
Ejemplo n.º 6
0
        private void OnPackageReceived(TcpTypedConnection connection, TcpPackage package)
        {
            Subscription subscription;
            if(!_subscriptions.TryGetValue(package.CorrelationId, out subscription))
            {
                _log.Error("Unexpected package received : {0} ({1})", package.CorrelationId, package.Command);
                return;
            }

            try
            {
                switch (package.Command)
                {
                    case TcpCommand.StreamEventAppeared:
                        var dto = package.Data.Deserialize<ClientMessage.StreamEventAppeared>();
                        var recordedEvent = new RecordedEvent(dto);
                        var commitPos = dto.CommitPosition;
                        var preparePos = dto.PreparePosition;
                        ExecuteUserCallbackAsync(() => subscription.EventAppeared(recordedEvent, new Position(commitPos, preparePos)));
                        break;
                    case TcpCommand.SubscriptionDropped:
                    case TcpCommand.SubscriptionToAllDropped:
                        Subscription removed;
                        if(_subscriptions.TryRemove(subscription.Id, out removed))
                        {
                            removed.Source.SetResult(null);
                            ExecuteUserCallbackAsync(removed.SubscriptionDropped);
                        }
                        break;
                    default:
                        throw new ArgumentOutOfRangeException(string.Format("Unexpected command : {0}", package.Command));
                }
            }
            catch (Exception e)
            {
                _log.Error(e, "Error on package received");
            }
        }
        public InspectionResult InspectPackage(TcpPackage package)
        {
            try
            {
                if (package.Command != TcpCommand.ReadStreamEventsForwardCompleted)
                {
                    return new InspectionResult(InspectionDecision.NotifyError,
                        new CommandNotExpectedException(TcpCommand.ReadStreamEventsForwardCompleted.ToString(),
                                                        package.Command.ToString()));
                }

                var data = package.Data;
                var dto = data.Deserialize<ClientMessages.ReadStreamEventsForwardCompleted>();
                _result = dto;

                switch ((RangeReadResult)dto.Result)
                {
                    case RangeReadResult.Success:
                        return new InspectionResult(InspectionDecision.Succeed);
                    case RangeReadResult.StreamDeleted:
                        return new InspectionResult(InspectionDecision.NotifyError, new StreamDeletedException(_stream));
                    case RangeReadResult.NoStream:
                        return new InspectionResult(InspectionDecision.NotifyError, new StreamDoesNotExistException());
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            catch (Exception e)
            {
                return new InspectionResult(InspectionDecision.NotifyError, e);
            }
        }
        private void HandleTcpPackage(TcpPackageConnection connection, TcpPackage package)
        {
            if (_connection != connection || _state == ConnectionState.Closed || _state == ConnectionState.Init)
            {
                LogDebug("IGNORED: HandleTcpPackage connId {0}, package {1}, {2}.", connection.ConnectionId, package.Command, package.CorrelationId);
                return;
            }
            
            LogDebug("HandleTcpPackage connId {0}, package {1}, {2}.", _connection.ConnectionId, package.Command, package.CorrelationId);
            _packageNumber += 1;

            if (package.Command == TcpCommand.HeartbeatResponseCommand)
                return;
            if (package.Command == TcpCommand.HeartbeatRequestCommand)
            {
                _connection.EnqueueSend(new TcpPackage(TcpCommand.HeartbeatResponseCommand, package.CorrelationId, null));
                return;
            }

            if (package.Command == TcpCommand.Authenticated || package.Command == TcpCommand.NotAuthenticated)
            {
                if (_state == ConnectionState.Connecting
                    && _connectingPhase == ConnectingPhase.Authentication
                    && _authInfo.CorrelationId == package.CorrelationId)
                {
                    if (package.Command == TcpCommand.NotAuthenticated)
                        RaiseAuthenticationFailed("Not authenticated");

                    GoToConnectedState();
                    return;
                }
            }

            if (package.Command == TcpCommand.BadRequest && package.CorrelationId == Guid.Empty)
            {
                string message = Helper.EatException(() => Helper.UTF8NoBom.GetString(package.Data.Array, package.Data.Offset, package.Data.Count));
                var exc = new EventStoreConnectionException(
                        string.Format("Bad request received from server. Error: {0}", string.IsNullOrEmpty(message) ? "<no message>" : message));
                CloseConnection("Connection-wide BadRequest received. Too dangerous to continue.", exc);
                return;
            }

            OperationItem operation;
            SubscriptionItem subscription;
            if (_operations.TryGetActiveOperation(package.CorrelationId, out operation))
            {
                var result = operation.Operation.InspectPackage(package);
                LogDebug("HandleTcpPackage OPERATION DECISION {0} ({1}), {2}", result.Decision, result.Description, operation);
                switch (result.Decision)
                {
                    case InspectionDecision.DoNothing: break; 
                    case InspectionDecision.EndOperation: 
                        _operations.RemoveOperation(operation); 
                        break;
                    case InspectionDecision.Retry: 
                        _operations.ScheduleOperationRetry(operation); 
                        break;
                    case InspectionDecision.Reconnect:
                        ReconnectTo(new NodeEndPoints(result.TcpEndPoint, result.SecureTcpEndPoint));
                        _operations.ScheduleOperationRetry(operation);
                        break;
                    default: throw new Exception(string.Format("Unknown InspectionDecision: {0}", result.Decision));
                }
                if (_state == ConnectionState.Connected)
                    _operations.ScheduleWaitingOperations(connection);
            }
            else if (_subscriptions.TryGetActiveSubscription(package.CorrelationId, out subscription))
            {
                var result = subscription.Operation.InspectPackage(package);
                LogDebug("HandleTcpPackage SUBSCRIPTION DECISION {0} ({1}), {2}", result.Decision, result.Description, subscription);
                switch (result.Decision)
                {
                    case InspectionDecision.DoNothing: break;
                    case InspectionDecision.EndOperation: 
                        _subscriptions.RemoveSubscription(subscription); 
                        break;
                    case InspectionDecision.Retry: 
                        _subscriptions.ScheduleSubscriptionRetry(subscription); 
                        break;
                    case InspectionDecision.Reconnect:
                        ReconnectTo(new NodeEndPoints(result.TcpEndPoint, result.SecureTcpEndPoint));
                        _subscriptions.ScheduleSubscriptionRetry(subscription);
                        break;
                    case InspectionDecision.Subscribed:
                        subscription.IsSubscribed = true;
                        break;
                    default: throw new Exception(string.Format("Unknown InspectionDecision: {0}", result.Decision));
                }
            }
            else
            {
                LogDebug("HandleTcpPackage UNMAPPED PACKAGE with CorrelationId {0:B}, Command: {1}", package.CorrelationId, package.Command);
            }
        }
Ejemplo n.º 9
0
        public InspectionResult InspectPackage(TcpPackage package)
        {
            try
            {
                if (package.Command != TcpCommand.DeleteStreamCompleted)
                {
                    return new InspectionResult(InspectionDecision.NotifyError,
                                                new CommandNotExpectedException(TcpCommand.DeleteStreamCompleted.ToString(),
                                                                                package.Command.ToString()));
                }

                var data = package.Data;
                var dto = data.Deserialize<ClientMessages.DeleteStreamCompleted>();
                _result = dto;

                switch ((OperationErrorCode)dto.ErrorCode)
                {
                    case OperationErrorCode.Success:
                        return new InspectionResult(InspectionDecision.Succeed);
                    case OperationErrorCode.PrepareTimeout:
                    case OperationErrorCode.CommitTimeout:
                    case OperationErrorCode.ForwardTimeout:
                        return new InspectionResult(InspectionDecision.Retry);
                    case OperationErrorCode.WrongExpectedVersion:
                        var err = string.Format("Delete stream failed due to WrongExpectedVersion. Stream: {0}, Expected version: {1}, CorrID: {2}.",
                                                _stream,
                                                _expectedVersion,
                                                CorrelationId);
                        return new InspectionResult(InspectionDecision.NotifyError, new WrongExpectedVersionException(err));
                    case OperationErrorCode.StreamDeleted:
                        return new InspectionResult(InspectionDecision.NotifyError, new StreamDeletedException(_stream));
                    case OperationErrorCode.InvalidTransaction:
                        return new InspectionResult(InspectionDecision.NotifyError, new InvalidTransactionException());
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            catch (Exception e)
            {
                return new InspectionResult(InspectionDecision.NotifyError, e);
            }
        }
        public InspectionResult InspectPackage(TcpPackage package)
        {
            try
            {
                switch (package.Command)
                {
                    case TcpCommand.SubscriptionConfirmation:
                    {
                        var dto = package.Data.Deserialize<ClientMessage.SubscriptionConfirmation>();
                        ConfirmSubscription(dto.LastCommitPosition, dto.LastEventNumber);
                        return new InspectionResult(InspectionDecision.Subscribed, "SubscriptionConfirmation");
                    }

                    case TcpCommand.StreamEventAppeared:
                    {
                        var dto = package.Data.Deserialize<ClientMessage.StreamEventAppeared>();
                        EventAppeared(new ResolvedEvent(dto.Event));
                        return new InspectionResult(InspectionDecision.DoNothing, "StreamEventAppeared");
                    }

                    case TcpCommand.SubscriptionDropped:
                    {
                        var dto = package.Data.Deserialize<ClientMessage.SubscriptionDropped>();
                        switch (dto.Reason)
                        {
                            case ClientMessage.SubscriptionDropped.SubscriptionDropReason.Unsubscribed:
                                DropSubscription(SubscriptionDropReason.UserInitiated, null);
                                break;
                            case ClientMessage.SubscriptionDropped.SubscriptionDropReason.AccessDenied:
                                DropSubscription(SubscriptionDropReason.AccessDenied, 
                                                 new AccessDeniedException(string.Format("Subscription to '{0}' failed due to access denied.", _streamId == string.Empty ? "<all>" : _streamId)));
                                break;
                            default: 
                                if (_verboseLogging) _log.Debug("Subscription dropped by server. Reason: {0}.", dto.Reason);
                                DropSubscription(SubscriptionDropReason.Unknown, 
                                                 new CommandNotExpectedException(string.Format("Unsubscribe reason: '{0}'.", dto.Reason)));
                                break;
                        }
                        return new InspectionResult(InspectionDecision.EndOperation, string.Format("SubscriptionDropped: {0}", dto.Reason));
                    }

                    case TcpCommand.NotAuthenticated:
                    {
                        string message = Helper.EatException(() => Helper.UTF8NoBom.GetString(package.Data.Array, package.Data.Offset, package.Data.Count));
                        DropSubscription(SubscriptionDropReason.NotAuthenticated,
                                         new NotAuthenticatedException(string.IsNullOrEmpty(message) ? "Authentication error" : message));
                        return new InspectionResult(InspectionDecision.EndOperation, "NotAuthenticated");
                    }

                    case TcpCommand.BadRequest:
                    {
                        string message = Helper.EatException(() => Helper.UTF8NoBom.GetString(package.Data.Array, package.Data.Offset, package.Data.Count));
                        DropSubscription(SubscriptionDropReason.ServerError, 
                                         new ServerErrorException(string.IsNullOrEmpty(message) ? "<no message>" : message));
                        return new InspectionResult(InspectionDecision.EndOperation, string.Format("BadRequest: {0}", message));
                    }

                    case TcpCommand.NotHandled:
                    {
                        if (_subscription != null)
                            throw new Exception("NotHandled command appeared while we already subscribed.");

                        var message = package.Data.Deserialize<ClientMessage.NotHandled>();
                        switch (message.Reason)
                        {
                            case ClientMessage.NotHandled.NotHandledReason.NotReady:
                                return new InspectionResult(InspectionDecision.Retry, "NotHandled - NotReady");

                            case ClientMessage.NotHandled.NotHandledReason.TooBusy:
                                return new InspectionResult(InspectionDecision.Retry, "NotHandled - TooBusy");

                            case ClientMessage.NotHandled.NotHandledReason.NotMaster:
                                var masterInfo = message.AdditionalInfo.Deserialize<ClientMessage.NotHandled.MasterInfo>();
                                return new InspectionResult(InspectionDecision.Reconnect, "NotHandled - NotMaster",
                                                            masterInfo.ExternalTcpEndPoint, masterInfo.ExternalSecureTcpEndPoint);

                            default:
                                _log.Error("Unknown NotHandledReason: {0}.", message.Reason);
                                return new InspectionResult(InspectionDecision.Retry, "NotHandled - <unknown>");
                        }
                    }

                    default:
                    {
                        DropSubscription(SubscriptionDropReason.ServerError, 
                                         new CommandNotExpectedException(package.Command.ToString()));
                        return new InspectionResult(InspectionDecision.EndOperation, package.Command.ToString());
                    }
                }
            }
            catch (Exception e)
            {
                DropSubscription(SubscriptionDropReason.Unknown, e);
                return new InspectionResult(InspectionDecision.EndOperation, string.Format("Exception - {0}", e.Message));
            }
        }
Ejemplo n.º 11
0
 public HandleTcpPackageMessage(TcpPackageConnection connection, TcpPackage package)
 {
     Connection = connection;
     Package = package;
 }
 public void Unsubscribe(Guid correlationId)
 {
     if (DropSubscription(correlationId))
     {
         var pkg = new TcpPackage(TcpCommand.UnsubscribeFromStream,
                                  correlationId,
                                  new ClientMessage.UnsubscribeFromStream().Serialize());
         _connection.EnqueueSend(pkg.AsByteArray());
     }
 }
        private void OnPackageReceived(TcpTypedConnection connection, TcpPackage package)
        {
            SubscriptionTaskPair subscription;
            if (!_subscriptions.TryGetValue(package.CorrelationId, out subscription))
            {
                _log.Error("Unexpected package received : {0} ({1})", package.CorrelationId, package.Command);
                return;
            }

            try
            {
                switch (package.Command)
                {
                    case TcpCommand.SubscriptionConfirmation:
                    {
                        var dto = package.Data.Deserialize<ClientMessage.SubscriptionConfirmation>();
                        subscription.Subscription.ConfirmSubscription(dto.LastCommitPosition, dto.LastEventNumber);
                        subscription.TaskCompletionSource.SetResult(subscription.Subscription);
                        break;
                    }
                    case TcpCommand.StreamEventAppeared:
                    {
                        var dto = package.Data.Deserialize<ClientMessage.StreamEventAppeared>();
                        ExecuteUserCallbackAsync(() => subscription.Subscription.EventAppeared(new ResolvedEvent(dto.Event)));
                        break;
                    }
                    case TcpCommand.SubscriptionDropped:
                    {
                        DropSubscription(package.CorrelationId);
                        break;
                    }
                    default:
                        throw new ArgumentOutOfRangeException(string.Format("Unexpected command : {0}", package.Command));
                }
            }
            catch (Exception e)
            {
                _log.Error(e, "Error on package received");
            }
        }
Ejemplo n.º 14
0
        public TcpTypedConnection CreateTcpConnection(Action<TcpTypedConnection, TcpPackage> handlePackage,
                                              Action<TcpTypedConnection> connectionEstablished,
                                              Action<TcpTypedConnection, IPEndPoint, SocketError> connectionClosed)
        {
            var connectionCreatedEvent = new AutoResetEvent(false);
            TcpTypedConnection typedConnection = null;

            var connection = _connector.ConnectTo(
                _tcpEndpoint,
                tcpConnection =>
                {
                    _log.Debug("Connected to [{0}].", tcpConnection.EffectiveEndPoint);
                    connectionCreatedEvent.WaitOne(500);
                    connectionEstablished(typedConnection);
                },
                (conn, error) =>
                {
                    var message = string.Format("Connection to [{0}] failed. Error: {1}.", conn.EffectiveEndPoint, error);
                    _log.Debug(message);

                    connectionClosed(null, conn.EffectiveEndPoint, error);
                });

            typedConnection = new TcpTypedConnection(connection);
            typedConnection.ConnectionClosed +=
                (conn, error) =>
                {
                    _log.Debug("Connection [{0}] was closed {1}",
                               conn.EffectiveEndPoint,
                               error == SocketError.Success ? "cleanly." : "with error: " + error + ".");

                    connectionClosed(conn, conn.EffectiveEndPoint, error);
                };

            connectionCreatedEvent.Set();

            typedConnection.ReceiveAsync((conn, pkg) =>
            {
                var package = new TcpPackage();
                var valid = false;
                try
                {
                    package = TcpPackage.FromArraySegment(new ArraySegment<byte>(pkg));
                    valid = true;

                    if (package.Command == TcpCommand.HeartbeatRequestCommand)
                    {
                        var response = new TcpPackage(TcpCommand.HeartbeatResponseCommand, Guid.NewGuid(), null);
                        conn.EnqueueSend(response.AsByteArray());
                        return;
                    }

                    handlePackage(conn, package);
                }
                catch (Exception e)
                {
                    var effectiveEndPoint = conn.EffectiveEndPoint;
                    var message = string.Format("[{0}] ERROR for {1}. Connection will be closed.",
                                                effectiveEndPoint,
                                                valid ? package.Command as object : "<invalid package>");

                    _log.Debug(e, message);
                    conn.Close();
                }
            });

            return typedConnection;
        }
Ejemplo n.º 15
0
        private void IncomingMessageArrived(ArraySegment<byte> data)
        {
            var package = new TcpPackage();
            var valid = false;
            try
            {
                package = TcpPackage.FromArraySegment(data);
                valid = true;
                _handlePackage(this, package);
            }
            catch (Exception e)
            {
                _connection.Close(string.Format("Error when processing TcpPackage {0}: {1}", 
                                                valid ? package.Command.ToString() : "<invalid package>", e.Message));

                var message = string.Format("[{0}, L{1}] ERROR for {2}. Connection will be closed.",
                                            RemoteEndPoint, LocalEndPoint, valid ? package.Command.ToString() : "<invalid package>");
                if (_onError != null)
                    _onError(this, e);
                _log.Debug(e, message);
            }
        }
        public InspectionResult InspectPackage(TcpPackage package)
        {
            try
            {
                if (package.Command != TcpCommand.ReadStreamEventsForwardCompleted)
                {
                    return new InspectionResult(InspectionDecision.NotifyError,
                                                new CommandNotExpectedException(TcpCommand.ReadStreamEventsForwardCompleted.ToString(), 
                                                                                package.Command.ToString()));
                }

                _result = package.Data.Deserialize<ClientMessage.ReadStreamEventsCompleted>();
                switch (_result.Result)
                {
                    case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.Success:
                    case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.StreamDeleted:
                    case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.NoStream:
                        return new InspectionResult(InspectionDecision.Succeed);
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            catch (Exception e)
            {
                return new InspectionResult(InspectionDecision.NotifyError, e);
            }
        }
Ejemplo n.º 17
0
 public void EnqueueSend(TcpPackage package)
 {
     if (_connection == null)
         throw new InvalidOperationException("Failed connection.");
     _connection.EnqueueSend(_framer.FrameData(package.AsArraySegment()));
 }
        private void OnPackageReceived(TcpTypedConnection connection, TcpPackage package)
        {
            var corrId = package.CorrelationId;
            WorkItem workItem;

            if (!_inProgress.TryGetValue(corrId, out workItem))
            {
                _log.Error("Unexpected CorrelationId received {{{0}}}", corrId);
                return;
            }

            var result = workItem.Operation.InspectPackage(package);
            switch (result.Decision)
            {
                case InspectionDecision.Succeed:
                {
                    if (TryRemoveWorkItem(workItem))
                        workItem.Operation.Complete();
                    break;
                }
                case InspectionDecision.Retry:
                {
                    Retry(workItem);
                    break;
                }
                case InspectionDecision.Reconnect:
                {
                    Reconnect(workItem, (IPEndPoint) result.Data);
                    break;
                }
                case InspectionDecision.NotifyError:
                {
                    if (TryRemoveWorkItem(workItem))
                        workItem.Operation.Fail(result.Error);
                    break;
                }
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
Ejemplo n.º 19
0
        public Task SubscribeToAllStreams(Action<RecordedEvent, Position> eventAppeared, Action subscriptionDropped)
        {
            var id = Guid.NewGuid();
            var source = new TaskCompletionSource<object>();

            if (_subscriptions.TryAdd(id, new Subscription(source, id, eventAppeared, subscriptionDropped)))
            {
                var subscribe = new ClientMessage.SubscribeToAllStreams();
                var pkg = new TcpPackage(TcpCommand.SubscribeToAllStreams, id, subscribe.Serialize());
                _connection.EnqueueSend(pkg.AsByteArray());
            }
            else
            {
                source.SetException(new Exception("Failed to add subscription to all streams. Concurrency failure"));
            }

            return source.Task;
        }
Ejemplo n.º 20
0
        public InspectionResult InspectPackage(TcpPackage package)
        {
            try
            {
                if (package.Command == TcpCommand.DeniedToRoute)
                {
                    var route = package.Data.Deserialize<ClientMessage.DeniedToRoute>();
                    return new InspectionResult(InspectionDecision.Reconnect,
                                                data: new EndpointsPair(route.ExternalTcpEndPoint,
                                                                        route.ExternalHttpEndPoint));
                }
                if (package.Command != TcpCommand.CreateStreamCompleted)
                    return new InspectionResult(InspectionDecision.NotifyError,
                                                new CommandNotExpectedException(TcpCommand.CreateStreamCompleted.ToString(),
                                                                                package.Command.ToString()));

                var data = package.Data;
                var dto = data.Deserialize<ClientMessage.CreateStreamCompleted>();
                _result = dto;

                switch ((OperationErrorCode)dto.ErrorCode)
                {
                    case OperationErrorCode.Success:
                        return new InspectionResult(InspectionDecision.Succeed);

                    case OperationErrorCode.PrepareTimeout:
                    case OperationErrorCode.CommitTimeout:
                    case OperationErrorCode.ForwardTimeout:
                        return new InspectionResult(InspectionDecision.Retry);
                    case OperationErrorCode.WrongExpectedVersion:
                        var err = string.Format("Create stream failed due to WrongExpectedVersion. Stream: {0}, CorrID: {1}.",
                                                _stream,
                                                CorrelationId);
                        return new InspectionResult(InspectionDecision.NotifyError, new WrongExpectedVersionException(err));
                    case OperationErrorCode.StreamDeleted:
                        return new InspectionResult(InspectionDecision.NotifyError, new StreamDeletedException(_stream));
                    case OperationErrorCode.InvalidTransaction:
                        return new InspectionResult(InspectionDecision.NotifyError, new InvalidTransactionException());
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            catch (Exception e)
            {
                return new InspectionResult(InspectionDecision.NotifyError, e);
            }
        }
Ejemplo n.º 21
0
        public void UnsubscribeFromAllStreams()
        {
            var all = _subscriptions.Values;
            var ids = all.Where(s => s.Stream == null).Select(s => s.Id);

            foreach (var id in ids)
            {
                Subscription removed;
                if (_subscriptions.TryRemove(id, out removed))
                {
                    removed.Source.SetResult(null);
                    ExecuteUserCallbackAsync(removed.SubscriptionDropped);

                    var pkg = new TcpPackage(TcpCommand.UnsubscribeFromAllStreams,
                                             id,
                                             new ClientMessage.UnsubscribeFromAllStreams().Serialize());
                    _connection.EnqueueSend(pkg.AsByteArray());
                }
            }
        }
 public void should_throw_argument_exception_on_serialization_when_password_too_long()
 {
     var pkg = new TcpPackage(TcpCommand.BadRequest, TcpFlags.Authenticated, Guid.NewGuid(), "login", new string('*', 256), new byte[] { 1, 2, 3 });
     Assert.Throws<ArgumentException>(() => pkg.AsByteArray());
 }
        public InspectionResult InspectPackage(TcpPackage package)
        {
            try
            {
                if (package.Command == TcpCommand.DeniedToRoute)
                {
                    var route = package.Data.Deserialize<ClientMessage.DeniedToRoute>();
                    return new InspectionResult(InspectionDecision.Reconnect, data: route.ExternalTcpEndPoint);
                }
                if (package.Command != TcpCommand.TransactionWriteCompleted)
                {
                    return new InspectionResult(InspectionDecision.NotifyError,
                                             new CommandNotExpectedException(TcpCommand.TransactionWriteCompleted.ToString(),
                                                                             package.Command.ToString()));
                }

                var data = package.Data;
                var dto = data.Deserialize<ClientMessage.TransactionWriteCompleted>();
                _result = dto;

                switch (dto.Result)
                {
                    case ClientMessage.OperationResult.Success:
                        return new InspectionResult(InspectionDecision.Succeed);
                    case ClientMessage.OperationResult.PrepareTimeout:
                    case ClientMessage.OperationResult.CommitTimeout:
                    case ClientMessage.OperationResult.ForwardTimeout:
                        return new InspectionResult(InspectionDecision.Retry);
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            catch (Exception e)
            {
                return new InspectionResult(InspectionDecision.NotifyError, e);
            }
        }