AsByteArray() public méthode

public AsByteArray ( ) : byte[]
Résultat byte[]
Exemple #1
0
        public bool Execute(CommandProcessorContext context, string[] args)
        {
            context.IsAsync();

            var package = new TcpPackage(TcpCommand.Ping, Guid.NewGuid(), null);
            context.Log.Info("[{0}:{1}]: PING...", context.Client.Options.Ip, context.Client.Options.TcpPort);

            var connection = context.Client.CreateTcpConnection(
                context,
                (conn, pkg) =>
                {
                    if (pkg.Command != TcpCommand.Pong)
                    {
                        context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                        return;
                    }
                    context.Log.Info("[{0}:{1}]: PONG!", context.Client.Options.Ip, context.Client.Options.TcpPort);
                    conn.Close();
                    context.Success();
                },
                null,
                (typedConnection, error) =>
                    {
                        if (error == SocketError.Success)
                            context.Success();
                        else
                            context.Fail();
                    });
            connection.EnqueueSend(package.AsByteArray());
            context.WaitForCompletion();
            return true;
        }
        public bool Execute(CommandProcessorContext context, string[] args)
        {
            context.IsAsync();

            context.Client.CreateTcpConnection(
                context,
                connectionEstablished: conn =>
                {
                    var package = new TcpPackage(TcpCommand.Ping, Guid.NewGuid(), null);
                    context.Log.Info("[{0}:{1}]: PING...", context.Client.Options.Ip, context.Client.Options.TcpPort);
                    conn.EnqueueSend(package.AsByteArray());
                },
                handlePackage: (conn, pkg) =>
                {
                    if (pkg.Command != TcpCommand.Pong)
                    {
                        context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                        return;
                    }
                    context.Log.Info("[{0}:{1}]: PONG!", context.Client.Options.Ip, context.Client.Options.TcpPort);
                    context.Success();
                    conn.Close();
                },
                connectionClosed: (typedConnection, error) => context.Fail(reason: "Connection was closed prematurely."));
            context.WaitForCompletion();
            return true;
        }
        private void PingFloodWaiting(CommandProcessorContext context, int clientsCnt, long requestsCnt)
        {
            context.IsAsync();

            var clients = new List<TcpTypedConnection<byte[]>>();
            var threads = new List<Thread>();
            var doneEvent = new ManualResetEventSlim(false);
            var clientsDone = 0;
            long all = 0;
            for (int i = 0; i < clientsCnt; i++)
            {
                var autoResetEvent = new AutoResetEvent(false);
                var client = context.Client.CreateTcpConnection(
                    context,
                    (_, __) =>
                    {
                        Interlocked.Increment(ref all);
                        autoResetEvent.Set();
                    },
                    connectionClosed: (conn, err) => context.Fail(reason: "Connection was closed prematurely."));
                clients.Add(client);

                var count = requestsCnt / clientsCnt + ((i == clientsCnt - 1) ? requestsCnt % clientsCnt : 0);
                threads.Add(new Thread(() =>
                {
                    for (int j = 0; j < count; ++j)
                    {
                        var package = new TcpPackage(TcpCommand.Ping, Guid.NewGuid(), null);
                        client.EnqueueSend(package.AsByteArray());
                        autoResetEvent.WaitOne();
                    }
                    if (Interlocked.Increment(ref clientsDone) == clientsCnt)
                    {
                        context.Success();
                        doneEvent.Set();
                    }
                }) { IsBackground = true });
            }

            var sw = Stopwatch.StartNew();
            threads.ForEach(thread => thread.Start());
            doneEvent.Wait();
            sw.Stop();
            clients.ForEach(x => x.Close());

            var reqPerSec = (all + 0.0)/sw.ElapsedMilliseconds*1000;
            context.Log.Info("{0} requests completed in {1}ms ({2:0.00} reqs per sec).", all, sw.ElapsedMilliseconds, reqPerSec);
            PerfUtils.LogData(Keyword,
                              PerfUtils.Row(PerfUtils.Col("clientsCnt", clientsCnt),
                                            PerfUtils.Col("requestsCnt", requestsCnt),
                                            PerfUtils.Col("ElapsedMilliseconds", sw.ElapsedMilliseconds)));
            PerfUtils.LogTeamCityGraphData(string.Format("{0}-{1}-{2}-reqPerSec", Keyword, clientsCnt, requestsCnt), (int) reqPerSec);
            PerfUtils.LogTeamCityGraphData(string.Format("{0}-latency-ms", Keyword), (int) Math.Round(sw.Elapsed.TotalMilliseconds/all));

            if (Interlocked.Read(ref all) == requestsCnt)
                context.Success();
            else
                context.Fail();
        }
        public bool Execute(CommandProcessorContext context, string[] args)
        {
            var package = new TcpPackage(TcpCommand.ScavengeDatabase, Guid.NewGuid(), null);
            context.Log.Info("Sending SCAVENGE request...");

            var connection = context.Client.CreateTcpConnection(
                context,
                (conn, pkg) => { },
                null,
                (typedConnection, error) =>
                {
                    if (error == SocketError.Success)
                        context.Success();
                    else
                        context.Fail();
                });
            connection.EnqueueSend(package.AsByteArray());
            connection.Close("OK");
            return true;
        }
        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;
            context.Client.CreateTcpConnection(
                    context,
                    connectionEstablished: conn =>
                    {
                        context.Log.Info("[{0}, L{1}]: Starting transaction...", conn.RemoteEndPoint, conn.LocalEndPoint);
                        sw.Start();
                        
                        var tranStart = new TcpClientMessageDto.TransactionStart(eventStreamId, expectedVersion, false);
                        var package = new TcpPackage(TcpCommand.TransactionStart, Guid.NewGuid(), 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<TcpClientMessageDto.TransactionStartCompleted>();
                                if (dto.Result != TcpClientMessageDto.OperationResult.Success)
                                {
                                    var msg = string.Format("Error while starting transaction: {0} ({1}).", dto.Message, dto.Result);
                                    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 TcpClientMessageDto.TransactionWrite(
                                            transactionId,
                                            new[] 
                                            { 
                                                new TcpClientMessageDto.NewEvent(Guid.NewGuid().ToByteArray() ,
                                                                                 "TakeSomeSpaceEvent",
                                                                                 0,0,
                                                                                 Common.Utils.Helper.UTF8NoBom.GetBytes(Guid.NewGuid().ToString()),
                                                                                 Common.Utils.Helper.UTF8NoBom.GetBytes(Guid.NewGuid().ToString()))
                                            },
                                            false);
                                        var package = new TcpPackage(TcpCommand.TransactionWrite, Guid.NewGuid(), 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<TcpClientMessageDto.TransactionWriteCompleted>();
                                if (dto.Result != TcpClientMessageDto.OperationResult.Success)
                                {
                                    var msg = string.Format("Error while writing transactional event: {0} ({1}).", dto.Message, dto.Result);
                                    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 TcpClientMessageDto.TransactionCommit(transactionId, false);
                                        var package = new TcpPackage(TcpCommand.TransactionCommit, Guid.NewGuid(), 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<TcpClientMessageDto.TransactionCommitCompleted>();
                                if (dto.Result != TcpClientMessageDto.OperationResult.Success)
                                {
                                    var msg = string.Format("Error while committing transaction: {0} ({1}).", dto.Message, dto.Result);
                                    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) => context.Fail(reason: "Connection was closed prematurely."));
            context.WaitForCompletion();
            return true;
        }
        private void ReadFlood(CommandProcessorContext context, string eventStreamId, int clientsCnt, long requestsCnt)
        {
            context.IsAsync();

            var clients = new List<TcpTypedConnection<byte[]>>();
            var threads = new List<Thread>();
            var autoResetEvent = new AutoResetEvent(false);
            var sw2 = new Stopwatch();

            long all = 0;

            for (int i = 0; i < clientsCnt; i++)
            {
                var count = requestsCnt / clientsCnt + ((i == clientsCnt - 1) ? requestsCnt % clientsCnt : 0);

                int sent = 0;
                int received = 0;

                var client = context.Client.CreateTcpConnection(
                    context,
                    (conn, pkg) =>
                    {
                        Interlocked.Increment(ref received);

                        var localAll = Interlocked.Increment(ref all);
                        if (localAll % 1000 == 0) Console.Write(".");
                        if (localAll % 100000 == 0)
                        {
                            var elapsed = sw2.Elapsed;
                            sw2.Restart();
                            context.Log.Trace("\nDONE TOTAL {0} READS IN {1} ({2:0.0}/s).",
                                              localAll,
                                              elapsed,
                                              1000.0*100000/elapsed.TotalMilliseconds);
                        }
                        if (localAll == requestsCnt)
                            autoResetEvent.Set();
                    },
                    connectionClosed: (conn, err) =>
                    {
                        if (all < requestsCnt)
                            context.Fail(null, "Socket was closed, but not all requests were completed.");
                        else
                            context.Success();
                    });

                client.ConnectionClosed += (_, __) => context.Log.Debug("READS sent: {0}, received: {1}", sent, received);
                clients.Add(client);

                threads.Add(new Thread(() => 
                {
                    for (int j = 0; j < count; ++j)
                    {
                        var read = new ClientMessageDto.ReadEvent(Guid.NewGuid(), eventStreamId, 0);
                        var package = new TcpPackage(TcpCommand.ReadEvent, read.Serialize());
                        client.EnqueueSend(package.AsByteArray());
                        
                        Interlocked.Increment(ref sent);
                        while (sent - received > context.Client.Options.ReadWindow)
                            Thread.Sleep(1);
                    }
                }));
            }

            var sw = Stopwatch.StartNew();
            sw2.Start();
            foreach (var thread in threads)
            {
                thread.IsBackground = true;
                thread.Start();
            }

            autoResetEvent.WaitOne();
            sw.Stop();

            foreach (var client in clients)
            {
                client.Close();
            }

            context.Log.Info("Completed. READS done: {0}.", all);

            var reqPerSec = (requestsCnt + 0.0)/sw.ElapsedMilliseconds*1000;
            context.Log.Info("{0} requests completed in {1}ms ({2:0.00} reqs per sec).",
                             requestsCnt,
                             sw.ElapsedMilliseconds,
                             reqPerSec);

            PerfUtils.LogData(
                        Keyword,
                            PerfUtils.Row(PerfUtils.Col("clientsCnt", clientsCnt),
                                 PerfUtils.Col("requestsCnt", requestsCnt),
                                 PerfUtils.Col("ElapsedMilliseconds", sw.ElapsedMilliseconds)),
                        PerfUtils.Row(PerfUtils.Col("readsCnt", all))
            );

            PerfUtils.LogTeamCityGraphData(string.Format("{0}-{1}-{2}-reqPerSec", Keyword, clientsCnt, requestsCnt),
                        (int)reqPerSec);
         
            context.Success();
        }
        private void Flood(CommandProcessorContext context, 
                           string eventStreamId, 
                           int clientsCnt, 
                           int minPerSecond, 
                           int maxPerSecond, 
                           int runTimeMinutes)
        {
            context.IsAsync();

            var clients = new List<TcpTypedConnection<byte[]>>();
            var threads = new List<Thread>();
            var doneEvent = new ManualResetEvent(false);
            var done = false;

            var succ = 0;
            var fail = 0;

            var requestsCnt = 0;

            int sent = 0;
            int received = 0;

            var watchLockRoot = new object();
            var sw = Stopwatch.StartNew();
            for (int i = 0; i < clientsCnt; i++)
            {
                var esId = eventStreamId ?? "Stream-" + Thread.CurrentThread.ManagedThreadId % 3;

                var client = context.Client.CreateTcpConnection(
                    context,
                    (conn, pkg) =>
                    {
                        if (pkg.Command != TcpCommand.WriteEventsCompleted)
                        {
                            context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                            return;
                        }

                        var dto = pkg.Data.Deserialize<TcpClientMessageDto.WriteEventsCompleted>();
                        if (dto.Result == TcpClientMessageDto.OperationResult.Success)
                        {
                            var succDone = Interlocked.Increment(ref succ);
                            if (succDone%maxPerSecond == 0)
                                Console.Write(".");

                            Interlocked.Increment(ref requestsCnt);
                        }
                        else
                            Interlocked.Increment(ref fail);

                        Interlocked.Increment(ref received);
                    },
                    connectionClosed: (conn, err) =>
                    {
                        if (!done)
                            context.Fail(reason: "Socket was closed, but not all requests were completed.");
                        else
                            context.Success();
                    });
                clients.Add(client);

                threads.Add(new Thread(() =>
                {
                    var sentCount = 0;
                    var sleepTime = 0;

                    var dataSizeCoefficient = 1;
                    var currentMinute = -1;

                    while (true)
                    {
                        TimeSpan elapsed;
                        lock (watchLockRoot)
                            elapsed = sw.Elapsed;

                        if (elapsed.TotalMinutes > runTimeMinutes)
                        {
                            done = true;
                            doneEvent.Set();
                            break;
                        }

                        if (sentCount == 0)
                        {
                            int elapsedMinutesInt = (int)elapsed.TotalMinutes;
                            lock (_randomLockRoot)
                            {
                                sentCount = minPerSecond == maxPerSecond 
                                            ? maxPerSecond : _random.Next(minPerSecond, maxPerSecond);
                                dataSizeCoefficient = _random.Next(8, 256);
                            }

                            if (currentMinute != elapsedMinutesInt)
                            {
                                currentMinute = elapsedMinutesInt;
                                context.Log.Info("\nElapsed {0} of {1} minutes, sent {2}; next block coef. {3}",
                                                 elapsedMinutesInt,
                                                 runTimeMinutes,
                                                 sent,
                                                 dataSizeCoefficient);
                            }

                            sleepTime = 1000 / sentCount;
                        }

                        var dataSize = dataSizeCoefficient * 8;
                        var write = new TcpClientMessageDto.WriteEvents(
                            esId,
                            ExpectedVersion.Any,
                            new[]
                            {
                                new TcpClientMessageDto.NewEvent(
                                    Guid.NewGuid().ToByteArray(),
                                    "TakeSomeSpaceEvent",
                                    0,0,
                                    Helper.UTF8NoBom.GetBytes("DATA" + dataSize.ToString(" 00000 ") + new string('*', dataSize)),
                                    Helper.UTF8NoBom.GetBytes("METADATA" + new string('$', 100)))
                            },
                            false);
                        var package = new TcpPackage(TcpCommand.WriteEvents, Guid.NewGuid(), write.Serialize());
                        client.EnqueueSend(package.AsByteArray());

                        Interlocked.Increment(ref sent);

                        Thread.Sleep(sleepTime);
                        sentCount -= 1;

                        while (sent - received > context.Client.Options.WriteWindow/clientsCnt)
                        {
                            Thread.Sleep(1);
                        }
                    }
                }));
            }

            foreach (var thread in threads)
            {
                thread.IsBackground = true;
                thread.Start();
            }

            doneEvent.WaitOne();
            sw.Stop();

            foreach (var client in clients)
            {
                client.Close();
            }

            context.Log.Info("Completed. Successes: {0}, failures: {1}", succ, fail);
            var reqPerSec = (requestsCnt + 0.0)/sw.ElapsedMilliseconds*1000;
            context.Log.Info("{0} requests completed in {1}ms ({2:0.00} reqs per sec).",
                             requestsCnt,
                             sw.ElapsedMilliseconds,
                             reqPerSec);

            PerfUtils.LogData(
                    Keyword,
                    PerfUtils.Row(PerfUtils.Col("clientsCnt", clientsCnt),
                         PerfUtils.Col("requestsCnt", requestsCnt),
                         PerfUtils.Col("ElapsedMilliseconds", sw.ElapsedMilliseconds)),
                    PerfUtils.Row(PerfUtils.Col("successes", succ), PerfUtils.Col("failures", fail))
            );

            PerfUtils.LogTeamCityGraphData(string.Format("{0}-{1}-{2}-reqPerSec", Keyword, clientsCnt, requestsCnt),
                        (int)reqPerSec);

            PerfUtils.LogTeamCityGraphData(
                string.Format("{0}-{1}-{2}-failureSuccessRate", Keyword, clientsCnt, requestsCnt),
                100*fail/(fail + succ));

            context.Success();
        }
Exemple #8
0
        public bool Execute(CommandProcessorContext context, string[] args)
        {
            var eventStreamId = "test-stream";
            var fromNumber = 0;

            if (args.Length > 0)
            {
                if (args.Length > 2)
                    return false;

                eventStreamId = args[0];

                if (args.Length == 2)
                    fromNumber = int.Parse(args[1]);
            }

            context.IsAsync();

            var readDto = new ClientMessageDto.ReadEvent(Guid.NewGuid(), eventStreamId, fromNumber);
            var package = new TcpPackage(TcpCommand.ReadEvent, readDto.Serialize());

            var sw = new Stopwatch();

            context.Client.CreateTcpConnection(
                context,
                connectionEstablished: conn =>
                {
                    context.Log.Info("[{0}]: Reading...", conn.EffectiveEndPoint);
                    sw.Start();
                    conn.EnqueueSend(package.AsByteArray());
                },
                handlePackage: (conn, pkg) =>
                {
                    if (pkg.Command != TcpCommand.ReadEventCompleted)
                    {
                        context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                        return;
                    }

                    sw.Stop();

                    var dto = pkg.Data.Deserialize<ClientMessageDto.ReadEventCompleted>();

                    context.Log.Info("READ events from <{0}>:\n\n"
                                     + "\tCorrelationId: {1}\n"
                                     + "\tEventStreamId: {2}\n"
                                     + "\tEventNumber:   {3}\n"
                                     + "\tReadResult:    {4}\n"
                                     + "\tEventType:     {5}\n"
                                     + "\tData:          {6}\n"
                                     + "\tMetadata:      {7}\n",
                                     eventStreamId,
                                     dto.CorrelationId,
                                     dto.EventStreamId,
                                     dto.EventNumber,
                                     (SingleReadResult) dto.Result,
                                     dto.EventType,
                                     Encoding.UTF8.GetString(dto.Data ?? new byte[0]),
                                     Encoding.UTF8.GetString(dto.Metadata ?? new byte[0]));

                    context.Log.Info("Read request took: {0}.", sw.Elapsed);

                    PerfUtils.LogTeamCityGraphData(string.Format("{0}-latency-ms", Keyword), (int)sw.ElapsedMilliseconds);

                    conn.Close();
                    context.Success();
                },
                connectionClosed: (connection, error) =>
                {
                    if (error == SocketError.Success)
                        context.Success();
                    else
                        context.Fail();
                });

            context.WaitForCompletion();
            return true;
        }
        private void PingFlood(CommandProcessorContext context, int clientsCnt, long requestsCnt)
        {
            context.IsAsync();

            var doneEvent = new ManualResetEventSlim(false);
            var clients = new List<TcpTypedConnection<byte[]>>();
            var threads = new List<Thread>();
            long all = 0;

            for (int i = 0; i < clientsCnt; i++)
            {
                var count = requestsCnt / clientsCnt + ((i == clientsCnt - 1) ? requestsCnt % clientsCnt : 0);
                long received = 0;
                long sent = 0;
                var client = context.Client.CreateTcpConnection(
                    context,
                    (conn, msg) =>
                    {
                        Interlocked.Increment(ref received);
                        var pongs = Interlocked.Increment(ref all);
                        if (pongs % 10000 == 0) Console.Write('.');
                        if (pongs == requestsCnt)
                        {
                            context.Success();
                            doneEvent.Set();
                        }
                    },
                    connectionClosed: (conn, err) => context.Fail(reason: "Connection was closed prematurely."));
                clients.Add(client);

                threads.Add(new Thread(() =>
                {
                    for (int j = 0; j < count; ++j)
                    {
                        var package = new TcpPackage(TcpCommand.Ping, Guid.NewGuid(), Payload);
                        client.EnqueueSend(package.AsByteArray());
                       
                        var localSent = Interlocked.Increment(ref sent);
                        while (localSent - Interlocked.Read(ref received) > context.Client.Options.PingWindow/clientsCnt)
                        {
                            Thread.Sleep(1);
                        }
                    }
                }) { IsBackground = true });
            }

            var sw = Stopwatch.StartNew();
            threads.ForEach(thread => thread.Start());
            doneEvent.Wait();
            sw.Stop();
            clients.ForEach(client => client.Close());

            var reqPerSec = (all + 0.0)/sw.ElapsedMilliseconds*1000;
            context.Log.Info("{0} requests completed in {1}ms ({2:0.00} reqs per sec).", all, sw.ElapsedMilliseconds, reqPerSec);
            PerfUtils.LogData(Keyword,
                              PerfUtils.Row(PerfUtils.Col("clientsCnt", clientsCnt),
                                            PerfUtils.Col("requestsCnt", requestsCnt),
                                            PerfUtils.Col("ElapsedMilliseconds", sw.ElapsedMilliseconds)));
            PerfUtils.LogTeamCityGraphData(string.Format("{0}-{1}-{2}-reqPerSec", Keyword, clientsCnt, requestsCnt), (int)reqPerSec);

            if (Interlocked.Read(ref all) == requestsCnt)
                context.Success();
            else
                context.Fail();
        }
Exemple #10
0
        public Connection CreateTcpConnection(CommandProcessorContext context, 
                                              Action<Connection, TcpPackage> handlePackage,
                                              Action<Connection> connectionEstablished = null,
                                              Action<Connection, SocketError> connectionClosed = null,
                                              bool failContextOnError = true,
                                              IPEndPoint tcpEndPoint = null)
        {
            var connectionCreatedEvent = new ManualResetEventSlim(false);
            Connection typedConnection = null;

            var connection = _connector.ConnectTo(
                Guid.NewGuid(),
                tcpEndPoint ?? TcpEndpoint,
                conn =>
                {
                    // we execute callback on ThreadPool because on FreeBSD it can be called synchronously
                    // causing deadlock
                    ThreadPool.QueueUserWorkItem(_ => 
                    {
                        if (!InteractiveMode)
                            Log.Info("Connected to [{0}, L{1}].", conn.RemoteEndPoint, conn.LocalEndPoint);
                        if (connectionEstablished != null)
                        {
                            if (!connectionCreatedEvent.Wait(10000))
                                throw new Exception("TcpTypedConnection creation took too long!");
                            connectionEstablished(typedConnection);
                        }
                    });
                },
                (conn, error) =>
                {
                    var message = string.Format("Connection to [{0}, L{1}] failed. Error: {2}.",
                                                conn.RemoteEndPoint, conn.LocalEndPoint, error);
                    Log.Error(message);

                    if (connectionClosed != null)
                        connectionClosed(null, error);

                    if (failContextOnError)
                        context.Fail(reason: string.Format("Socket connection failed with error {0}.", error));
                },
                verbose: !InteractiveMode);

            typedConnection = new Connection(connection, new RawMessageFormatter(_bufferManager), new LengthPrefixMessageFramer());
            typedConnection.ConnectionClosed +=
                (conn, error) =>
                {
                    if (!InteractiveMode || error != SocketError.Success)
                    {
                        Log.Info("Connection [{0}, L{1}] was closed {2}",
                                 conn.RemoteEndPoint, conn.LocalEndPoint,
                                 error == SocketError.Success ? "cleanly." : "with error: " + error + ".");
                    }

                    if (connectionClosed != null)
                        connectionClosed(conn, error);
                    else
                        Log.Info("connectionClosed callback was null");
                };
            connectionCreatedEvent.Set();

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

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

                        handlePackage(conn, package);
                    }
                    catch (Exception ex)
                    {
                        Log.InfoException(ex,
                                          "[{0}, L{1}] ERROR for {2}. Connection will be closed.",
                                          conn.RemoteEndPoint, conn.LocalEndPoint,
                                          validPackage ? package.Command as object : "<invalid package>");
                        conn.Close(ex.Message);

                        if (failContextOnError)
                            context.Fail(ex);
                    }
                });

            return typedConnection;
        }
        private void PingFloodWaiting(CommandProcessorContext context, int clientsCnt, int requestsCnt)
        {
            context.IsAsync();

            var clients = new List<TcpTypedConnection<byte[]>>();
            var threads = new List<Thread>();
            var doneEvent = new AutoResetEvent(false);
            var clientsDone = 0;

            for (int i = 0; i < clientsCnt; i++)
            {
                var autoResetEvent = new AutoResetEvent(false);
                var client = context.Client.CreateTcpConnection(
                    context,
                    (_, __) => autoResetEvent.Set(),
                    connectionClosed: (conn, err) =>
                    {
                        if (clientsDone < clientsCnt)
                            context.Fail(null, "Socket was closed, but not all requests were completed.");
                        else
                            context.Success();
                    });
                clients.Add(client);
                var count = requestsCnt / clientsCnt + ((i == clientsCnt - 1) ? requestsCnt % clientsCnt : 0);

                threads.Add(new Thread(() =>
                {
                    for (int j = 0; j < count; ++j)
                    {
                        //TODO GFY ping needs correlation id
                        var package = new TcpPackage(TcpCommand.Ping, Guid.NewGuid(), null);
                        client.EnqueueSend(package.AsByteArray());

                        autoResetEvent.WaitOne();
                    }
                    if (Interlocked.Increment(ref clientsDone) == clientsCnt)
                        doneEvent.Set();
                }));
            }

            var sw = Stopwatch.StartNew();
            foreach (var thread in threads)
            {
                thread.IsBackground = true;
                thread.Start();
            }
            
            doneEvent.WaitOne();
            sw.Stop();

            clients.ForEach(x => x.Close());

            var reqPerSec = (requestsCnt + 0.0)/sw.ElapsedMilliseconds*1000;
            context.Log.Info("{0} requests completed in {1}ms ({2:0.00} reqs per sec).",
                             requestsCnt,
                             sw.ElapsedMilliseconds,
                             reqPerSec);

            PerfUtils.LogData(
                    Keyword,
                    PerfUtils.Row(PerfUtils.Col("clientsCnt", clientsCnt),
                            PerfUtils.Col("requestsCnt", requestsCnt),
                            PerfUtils.Col("ElapsedMilliseconds", sw.ElapsedMilliseconds))
                );

            PerfUtils.LogTeamCityGraphData(string.Format("{0}-{1}-{2}-reqPerSec", Keyword, clientsCnt, requestsCnt),
                                           (int) reqPerSec);

            PerfUtils.LogTeamCityGraphData(string.Format("{0}-latency-ms", Keyword),
                                           (int) (sw.ElapsedMilliseconds/requestsCnt));

            context.Success();
        }
Exemple #12
0
        public bool Execute(CommandProcessorContext context, string[] args)
        {
            var eventStreamId = "test-stream";
            var expectedVersion = ExpectedVersion.Any;

            if (args.Length > 0)
            {
                if (args.Length > 2)
                    return false;

                eventStreamId = args[0];

                if (args.Length == 2)
                    expectedVersion = args[1].Trim().ToUpper() == "ANY" ? ExpectedVersion.Any : int.Parse(args[1]);
            }

            context.IsAsync();

            var corrid = Guid.NewGuid();
            var deleteDto = new ClientMessageDto.DeleteStream(eventStreamId, expectedVersion);
            var package = new TcpPackage(TcpCommand.DeleteStream, corrid, deleteDto.Serialize());

            var sw = new Stopwatch();
            var done = false;

            context.Client.CreateTcpConnection(
                context,
                connectionEstablished: conn =>
                {
                    context.Log.Info("[{0}]: Trying to delete event stream '{1}'...", conn.EffectiveEndPoint, eventStreamId);
                    sw.Start();
                    conn.EnqueueSend(package.AsByteArray());
                },
                handlePackage: (conn, pkg) =>
                {
                    sw.Stop();

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

                    var dto = pkg.Data.Deserialize<ClientMessageDto.DeleteStreamCompleted>();

                    if (dto.ErrorCode == (int)OperationErrorCode.Success)
                        context.Log.Info("DELETED event stream {0}.", eventStreamId);
                    else
                        context.Log.Info("DELETION FAILED for event stream {0}: {1} ({2}).",
                                         eventStreamId,
                                         dto.Error,
                                         (OperationErrorCode) dto.ErrorCode);

                    context.Log.Info("Delete request took: {0}.", sw.Elapsed);

                    PerfUtils.LogTeamCityGraphData(string.Format("{0}-latency-ms", Keyword), (int)sw.ElapsedMilliseconds);

                    done = true;

                    conn.Close();
                    context.Success();
                },
                connectionClosed:(connection, error) =>
                {
                    if (done && error == SocketError.Success)
                        context.Success();
                    else
                        context.Fail();
                });

            context.WaitForCompletion();
            return true;
        }
        private void WriteFlood(CommandProcessorContext context, int clientsCnt, long requestsCnt, int streamsCnt, int size)
        {
            context.IsAsync();

            var doneEvent = new ManualResetEventSlim(false);
            var clients = new List<TcpTypedConnection<byte[]>>();
            var threads = new List<Thread>();

            long succ = 0;
            long fail = 0;
            long prepTimeout = 0;
            long commitTimeout = 0;
            long forwardTimeout = 0;
            long wrongExpVersion = 0;
            long streamDeleted = 0;
            long all = 0;

            var streams = Enumerable.Range(0, streamsCnt).Select(x => Guid.NewGuid().ToString()).ToArray();
            //var streams = Enumerable.Range(0, streamsCnt).Select(x => string.Format("stream-{0}", x)).ToArray();
            var sw2 = new Stopwatch();
            for (int i = 0; i < clientsCnt; i++)
            {
                var count = requestsCnt / clientsCnt + ((i == clientsCnt - 1) ? requestsCnt % clientsCnt : 0);
                long sent = 0;
                long received = 0;
                var rnd = new Random();
                var client = context.Client.CreateTcpConnection(
                    context,
                    (conn, pkg) =>
                    {
                        if (pkg.Command != TcpCommand.WriteEventsCompleted)
                        {
                            context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                            return;
                        }

                        var dto = pkg.Data.Deserialize<TcpClientMessageDto.WriteEventsCompleted>();
                        _monitor.EndOperation(pkg.CorrelationId);
                        switch(dto.Result)
                        {
                            case TcpClientMessageDto.OperationResult.Success:
                                if (Interlocked.Increment(ref succ) % 1000 == 0) Console.Write('.');
                                break;
                            case TcpClientMessageDto.OperationResult.PrepareTimeout:
                                Interlocked.Increment(ref prepTimeout);
                                break;
                            case TcpClientMessageDto.OperationResult.CommitTimeout:
                                Interlocked.Increment(ref commitTimeout);
                                break;
                            case TcpClientMessageDto.OperationResult.ForwardTimeout:
                                Interlocked.Increment(ref forwardTimeout);
                                break;
                            case TcpClientMessageDto.OperationResult.WrongExpectedVersion:
                                Interlocked.Increment(ref wrongExpVersion);
                                break;
                            case TcpClientMessageDto.OperationResult.StreamDeleted:
                                Interlocked.Increment(ref streamDeleted);
                                break;
                            default:
                                throw new ArgumentOutOfRangeException();
                        }
                        if (dto.Result != TcpClientMessageDto.OperationResult.Success)
                            if (Interlocked.Increment(ref fail)%1000 == 0)
                                Console.Write('#');
                        Interlocked.Increment(ref received);
                        var localAll = Interlocked.Increment(ref all);
                        if (localAll % 100000 == 0)
                        {
                            var elapsed = sw2.Elapsed;
                            sw2.Restart();
                            context.Log.Trace("\nDONE TOTAL {0} WRITES IN {1} ({2:0.0}/s) [S:{3}, F:{4} (WEV:{5}, P:{6}, C:{7}, F:{8}, D:{9})].",
                                              localAll, elapsed, 1000.0*100000/elapsed.TotalMilliseconds,
                                              succ, fail,
                                              wrongExpVersion, prepTimeout, commitTimeout, forwardTimeout, streamDeleted);
                        }
                        if (localAll == requestsCnt)
                        {
                            context.Success();
                            doneEvent.Set();
                        }
                    },
                    connectionClosed: (conn, err) => context.Fail(reason: "Connection was closed prematurely."));
                clients.Add(client);

                threads.Add(new Thread(() =>
                {
                    for (int j = 0; j < count; ++j)
                    {
                        var corrid = Guid.NewGuid();
                        var write = new TcpClientMessageDto.WriteEvents(
                            streams[rnd.Next(streamsCnt)],
                            ExpectedVersion.Any,
                            new[]
                            {
                                new TcpClientMessageDto.NewEvent(Guid.NewGuid().ToByteArray(),
                                                                 "TakeSomeSpaceEvent",
                                                                 1,0,
                                                                 Common.Utils.Helper.UTF8NoBom.GetBytes("{ \"DATA\" : \"" + new string('*', size) + "\"}"),
                                                                 Common.Utils.Helper.UTF8NoBom.GetBytes("{ \"METADATA\" : \"" + new string('$', 100) + "\"}"))
                            },
                            false);
                        var package = new TcpPackage(TcpCommand.WriteEvents, corrid, write.Serialize());
                        _monitor.StartOperation(corrid);
                        client.EnqueueSend(package.AsByteArray());

                        var localSent = Interlocked.Increment(ref sent);
                        while (localSent - Interlocked.Read(ref received) > context.Client.Options.WriteWindow/clientsCnt)
                        {
                            Thread.Sleep(1);
                        }
                    }
                }) { IsBackground = true });
            }

            var sw = Stopwatch.StartNew();
            sw2.Start();
            threads.ForEach(thread => thread.Start());
            doneEvent.Wait();
            sw.Stop();
            clients.ForEach(client => client.Close());

            context.Log.Info("Completed. Successes: {0}, failures: {1} (WRONG VERSION: {2}, P: {3}, C: {4}, F: {5}, D: {6})",
                             succ, fail,
                             wrongExpVersion, prepTimeout, commitTimeout, forwardTimeout, streamDeleted);

            var reqPerSec = (all + 0.0) / sw.ElapsedMilliseconds * 1000;
            context.Log.Info("{0} requests completed in {1}ms ({2:0.00} reqs per sec).", all, sw.ElapsedMilliseconds, reqPerSec);

            PerfUtils.LogData(
                Keyword,
                PerfUtils.Row(PerfUtils.Col("clientsCnt", clientsCnt),
                              PerfUtils.Col("requestsCnt", requestsCnt),
                              PerfUtils.Col("ElapsedMilliseconds", sw.ElapsedMilliseconds)),
                PerfUtils.Row(PerfUtils.Col("successes", succ), PerfUtils.Col("failures", fail)));

            var failuresRate = (int) (100 * fail / (fail + succ));
            PerfUtils.LogTeamCityGraphData(string.Format("{0}-{1}-{2}-reqPerSec", Keyword, clientsCnt, requestsCnt), (int)reqPerSec);
            PerfUtils.LogTeamCityGraphData(string.Format("{0}-{1}-{2}-failureSuccessRate", Keyword, clientsCnt, requestsCnt), failuresRate);
            PerfUtils.LogTeamCityGraphData(string.Format("{0}-c{1}-r{2}-st{3}-s{4}-reqPerSec", Keyword, clientsCnt, requestsCnt, streamsCnt, size), (int)reqPerSec);
            PerfUtils.LogTeamCityGraphData(string.Format("{0}-c{1}-r{2}-st{3}-s{4}-failureSuccessRate", Keyword, clientsCnt, requestsCnt, streamsCnt, size), failuresRate);
            _monitor.GetMeasurementDetails();
            if (Interlocked.Read(ref succ) != requestsCnt)
                context.Fail(reason: "There were errors or not all requests completed.");
            else
                context.Success();
        }
        public bool Execute(CommandProcessorContext context, string[] args)
        {
            var eventStreamId = "test-stream";
            string metadata = null;

            if (args.Length > 0)
            {
                if (args.Length > 2)
                    return false;
                eventStreamId = args[0];
                if (args.Length > 1)
                    metadata = args[1];
            }

            context.IsAsync();
            var createStreamDto = new TcpClientMessageDto.CreateStream(
                    eventStreamId,
                    Guid.NewGuid().ToByteArray(), 
                    Encoding.UTF8.GetBytes(metadata ?? string.Format("{{\"StreamName\": \"{0}\"}}", eventStreamId)),
                    true,
                    metadata == null);
            var package = new TcpPackage(TcpCommand.CreateStream, Guid.NewGuid(), createStreamDto.Serialize());

            var sw = new Stopwatch();

            context.Client.CreateTcpConnection(
                    context,
                    connectionEstablished: conn =>
                    {
                        context.Log.Info("[{0}]: Trying to create stream '{1}'...", conn.EffectiveEndPoint, eventStreamId);
                        sw.Start();
                        conn.EnqueueSend(package.AsByteArray());
                    },
                    handlePackage: (conn, pkg) =>
                    {
                        if (pkg.Command != TcpCommand.CreateStreamCompleted)
                        {
                            context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                            return;
                        }

                        sw.Stop();

                        var dto = pkg.Data.Deserialize<TcpClientMessageDto.CreateStreamCompleted>();
                        if (dto.Result == TcpClientMessageDto.OperationResult.Success)
                        {
                            context.Log.Info("Successfully created stream '{0}'.", eventStreamId);
                            PerfUtils.LogTeamCityGraphData(string.Format("{0}-latency-ms", Keyword), (int)sw.ElapsedMilliseconds);
                        }
                        else
                        {
                            context.Log.Info("Error while creating stream {0}: {1} ({2}).", eventStreamId, dto.Message, dto.Result);
                        }

                        context.Log.Info("Create stream request took: {0}.", sw.Elapsed);
                        conn.Close();
                        context.Success();
                    },
                    connectionClosed: (connection, error) =>
                    {
                        if (error == SocketError.Success)
                            context.Success();
                        else
                            context.Fail();
                    });

            context.WaitForCompletion();
            return true;
        }
        private void PingFlood(CommandProcessorContext context, int clientsCnt, int requestsCnt)
        {
            context.IsAsync();

            var autoResetEvent = new AutoResetEvent(false);
            var clients = new List<TcpTypedConnection<byte[]>>();
            var threads = new List<Thread>();
            var all = 0;

            for (int i = 0; i < clientsCnt; i++)
            {
                var count = requestsCnt / clientsCnt + ((i == clientsCnt - 1) ? requestsCnt % clientsCnt : 0);
                int sent = 0;
                int received = 0;

                var client = context.Client.CreateTcpConnection(
                    context,
                    (conn, msg) =>
                    {
                        Interlocked.Increment(ref received);
                        var pongs = Interlocked.Increment(ref all);
                        if (pongs % 10000 == 0)
                            Console.Write('.');
                        if (pongs == requestsCnt)
                            autoResetEvent.Set();
                    },
                    connectionClosed: (conn, err) =>
                    {
                        if (all < requestsCnt)
                            context.Fail(null, "Socket was closed, but not all requests were completed.");
                        else
                            context.Success();
                    });

                clients.Add(client);

                threads.Add(new Thread(() =>
                {
                    for (int j = 0; j < count; ++j)
                    {
                        var package = new TcpPackage(TcpCommand.Ping, Payload);
                        client.EnqueueSend(package.AsByteArray());
                        Interlocked.Increment(ref sent);

                        while (sent - received > context.Client.Options.PingWindow)
                            Thread.Sleep(1);
                    }
                }));
            }

            var sw = Stopwatch.StartNew();
            foreach (var thread in threads)
            {
                thread.IsBackground = true;
                thread.Start();
            }

            autoResetEvent.WaitOne();
            sw.Stop();

            foreach (var client in clients)
            {
                client.Close();
            }

            var reqPerSec = (requestsCnt + 0.0)/sw.ElapsedMilliseconds*1000;
            context.Log.Info("{0} requests completed in {1}ms ({2:0.00} reqs per sec).",
                             requestsCnt,
                             sw.ElapsedMilliseconds,
                             reqPerSec);

            PerfUtils.LogData(
                    Keyword,
                    PerfUtils.Row(PerfUtils.Col("clientsCnt", clientsCnt),
                            PerfUtils.Col("requestsCnt", requestsCnt),
                            PerfUtils.Col("ElapsedMilliseconds", sw.ElapsedMilliseconds))
                );

            PerfUtils.LogTeamCityGraphData(string.Format("{0}-{1}-{2}-reqPerSec", Keyword, clientsCnt, requestsCnt),
                                    (int)reqPerSec);

            context.Success();
        }
Exemple #16
0
        public Connection CreateTcpConnection(CommandProcessorContext context, 
                                              Action<Connection, TcpPackage> handlePackage,
                                              Action<Connection> connectionEstablished = null,
                                              Action<Connection, SocketError> connectionClosed = null,
                                              bool failContextOnError = true)
        {
            var connectionCreatedEvent = new AutoResetEvent(false);
            Connection typedConnection = null;

            var connection = _connector.ConnectTo(
                TcpEndpoint,
                conn =>
                {
                    Log.Info("Connected to [{0}].", conn.EffectiveEndPoint);
                    if (connectionEstablished != null)
                    {
                        connectionCreatedEvent.WaitOne(500);
                        connectionEstablished(typedConnection);
                    }
                },
                (conn, error) =>
                {
                    var message = string.Format("Connection to [{0}] failed. Error: {1}.",
                                                conn.EffectiveEndPoint,
                                                error);
                    Log.Error(message);

                    if (connectionClosed != null)
                        connectionClosed(null, error);

                    if (failContextOnError)
                        context.Fail(reason: string.Format("Socket connection failed with error {0}.", error));
                });

            typedConnection = new Connection(connection, new RawMessageFormatter(_bufferManager), new LengthPrefixMessageFramer());
            typedConnection.ConnectionClosed +=
                (conn, error) =>
                {
                    Log.Info("Connection [{0}] was closed {1}",
                                conn.EffectiveEndPoint,
                                error == SocketError.Success ? "cleanly." : "with error: " + error + ".");

                    if (connectionClosed != null)
                        connectionClosed(conn, error);
                    else
                        Log.Info("connectionClosed callback was null");
                };
            connectionCreatedEvent.Set();

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

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

                        handlePackage(conn, package);
                    }
                    catch (Exception ex)
                    {
                        Log.InfoException(ex,
                                          "[{0}] ERROR for {1}. Connection will be closed.",
                                          conn.EffectiveEndPoint,
                                          validPackage ? package.Command as object : "<invalid package>");
                        conn.Close();

                        if (failContextOnError)
                            context.Fail(ex);
                    }
                });

            return typedConnection;
        }
        private void ReadFlood(CommandProcessorContext context, string eventStreamId, int clientsCnt, long requestsCnt,
                               bool resolveLinkTos, bool requireMaster)
        {
            context.IsAsync();

            var clients = new List<TcpTypedConnection<byte[]>>();
            var threads = new List<Thread>();
            var doneEvent = new ManualResetEventSlim(false);
            var sw2 = new Stopwatch();
            long succ = 0;
            long fail = 0;
            long all = 0;
            for (int i = 0; i < clientsCnt; i++)
            {
                var count = requestsCnt / clientsCnt + ((i == clientsCnt - 1) ? requestsCnt % clientsCnt : 0);
                long received = 0;
                long sent = 0;
                var client = context.Client.CreateTcpConnection(
                    context,
                    (conn, pkg) =>
                    {
                        if (pkg.Command != TcpCommand.ReadEventCompleted)
                        {
                            context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                            return;
                        }

                        var dto = pkg.Data.Deserialize<TcpClientMessageDto.ReadEventCompleted>();
                        _monitor.EndOperation(pkg.CorrelationId);
                        if (dto.Result == TcpClientMessageDto.ReadEventCompleted.ReadEventResult.Success)
                        {
                            if (Interlocked.Increment(ref succ) % 1000 == 0) Console.Write(".");
                        }
                        else
                        {
                            if (Interlocked.Increment(ref fail) % 1000 == 0) Console.Write("#");
                        }

                        Interlocked.Increment(ref received);
                        var localAll = Interlocked.Increment(ref all);
                        if (localAll % 100000 == 0)
                        {
                            var elapsed = sw2.Elapsed;
                            sw2.Restart();
                            context.Log.Trace("\nDONE TOTAL {0} READS IN {1} ({2:0.0}/s).", localAll, elapsed, 1000.0*100000/elapsed.TotalMilliseconds);
                        }
                        if (localAll == requestsCnt)
                        {
                            context.Success();
                            doneEvent.Set();
                        }
                    },
                    connectionClosed: (conn, err) => context.Fail(reason: "Connection was closed prematurely."));
                clients.Add(client);

                threads.Add(new Thread(() => 
                {
                    for (int j = 0; j < count; ++j)
                    {
                        var corrId = Guid.NewGuid();
                        var read = new TcpClientMessageDto.ReadEvent(eventStreamId, 0, resolveLinkTos, requireMaster);
                        var package = new TcpPackage(TcpCommand.ReadEvent, corrId, read.Serialize());
                        _monitor.StartOperation(corrId);
                        client.EnqueueSend(package.AsByteArray());
                        
                        var localSent = Interlocked.Increment(ref sent);
                        while (localSent - Interlocked.Read(ref received) > context.Client.Options.ReadWindow/clientsCnt)
                        {
                            Thread.Sleep(1);
                        }
                    }
                }) { IsBackground = true });
            }

            var sw = Stopwatch.StartNew();
            sw2.Start();
            threads.ForEach(thread => thread.Start());
            doneEvent.Wait();
            sw.Stop();
            clients.ForEach(client => client.Close());

            var reqPerSec = (all + 0.0) / sw.ElapsedMilliseconds * 1000;
            context.Log.Info("Completed. READS succ: {0}, fail: {1}.", Interlocked.Read(ref succ), Interlocked.Read(ref fail));
            context.Log.Info("{0} requests completed in {1}ms ({2:0.00} reqs per sec).", all, sw.ElapsedMilliseconds, reqPerSec);
            _monitor.GetMeasurementDetails();
            PerfUtils.LogData(Keyword,
                              PerfUtils.Row(PerfUtils.Col("clientsCnt", clientsCnt),
                                            PerfUtils.Col("requestsCnt", requestsCnt),
                                            PerfUtils.Col("ElapsedMilliseconds", sw.ElapsedMilliseconds)),
                              PerfUtils.Row(PerfUtils.Col("readsCnt", all)));
            PerfUtils.LogTeamCityGraphData(string.Format("{0}-{1}-{2}-reqPerSec", Keyword, clientsCnt, requestsCnt), (int)reqPerSec);

            if (succ != requestsCnt)
                context.Fail(reason: "There were errors or not all requests completed.");
            else
                context.Success();
        }
        private void WriteFlood(CommandProcessorContext context, int clientsCnt, int requestsCnt)
        {
            context.IsAsync();

            var clients = new List<TcpTypedConnection<byte[]>>();
            var threads = new List<Thread>();
            var autoResetEvent = new AutoResetEvent(false);

            var succ = 0;
            var fail = 0;
            var all = 0;

            for (int i = 0; i < clientsCnt; i++)
            {
                var count = requestsCnt / clientsCnt + ((i == clientsCnt - 1) ? requestsCnt % clientsCnt : 0);

                var autoEvent = new AutoResetEvent(false);
                var eventStreamId = "es" + Guid.NewGuid();
                var received = 0;

                var client = context.Client.CreateTcpConnection(
                    context,
                    (conn, pkg) =>
                    {
                        if (pkg.Command != TcpCommand.WriteEventsCompleted)
                        {
                            context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                            return;
                        }

                        Interlocked.Increment(ref received);

                        var dto = pkg.Data.Deserialize<TcpClientMessageDto.WriteEventsCompleted>();
                        if (dto.Result == TcpClientMessageDto.OperationResult.Success)
                        {
                            if (Interlocked.Increment(ref succ)%1000 == 0)
                                Console.Write(".");
                        }
                        else
                            Interlocked.Increment(ref fail);

                        if (Interlocked.Increment(ref all) == requestsCnt)
                            autoResetEvent.Set();
                        autoEvent.Set();
                    },
                    connectionClosed: (conn, err) =>
                    {
                        if (received < count)
                            context.Fail(null, "Socket was closed, but not all requests were completed.");
                        else
                            context.Success();
                    });
                clients.Add(client);

                threads.Add(new Thread(() =>
                {
                    
                    for (int j = 0; j < count; ++j)
                    {
                        var write = new TcpClientMessageDto.WriteEvents(
                            eventStreamId,
                            ExpectedVersion.Any,
                            new[]
                            {
                                new TcpClientMessageDto.NewEvent(Guid.NewGuid().ToByteArray(),
                                                                 "TakeSomeSpaceEvent",
                                                                 false,
                                                                 Encoding.UTF8.GetBytes("DATA" + new string('*', 256)),
                                                                 Encoding.UTF8.GetBytes("METADATA" + new string('$', 100)))
                            },
                            true);
                        var package = new TcpPackage(TcpCommand.WriteEvents, Guid.NewGuid(), write.Serialize());
                        client.EnqueueSend(package.AsByteArray());
                        autoEvent.WaitOne();
                    }
                }));
            }

            var sw = Stopwatch.StartNew();
            foreach (var thread in threads)
            {
                thread.IsBackground = true;
                thread.Start();
            }
            autoResetEvent.WaitOne();
            sw.Stop();

            foreach (var client in clients)
            {
                client.Close();
            }

            context.Log.Info("Completed. Successes: {0}, failures: {1}", succ, fail);

            var reqPerSec = (requestsCnt + 0.0)/sw.ElapsedMilliseconds*1000;
            context.Log.Info("{0} requests completed in {1}ms ({2:0.00} reqs per sec).",
                             all,
                             sw.ElapsedMilliseconds,
                             reqPerSec);

            PerfUtils.LogData(
                        Keyword,
                        PerfUtils.Row(PerfUtils.Col("clientsCnt", clientsCnt),
                             PerfUtils.Col("requestsCnt", requestsCnt),
                             PerfUtils.Col("ElapsedMilliseconds", sw.ElapsedMilliseconds)),
                        PerfUtils.Row(PerfUtils.Col("successes", succ), PerfUtils.Col("failures", fail)));

            PerfUtils.LogTeamCityGraphData(string.Format("{0}-{1}-{2}-reqPerSec", Keyword, clientsCnt, requestsCnt),
                                           (int) reqPerSec);

            PerfUtils.LogTeamCityGraphData(
                string.Format("{0}-{1}-{2}-failureSuccessRate", Keyword, clientsCnt, requestsCnt),
                100 * fail / (fail + succ));

            PerfUtils.LogTeamCityGraphData(string.Format("{0}-latency-ms", Keyword),
                                           (int) (sw.ElapsedMilliseconds/requestsCnt));

            context.Success();
        }
        private void Write(Status status, int writerIdx, CommandProcessorContext context, int requests, ManualResetEventSlim finish)
        {
            TcpTypedConnection<byte[]> connection;
            var iteration = new AutoResetEvent(false);

            var sent = 0;

            var prepareTimeouts = 0;
            var commitTimeouts = 0;
            var forwardTimeouts = 0;
            var wrongExpectedVersion = 0;
            var streamsDeleted = 0;

            var failed = 0;

            var rnd = new Random();

            var streamIdx = -1;
            var head = -1;

            Action<TcpTypedConnection<byte[]>, TcpPackage> packageHandler = (conn, pkg) =>
            {
                var dto = pkg.Data.Deserialize<TcpClientMessageDto.WriteEventsCompleted>();
                switch (dto.Result)
                {
                    case TcpClientMessageDto.OperationResult.Success:
                        lock (_heads)
                        {
                            var currentHead = _heads[streamIdx];
                            Ensure.Equal(currentHead, head, "currentHead");
                            _heads[streamIdx]++;
                        }
                        break;
                    case TcpClientMessageDto.OperationResult.PrepareTimeout:
                        prepareTimeouts++;
                        failed++;
                        break;
                    case TcpClientMessageDto.OperationResult.CommitTimeout:
                        commitTimeouts++;
                        failed++;
                        break;
                    case TcpClientMessageDto.OperationResult.ForwardTimeout:
                        forwardTimeouts++;
                        failed++;
                        break;
                    case TcpClientMessageDto.OperationResult.WrongExpectedVersion:
                        wrongExpectedVersion++;
                        failed++;
                        break;
                    case TcpClientMessageDto.OperationResult.StreamDeleted:
                        streamsDeleted++;
                        failed++;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }

                sent++;
                if (sent % 1000 == 0)
                    status.ReportWritesProgress(writerIdx, sent, prepareTimeouts, commitTimeouts, forwardTimeouts,
                                                wrongExpectedVersion, streamsDeleted, failed, requests);
                if (sent == requests)
                    finish.Set();

                iteration.Set();
            };

            Action<TcpTypedConnection<byte[]>> established = _ => { };
            Action<TcpTypedConnection<byte[]>, SocketError> closed = null;
            closed = (_, __) =>
            {
                Thread.Sleep(TimeSpan.FromSeconds(1));
                connection = context.Client.CreateTcpConnection(context, packageHandler, cn => iteration.Set(), closed, false);
            };

            connection = context.Client.CreateTcpConnection(context, packageHandler, established, closed, false);

            for (var i = 0; i < requests; ++i)
            {
                streamIdx = NextStreamForWriting(rnd, writerIdx);
                lock (_heads)
                {
                    head = _heads[streamIdx];
                }
                var evnt = CreateEvent(_streams[streamIdx], head + 1);
                var write = new TcpClientMessageDto.WriteEvents(
                    _streams[streamIdx],
                    head,
                    new[] 
                    { 
                        new TcpClientMessageDto.NewEvent(evnt.EventId.ToByteArray(), evnt.EventType,evnt.IsJson ? 1 : 0, 0, evnt.Data, evnt.Metadata) 
                    },
                    false);

                var package = new TcpPackage(TcpCommand.WriteEvents, Guid.NewGuid(), write.Serialize());
                connection.EnqueueSend(package.AsByteArray());
                iteration.WaitOne();
            }

            status.ReportWritesProgress(writerIdx, sent, prepareTimeouts, commitTimeouts, forwardTimeouts,
                                        wrongExpectedVersion, streamsDeleted, failed, requests);
            status.FinilizeStatus(writerIdx, failed != sent);
            connection.Close();
        }
        public bool Execute(CommandProcessorContext context, string[] args)
        {
            bool forward = true;
            long commitPos = 0;
            long preparePos = 0;
            bool posOverriden = false;

            if (args.Length > 0)
            {
                if (args.Length != 1 && args.Length != 3)
                    return false;

                if (args[0].ToUpper() == "F")
                    forward = true;
                else if (args[0].ToUpper() == "B")
                    forward = false;
                else
                    return false;

                if (args.Length == 3)
                {
                    posOverriden = true;
                    if (!long.TryParse(args[1], out commitPos) || !long.TryParse(args[2], out preparePos))
                        return false;
                }
            }

            if (!posOverriden)
            {
                commitPos = forward ? 0 : -1;
                preparePos = forward ? 0 : -1;
            }

            context.IsAsync();

            int total = 0;
            var sw = new Stopwatch();

            context.Client.CreateTcpConnection(
                context,
                connectionEstablished: conn =>
                {
                    context.Log.Info("[{0}]: Reading all {0}...", conn.EffectiveEndPoint, forward ? "FORWARD" : "BACKWARD");
                    sw.Start();

                    var readDto = forward
                                    ? (object)new TcpClientMessageDto.ReadAllEventsForward(commitPos, preparePos, 10, false)
                                    : new TcpClientMessageDto.ReadAllEventsBackward(commitPos, preparePos, 10, false);
                    var package = new TcpPackage(forward ? TcpCommand.ReadAllEventsForward : TcpCommand.ReadAllEventsBackward,
                                                 Guid.NewGuid(),
                                                 readDto.Serialize());
                    conn.EnqueueSend(package.AsByteArray());
                },
                handlePackage: (conn, pkg) =>
                {
                    TcpClientMessageDto.EventLinkPair[] records;
                    long nextCommitPos;
                    long nextPreparePos;

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

                        var dto = pkg.Data.Deserialize<TcpClientMessageDto.ReadAllEventsForwardCompleted>();
                        records = dto.Events;
                        nextCommitPos = dto.NextCommitPosition;
                        nextPreparePos = dto.NextPreparePosition;
                    }
                    else
                    {
                        if (pkg.Command != TcpCommand.ReadAllEventsBackwardCompleted)
                        {
                            context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                            return;
                        }

                        var dto = pkg.Data.Deserialize<TcpClientMessageDto.ReadAllEventsBackwardCompleted>();
                        records = dto.Events;
                        nextCommitPos = dto.NextCommitPosition;
                        nextPreparePos = dto.NextPreparePosition;
                    }

                    if (records == null || records.Length == 0)
                    {
                        sw.Stop();
                        context.Log.Info("=== Reading ALL {2} completed in {0}. Total read: {1}",
                                         sw.Elapsed,
                                         total,
                                         forward ? "FORWARD" : "BACKWARD");
                        conn.Close();
                        context.Success();
                        return;
                    }
                    var sb = new StringBuilder();
                    for (int i = 0; i < records.Length; ++i)
                    {
                        var evnt = records[i].Event;
                        sb.AppendFormat("\n{0}:\tStreamId: {1},\n\tEventNumber: {2},\n\tData:\n{3},\n\tEventType: {4}\n",
                                        total,
                                        evnt.EventStreamId,
                                        evnt.EventNumber,
                                        Encoding.UTF8.GetString(evnt.Data),
                                        evnt.EventType);
                        total += 1;
                    }
                    context.Log.Info("Next {0} events read:\n{1}", records.Length, sb.ToString());

                    var readDto = forward
                                    ? (object)new TcpClientMessageDto.ReadAllEventsForward(nextCommitPos, nextPreparePos, 10, false)
                                    : new TcpClientMessageDto.ReadAllEventsBackward(nextCommitPos, nextPreparePos, 10, false);
                    var package = new TcpPackage(forward ? TcpCommand.ReadAllEventsForward : TcpCommand.ReadAllEventsBackward,
                                                 Guid.NewGuid(),
                                                 readDto.Serialize());
                    conn.EnqueueSend(package.AsByteArray());

                },
                connectionClosed: (connection, error) =>
                {
                    if (error == SocketError.Success)
                        context.Success();
                    else
                        context.Fail();
                });

            context.WaitForCompletion();
            return true;
        }
        private void Read(Status status, int readerIdx, CommandProcessorContext context, ManualResetEventSlim finishedEvent)
        {
            TcpTypedConnection<byte[]> connection;
            var iteration = new AutoResetEvent(false);

            var successes = 0;
            var fails = 0;

            var rnd = new Random();

            var streamIdx = -1;
            var eventidx = -1;

            Action<TcpTypedConnection<byte[]>, TcpPackage> packageReceived = (conn, pkg) =>
            {
                var dto = pkg.Data.Deserialize<TcpClientMessageDto.ReadEventCompleted>();
                switch ((ReadEventResult)dto.Result)
                {
                    case ReadEventResult.Success:
                        if (Equal(_streams[streamIdx], eventidx, dto.Event.Event.EventType, dto.Event.Event.Data))
                        {
                            successes++;
                            if (successes % 1000 == 0)
                                status.ReportReadsProgress(readerIdx, successes, fails);
                        }
                        else
                        {
                            fails++;
                            status.ReportReadError(readerIdx, _streams[streamIdx], eventidx);
                        }
                        break;
                    case ReadEventResult.NotFound:
                    case ReadEventResult.NoStream:
                    case ReadEventResult.StreamDeleted:
                    case ReadEventResult.Error:
                    case ReadEventResult.AccessDenied:
                        fails++;
                        status.ReportNotFoundOnRead(readerIdx, _streams[streamIdx], eventidx);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }

                iteration.Set();
            };
            Action<TcpTypedConnection<byte[]>> established = _ => { };
            Action<TcpTypedConnection<byte[]>, SocketError> closed = null;
            closed = (_, __) =>
            {
                Thread.Sleep(TimeSpan.FromSeconds(1));
                connection = context.Client.CreateTcpConnection(context, packageReceived, cn => iteration.Set(), closed, false);
            };

            connection = context.Client.CreateTcpConnection(context, packageReceived, established, closed, false);

            while (!_stopReading)
            {
                streamIdx = NextStreamForReading(rnd, readerIdx);
                int head;
                lock (_heads)
                    head = _heads[streamIdx];

                if (head > 0)
                {
                    eventidx = NextRandomEventVersion(rnd, head);
                    var stream = _streams[streamIdx];
                    var corrid = Guid.NewGuid();
                    var read = new TcpClientMessageDto.ReadEvent(stream, eventidx, resolveLinkTos: false, requireMaster: false);
                    var package = new TcpPackage(TcpCommand.ReadEvent, corrid, read.Serialize());

                    connection.EnqueueSend(package.AsByteArray());
                    iteration.WaitOne();
                }
                else
                    Thread.Sleep(100);
            }

            status.ReportReadsProgress(readerIdx, successes, fails);
            status.FinilizeStatus(readerIdx, fails == 0);
            connection.Close();
            finishedEvent.Set();
        }
        public bool Execute(CommandProcessorContext context, string[] args)
        {
            var eventStreamId = "test-stream";
            const string data = "test-data";
            var writeCount = 10;
            var expectedVersion = ExpectedVersion.Any;

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

            context.IsAsync();

            var writeDto = new ClientMessageDto.WriteEvents(
                Guid.Empty,
                eventStreamId,
                expectedVersion,
                Enumerable.Range(0, writeCount).Select(x =>
                                                       new ClientMessageDto.Event(Guid.NewGuid(),
                                                                                  "type",
                                                                                  Encoding.UTF8.GetBytes(data),
                                                                                  new byte[0])).ToArray());

            var package = new TcpPackage(TcpCommand.WriteEvents, writeDto.Serialize());

            var sw = new Stopwatch();

            context.Client.CreateTcpConnection(
                context,
                connectionEstablished: conn =>
                {
                    context.Log.Info("[{0}]: Writing...", conn.EffectiveEndPoint);
                    sw.Start();
                    conn.EnqueueSend(package.AsByteArray());
                },
                handlePackage: (conn, pkg) =>
                {
                    if (pkg.Command != TcpCommand.WriteEventsCompleted)
                    {
                        context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                        return;
                    }

                    sw.Stop();

                    var dto = pkg.Data.Deserialize<ClientMessageDto.WriteEventsCompleted>();
                    if (dto.ErrorCode == (int)OperationErrorCode.Success)
                    {
                        context.Log.Info("Successfully written {0} events. CorrelationId: {1}.",
                                         writeCount,
                                         dto.CorrelationId);
                        PerfUtils.LogTeamCityGraphData(string.Format("{0}-latency-ms", Keyword), (int)sw.ElapsedMilliseconds);
                    }
                    else
                    {
                        context.Log.Info("Error while writing: {0}. CorrelationId: {1}.", dto.Error, dto.CorrelationId);
                    }
                    context.Log.Info("Write request took: {0}.", sw.Elapsed);
                    
                    conn.Close();
                    context.Success();
                },
                connectionClosed:(connection, error) =>
                    {
                        if(error == SocketError.Success)
                            context.Success();
                        else
                            context.Fail();
                    });

            context.WaitForCompletion();
            return true;
        }
        private void WriteFlood(CommandProcessorContext context, int clientsCnt, long requestsCnt, int streamsCnt)
        {
            context.IsAsync();

            var doneEvent = new AutoResetEvent(false);
            var clients = new List<TcpTypedConnection<byte[]>>();
            var threads = new List<Thread>();

            long succ = 0;
            long fail = 0;
            long prepTimeout = 0;
            long commitTimeout = 0;
            long forwardTimeout = 0;
            long wrongExpVersion = 0;
            long streamDeleted = 0;
            long all = 0;

            var streams = Enumerable.Range(0, streamsCnt).Select(x => Guid.NewGuid().ToString()).ToArray();
            var sw2 = new Stopwatch();

            for (int i = 0; i < clientsCnt; i++)
            {
                var count = requestsCnt / clientsCnt + ((i == clientsCnt - 1) ? requestsCnt % clientsCnt : 0);

                int sent = 0;
                int received = 0;
                var rnd = new Random();

                var client = context.Client.CreateTcpConnection(
                    context,
                    (conn, pkg) =>
                    {
                        if (pkg.Command != TcpCommand.WriteEventsCompleted)
                        {
                            context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                            return;
                        }

                        var dto = pkg.Data.Deserialize<TcpClientMessageDto.WriteEventsCompleted>();
                        switch((OperationErrorCode)dto.ErrorCode)
                        {
                            case OperationErrorCode.Success:
                                Interlocked.Increment(ref succ);
                                break;
                            case OperationErrorCode.PrepareTimeout:
                                Interlocked.Increment(ref prepTimeout);
                                break;
                            case OperationErrorCode.CommitTimeout:
                                Interlocked.Increment(ref commitTimeout);
                                break;
                            case OperationErrorCode.ForwardTimeout:
                                Interlocked.Increment(ref forwardTimeout);
                                break;
                            case OperationErrorCode.WrongExpectedVersion:
                                Interlocked.Increment(ref wrongExpVersion);
                                break;
                            case OperationErrorCode.StreamDeleted:
                                Interlocked.Increment(ref streamDeleted);
                                break;
                            default:
                                throw new ArgumentOutOfRangeException();
                        }
                        if (dto.ErrorCode != (int)OperationErrorCode.Success)
                            Interlocked.Increment(ref fail);

                        Interlocked.Increment(ref received);

                        var localAll = Interlocked.Increment(ref all);
                        if (localAll % 1000 == 0) Console.Write(".");
                        if (localAll % 100000 == 0)
                        {
                            var elapsed = sw2.Elapsed;
                            sw2.Restart();
                            context.Log.Trace("\nDONE TOTAL {0} WRITES IN {1} ({2:0.0}/s).",
                                              localAll,
                                              elapsed,
                                              1000.0*100000/elapsed.TotalMilliseconds);
                        }
                        if (localAll == requestsCnt)
                            doneEvent.Set();
                    },
                    connectionClosed: (conn, err) =>
                    {
                        if (all < requestsCnt)
                            context.Fail(null, "Socket was closed, but not all requests were completed.");
                        else
                            context.Success();
                    });

                clients.Add(client);

                threads.Add(new Thread(() =>
                {
                    for (int j = 0; j < count; ++j)
                    {
                        var write = new TcpClientMessageDto.WriteEvents(
                            streams[rnd.Next(streamsCnt)],
                            ExpectedVersion.Any,
                            new[]
                                {
                                    new TcpClientMessageDto.ClientEvent(Guid.NewGuid().ToByteArray(),
                                                                        "TakeSomeSpaceEvent",
                                                                        false,
                                                                        Encoding.UTF8.GetBytes("DATA" + new string('*', 256)),
                                                                        Encoding.UTF8.GetBytes("METADATA" + new string('$', 100)))
                                },
                            true);
                        var package = new TcpPackage(TcpCommand.WriteEvents, Guid.NewGuid(), write.Serialize());
                        client.EnqueueSend(package.AsByteArray());

                        Interlocked.Increment(ref sent);
                        while (sent - received > context.Client.Options.WriteWindow)
                            Thread.Sleep(1);
                    }
                }));
            }

            var sw = Stopwatch.StartNew();
            sw2.Start();
            foreach (var thread in threads)
            {
                thread.IsBackground = true;
                thread.Start();
            }
            doneEvent.WaitOne();
            sw.Stop();

            foreach (var client in clients)
            {
                client.Close();
            }

            context.Log.Info("Completed. Successes: {0}, failures: {1} (WRONG VERSION: {2}, P: {3}, C: {4}, F: {5}, D: {6})",
                             succ,
                             fail,
                             wrongExpVersion,
                             prepTimeout,
                             commitTimeout,
                             forwardTimeout,
                             streamDeleted);

            var reqPerSec = (all + 0.0) / sw.ElapsedMilliseconds * 1000;
            context.Log.Info("{0} requests completed in {1}ms ({2:0.00} reqs per sec).",
                             all,
                             sw.ElapsedMilliseconds,
                             reqPerSec);

            PerfUtils.LogData(
                Keyword,
                PerfUtils.Row(PerfUtils.Col("clientsCnt", clientsCnt),
                              PerfUtils.Col("requestsCnt", requestsCnt),
                              PerfUtils.Col("ElapsedMilliseconds", sw.ElapsedMilliseconds)),
                PerfUtils.Row(PerfUtils.Col("successes", succ), PerfUtils.Col("failures", fail)));

            PerfUtils.LogTeamCityGraphData(string.Format("{0}-{1}-{2}-reqPerSec", Keyword, clientsCnt, requestsCnt),
                                           (int) reqPerSec);

            PerfUtils.LogTeamCityGraphData(
                string.Format("{0}-{1}-{2}-failureSuccessRate", Keyword, clientsCnt, requestsCnt),
                100*fail/(fail + succ));

            if (succ < fail)
                context.Fail(reason: "Number of failures is greater than number of successes");
            else
                context.Success();
        }
        private void WriteFlood(CommandProcessorContext context, int writeCnt, int clientsCnt, long requestsCnt)
        {
            const string data = "test-data";
            
            context.IsAsync();

            var clients = new List<TcpTypedConnection<byte[]>>();
            var threads = new List<Thread>();
            var doneEvent = new ManualResetEventSlim(false);
            long succ = 0;
            long fail = 0;
            long all = 0;

            for (int i = 0; i < clientsCnt; i++)
            {
                var count = requestsCnt / clientsCnt + ((i == clientsCnt - 1) ? requestsCnt % clientsCnt : 0);
                var localDoneEvent = new AutoResetEvent(false);
                var eventStreamId = "es" + Guid.NewGuid();
                var client = context.Client.CreateTcpConnection(
                    context,
                    (conn, pkg) =>
                    {
                        if (pkg.Command != TcpCommand.WriteEventsCompleted)
                        {
                            context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                            return;
                        }

                        var dto = pkg.Data.Deserialize<TcpClientMessageDto.WriteEventsCompleted>();
                        if (dto.Result == TcpClientMessageDto.OperationResult.Success)
                        {
                            if (Interlocked.Increment(ref succ)%1000 == 0) Console.Write(".");
                        }
                        else 
                        {
                            if (Interlocked.Increment(ref fail)%1000 == 0) Console.Write("#");
                        }

                        if (Interlocked.Increment(ref all) == requestsCnt)
                        {
                            context.Success();
                            doneEvent.Set();
                        }
                        localDoneEvent.Set();
                    },
                    connectionClosed: (conn, err) => context.Fail(reason: "Connection was closed prematurely."));
                clients.Add(client);

                threads.Add(new Thread(() =>
                {
                    for (int j = 0; j < count; ++j)
                    {
                        var writeDto = new TcpClientMessageDto.WriteEvents(
                            eventStreamId,
                            ExpectedVersion.Any,
                            Enumerable.Range(0, writeCnt).Select(x => 
                                new TcpClientMessageDto.NewEvent(Guid.NewGuid().ToByteArray(),
                                                                 "type",
                                                                 0,0,
                                                                 Common.Utils.Helper.UTF8NoBom.GetBytes(data),
                                                                 new byte[0])).ToArray(),
                            false);
                        var package = new TcpPackage(TcpCommand.WriteEvents, Guid.NewGuid(), writeDto.Serialize());
                        client.EnqueueSend(package.AsByteArray());
                        localDoneEvent.WaitOne();
                    }
                }) { IsBackground = true });
            }

            var sw = Stopwatch.StartNew();
            threads.ForEach(thread => thread.Start());
            doneEvent.Wait();
            sw.Stop();
            clients.ForEach(client => client.Close());

            var reqPerSec = (all + 0.0) / sw.ElapsedMilliseconds * 1000;
            context.Log.Info("Completed. Successes: {0}, failures: {1}", succ, fail);
            context.Log.Info("{0} requests completed in {1}ms ({2:0.00} reqs per sec).", all, sw.ElapsedMilliseconds, reqPerSec);

            PerfUtils.LogData(Keyword,
                              PerfUtils.Row(PerfUtils.Col("clientsCnt", clientsCnt),
                                            PerfUtils.Col("requestsCnt", requestsCnt),
                                            PerfUtils.Col("ElapsedMilliseconds", sw.ElapsedMilliseconds)),
                              PerfUtils.Row(PerfUtils.Col("successes", succ), PerfUtils.Col("failures", fail)));
            PerfUtils.LogTeamCityGraphData(string.Format("{0}-{1}-{2}-reqPerSec", Keyword, clientsCnt, requestsCnt), (int)reqPerSec);
            PerfUtils.LogTeamCityGraphData(string.Format("{0}-{1}-{2}-failureSuccessRate", Keyword, clientsCnt, requestsCnt), (int)(100.0 * fail / (fail + succ)));
            PerfUtils.LogTeamCityGraphData(string.Format("{0}-latency-ms", Keyword), (int)Math.Round(sw.Elapsed.TotalMilliseconds / requestsCnt));

            if (succ != requestsCnt)
                context.Fail(reason: "There were errors or not all requests completed.");
            else
                context.Success();
        }
 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 bool Execute(CommandProcessorContext context, string[] args)
        {
            var eventStreamId = "test-stream";
            var expectedVersion = ExpectedVersion.Any;
            var data = GenerateTestData();
            string metadata = null;

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

            context.IsAsync();
            var writeDto = new TcpClientMessageDto.WriteEvents(
                eventStreamId,
                expectedVersion,
                new[]
                {
                    new TcpClientMessageDto.NewEvent(Guid.NewGuid().ToByteArray(),
                                                     "JsonDataEvent",
                                                     1,0,
                                                     Helper.UTF8NoBom.GetBytes(data),
                                                     Helper.UTF8NoBom.GetBytes(metadata ?? string.Empty))
                },
                false);
            var package = new TcpPackage(TcpCommand.WriteEvents, Guid.NewGuid(), writeDto.Serialize());

            var sw = new Stopwatch();
            bool dataReceived = false;

            context.Client.CreateTcpConnection(
                context,
                connectionEstablished: conn =>
                {
                    context.Log.Info("[{0}, L{1}]: Writing...", conn.RemoteEndPoint, conn.LocalEndPoint);
                    sw.Start();
                    conn.EnqueueSend(package.AsByteArray());
                },
                handlePackage: (conn, pkg) =>
                {
                    if (pkg.Command != TcpCommand.WriteEventsCompleted)
                    {
                        context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                        return;
                    }

                    dataReceived = true;
                    sw.Stop();

                    var dto = pkg.Data.Deserialize<TcpClientMessageDto.WriteEventsCompleted>();
                    if (dto.Result == TcpClientMessageDto.OperationResult.Success)
                    {
                        context.Log.Info("Successfully written. EventId: {0}.", package.CorrelationId);
                        PerfUtils.LogTeamCityGraphData(string.Format("{0}-latency-ms", Keyword), (int)sw.ElapsedMilliseconds);
                    }
                    else
                    {
                        context.Log.Info("Error while writing: {0} ({1}).", dto.Message, dto.Result);
                    }

                    context.Log.Info("Write request took: {0}.", sw.Elapsed);
                    conn.Close();
                    context.Success();
                },
                connectionClosed: (connection, error) =>
                {
                    if (dataReceived && error == SocketError.Success)
                        context.Success();
                    else
                        context.Fail();
                });

            context.WaitForCompletion();
            return true;
        }
        public bool Execute(CommandProcessorContext context, string[] args)
        {
            var eventStreamId = "test-stream";
            var expectedVersion = ExpectedVersion.Any;
            var data = "test-data";
            string metadata = null;

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

            context.IsAsync();

            var writeDto = new ClientMessageDto.WriteEvents(
                Guid.Empty,
                eventStreamId,
                expectedVersion,
                new[] 
                { 
                    new ClientMessageDto.Event(Guid.NewGuid() ,
                                               "TakeSomeSpaceEvent",
                                               Encoding.UTF8.GetBytes(data),
                                               Encoding.UTF8.GetBytes(metadata ?? string.Empty))
                });
            var package = new TcpPackage(TcpCommand.WriteEvents, writeDto.Serialize());

            var sw = new Stopwatch();

            context.Client.CreateTcpConnection(
                context,
                connectionEstablished: conn =>
                {
                    context.Log.Info("[{0}]: Writing...", conn.EffectiveEndPoint);
                    sw.Start();
                    conn.EnqueueSend(package.AsByteArray());
                },
                handlePackage: (conn, pkg) =>
                {
                    if (pkg.Command != TcpCommand.WriteEventsCompleted)
                    {
                        context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command));
                        return;
                    }

                    sw.Stop();

                    var dto = pkg.Data.Deserialize<ClientMessageDto.WriteEventsCompleted>();
                    if ((OperationErrorCode)dto.ErrorCode == OperationErrorCode.Success)
                    {
                        context.Log.Info("Successfully written. EventId: {0}.", dto.CorrelationId);
                        PerfUtils.LogTeamCityGraphData(string.Format("{0}-latency-ms", Keyword), (int)sw.ElapsedMilliseconds);
                    }
                    else
                    {
                        context.Log.Info("Error while writing: {0} ({1}). EventId: {2}.",
                                         dto.Error,
                                         (OperationErrorCode) dto.ErrorCode,
                                         dto.CorrelationId);
                    }

                    context.Log.Info("Write request took: {0}.", sw.Elapsed);
                    conn.Close();
                    context.Success();
                },
                connectionClosed: (connection, error) =>
                {
                    if (error == SocketError.Success)
                        context.Success();
                    else
                        context.Fail();
                });

            context.WaitForCompletion();
            return true;
        }