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;
        }
 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());
 }
Пример #3
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;
        }
Пример #4
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());
                }
            }
        }
Пример #5
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;
        }
 public void Unsubscribe(Guid correlationId)
 {
     if (DropSubscription(correlationId))
     {
         var pkg = new TcpPackage(TcpCommand.UnsubscribeFromStream,
                                  correlationId,
                                  new ClientMessage.UnsubscribeFromStream().Serialize());
         _connection.EnqueueSend(pkg.AsByteArray());
     }
 }