private static TcpPackage WrapTransactionWrite(ClientMessage.TransactionWrite msg)
        {
            var dto = new ClientMessageDto.TransactionWrite(msg.TransactionId,
                                                            msg.EventStreamId,
                                                            msg.Events.Select(x => new ClientMessageDto.Event(x.EventId, x.EventType, x.Data, x.Metadata)).ToArray());

            return(new TcpPackage(TcpCommand.TransactionWrite, msg.CorrelationId, dto.Serialize()));
        }
Beispiel #2
0
        public bool Execute(CommandProcessorContext context, string[] args)
        {
            var eventStreamId   = "test-stream";
            var expectedVersion = ExpectedVersion.Any;
            int eventsCnt       = 10;

            if (args.Length > 0)
            {
                if (args.Length > 3)
                {
                    return(false);
                }
                eventStreamId = args[0];
                if (args.Length > 1)
                {
                    expectedVersion = args[1].ToUpper() == "ANY" ? ExpectedVersion.Any : int.Parse(args[1]);
                }
                if (args.Length > 2)
                {
                    eventsCnt = int.Parse(args[1]);
                }
            }

            context.IsAsync();

            var  sw            = new Stopwatch();
            var  stage         = Stage.AcquiringTransactionId;
            long transactionId = -1;
            var  writtenEvents = 0;
            var  corrid        = Guid.NewGuid();

            context.Client.CreateTcpConnection(
                context,
                connectionEstablished: conn =>
            {
                context.Log.Info("[{0}]: Starting transaction...", conn.EffectiveEndPoint);
                sw.Start();

                var tranStart = new ClientMessageDto.TransactionStart(eventStreamId, expectedVersion);
                var package   = new TcpPackage(TcpCommand.TransactionStart, corrid, tranStart.Serialize());
                conn.EnqueueSend(package.AsByteArray());
            },
                handlePackage: (conn, pkg) =>
            {
                switch (stage)
                {
                case Stage.AcquiringTransactionId:
                    {
                        if (pkg.Command != TcpCommand.TransactionStartCompleted)
                        {
                            context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                            return;
                        }

                        var dto = pkg.Data.Deserialize <ClientMessageDto.TransactionStartCompleted>();
                        if ((OperationErrorCode)dto.ErrorCode != OperationErrorCode.Success)
                        {
                            var msg = string.Format("Error while starting transaction: {0} ({1}).", dto.Error, (OperationErrorCode)dto.ErrorCode);
                            context.Log.Info(msg);
                            context.Fail(reason: msg);
                        }
                        else
                        {
                            context.Log.Info("Successfully started transaction. TransactionId: {0}.", dto.TransactionId);
                            context.Log.Info("Now sending transactional events...", dto.TransactionId);

                            transactionId = dto.TransactionId;
                            stage         = Stage.Writing;
                            for (int i = 0; i < eventsCnt; ++i)
                            {
                                var writeDto = new ClientMessageDto.TransactionWrite(transactionId,
                                                                                     eventStreamId,
                                                                                     new[]
                                {
                                    new ClientMessageDto.Event(Guid.NewGuid(),
                                                               "TakeSomeSpaceEvent",
                                                               Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()),
                                                               Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()))
                                });
                                var package = new TcpPackage(TcpCommand.TransactionWrite, corrid, writeDto.Serialize());
                                conn.EnqueueSend(package.AsByteArray());
                            }
                        }

                        break;
                    }

                case Stage.Writing:
                    {
                        if (pkg.Command != TcpCommand.TransactionWriteCompleted)
                        {
                            context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                            return;
                        }

                        var dto = pkg.Data.Deserialize <ClientMessageDto.TransactionWriteCompleted>();
                        if ((OperationErrorCode)dto.ErrorCode != OperationErrorCode.Success)
                        {
                            var msg = string.Format("Error while writing transactional event: {0} ({1}).", dto.Error, (OperationErrorCode)dto.ErrorCode);
                            context.Log.Info(msg);
                            context.Fail(reason: msg);
                        }
                        else
                        {
                            writtenEvents += 1;
                            if (writtenEvents == eventsCnt)
                            {
                                context.Log.Info("Written all events. Committing...");

                                stage         = Stage.Committing;
                                var commitDto = new ClientMessageDto.TransactionCommit(transactionId, eventStreamId);
                                var package   = new TcpPackage(TcpCommand.TransactionCommit, corrid, commitDto.Serialize());
                                conn.EnqueueSend(package.AsByteArray());
                            }
                        }
                        break;
                    }

                case Stage.Committing:
                    {
                        if (pkg.Command != TcpCommand.TransactionCommitCompleted)
                        {
                            context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                            return;
                        }

                        sw.Stop();

                        var dto = pkg.Data.Deserialize <ClientMessageDto.TransactionCommitCompleted>();
                        if ((OperationErrorCode)dto.ErrorCode != OperationErrorCode.Success)
                        {
                            var msg = string.Format("Error while committing transaction: {0} ({1}).", dto.Error, (OperationErrorCode)dto.ErrorCode);
                            context.Log.Info(msg);
                            context.Log.Info("Transaction took: {0}.", sw.Elapsed);
                            context.Fail(reason: msg);
                        }
                        else
                        {
                            context.Log.Info("Successfully committed transaction [{0}]!", dto.TransactionId);
                            context.Log.Info("Transaction took: {0}.", sw.Elapsed);
                            PerfUtils.LogTeamCityGraphData(string.Format("{0}-latency-ms", Keyword), (int)sw.ElapsedMilliseconds);
                            context.Success();
                        }
                        conn.Close();
                        break;
                    }

                default:
                    throw new ArgumentOutOfRangeException();
                }
            },
                connectionClosed: (connection, error) =>
            {
                if (error == SocketError.Success && stage == Stage.Done)
                {
                    context.Success();
                }
                else
                {
                    context.Fail();
                }
            });

            context.WaitForCompletion();
            return(true);
        }