private async Task WriteFlood(CommandProcessorContext context, WriteFloodStats stats, int clientsCnt, long requestsCnt, int streamsCnt,
                                      int size, int batchSize, string streamPrefix, RequestMonitor monitor)
        {
            context.IsAsync();

            var doneEvent = new ManualResetEventSlim(false);
            var clients   = new List <IEventStoreConnection>();

            long last = 0;

            var streams = Enumerable.Range(0, streamsCnt).Select(x =>
                                                                 string.IsNullOrWhiteSpace(streamPrefix)
                                        ? Guid.NewGuid().ToString()
                                        : $"{streamPrefix}-{x}").ToArray();

            context.Log.Information("Writing streams randomly between {first} and {last}",
                                    streams.FirstOrDefault(),
                                    streams.LastOrDefault());

            var start = new TaskCompletionSource();

            stats.StartTime = DateTime.UtcNow;
            var sw2         = new Stopwatch();
            var capacity    = 2000 / clientsCnt;
            var clientTasks = new List <Task>();

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

                var client = context._clientApiTestClient.CreateConnection();
                await client.ConnectAsync();

                clientTasks.Add(RunClient(client, count));
            }

            async Task RunClient(IEventStoreConnection client, long count)
            {
                var         rnd     = new Random();
                List <Task> pending = new List <Task>(capacity);
                await start.Task;

                for (int j = 0; j < count; ++j)
                {
                    var events = new EventData[batchSize];
                    for (int q = 0; q < batchSize; q++)
                    {
                        events[q] = new EventData(Guid.NewGuid(),
                                                  "TakeSomeSpaceEvent", false,
                                                  Common.Utils.Helper.UTF8NoBom.GetBytes(
                                                      "{ \"DATA\" : \"" + new string('*', size) + "\"}"),
                                                  Common.Utils.Helper.UTF8NoBom.GetBytes(
                                                      "{ \"METADATA\" : \"" + new string('$', 100) + "\"}"));
                    }

                    var corrid = Guid.NewGuid();
                    monitor.StartOperation(corrid);

                    pending.Add(client.AppendToStreamAsync(streams[rnd.Next(streamsCnt)], ExpectedVersion.Any, events)
                                .ContinueWith(t => {
                        monitor.EndOperation(corrid);
                        if (t.IsCompletedSuccessfully)
                        {
                            Interlocked.Add(ref stats.Succ, batchSize);
                        }
                        else
                        {
                            if (Interlocked.Increment(ref stats.Fail) % 1000 == 0)
                            {
                                Console.Write("#");
                            }

                            if (t.Exception != null)
                            {
                                var exception = t.Exception.Flatten();
                                switch (exception.InnerException)
                                {
                                case WrongExpectedVersionException _:
                                    Interlocked.Increment(ref stats.WrongExpVersion);
                                    break;

                                case StreamDeletedException _:
                                    Interlocked.Increment(ref stats.StreamDeleted);
                                    break;

                                case OperationTimedOutException _:
                                    Interlocked.Increment(ref stats.CommitTimeout);
                                    break;
                                }
                            }
                        }

                        Interlocked.Add(ref stats.Succ, batchSize);
                        if (stats.Succ - last > 1000)
                        {
                            last = stats.Succ;
                            Console.Write(".");
                        }

                        var localAll = Interlocked.Add(ref stats.All, batchSize);
                        if (localAll % 100000 == 0)
                        {
                            stats.Elapsed = sw2.Elapsed;
                            stats.Rate    = 1000.0 * 100000 / stats.Elapsed.TotalMilliseconds;
                            sw2.Restart();
                            context.Log.Debug(
                                "\nDONE TOTAL {writes} WRITES IN {elapsed} ({rate:0.0}/s) [S:{success}, F:{failures} (WEV:{wrongExpectedVersion}, P:{prepareTimeout}, C:{commitTimeout}, F:{forwardTimeout}, D:{streamDeleted})].",
                                localAll, stats.Elapsed, stats.Rate,
                                stats.Succ, stats.Fail,
                                stats.WrongExpVersion, stats.PrepTimeout, stats.CommitTimeout, stats.ForwardTimeout, stats.StreamDeleted);
                            stats.WriteStatsToFile(context.StatsLogger);
                        }

                        if (localAll >= requestsCnt)
                        {
                            context.Success();
                            doneEvent.Set();
                        }
                    }));
                    if (pending.Count == capacity)
                    {
                        await Task.WhenAny(pending).ConfigureAwait(false);

                        while (pending.Count > 0 && Task.WhenAny(pending).IsCompleted)
                        {
                            pending.RemoveAll(x => x.IsCompleted);
                            if (stats.Succ - last > 1000)
                            {
                                Console.Write(".");
                                last = stats.Succ;
                            }
                        }
                    }
                }

                if (pending.Count > 0)
                {
                    await Task.WhenAll(pending);
                }
            }

            var sw = Stopwatch.StartNew();

            sw2.Start();
            start.SetResult();
            await Task.WhenAll(clientTasks);

            sw.Stop();

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

            context.Log.Information(
                "Completed. Successes: {success}, failures: {failures} (WRONG VERSION: {wrongExpectedVersion}, P: {prepareTimeout}, C: {commitTimeout}, F: {forwardTimeout}, D: {streamDeleted})",
                stats.Succ, stats.Fail,
                stats.WrongExpVersion, stats.PrepTimeout, stats.CommitTimeout, stats.ForwardTimeout, stats.StreamDeleted);
            stats.WriteStatsToFile(context.StatsLogger);

            var reqPerSec = (stats.All + 0.0) / sw.ElapsedMilliseconds * 1000;

            context.Log.Information("{requests} requests completed in {elapsed}ms ({rate:0.00} reqs per sec).", stats.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", stats.Succ), PerfUtils.Col("failures", stats.Fail)));

            var failuresRate = (int)(100 * stats.Fail / (stats.Fail + stats.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 stats.Succ) != requestsCnt)
            {
                context.Fail(reason: "There were errors or not all requests completed.");
            }
            else
            {
                context.Success();
            }
        }
Пример #2
0
 public void AddRequestMonitor(RequestMonitor requestMonitor)
 {
     requestMonitors.Add(requestMonitor);
 }
Пример #3
0
 internal BackupClient(string destinationHostNameOrIp, int destinationPort, string originHostNameOrIp, LogProvider logProvider, StoreId storeId, long timeout, ResponseUnpacker unpacker, ByteCounterMonitor byteCounterMonitor, RequestMonitor requestMonitor, LogEntryReader <ReadableClosablePositionAwareChannel> reader) : base(destinationHostNameOrIp, destinationPort, originHostNameOrIp, logProvider, storeId, FRAME_LENGTH, timeout, Client.DEFAULT_MAX_NUMBER_OF_CONCURRENT_CHANNELS_PER_CLIENT, FRAME_LENGTH, unpacker, byteCounterMonitor, requestMonitor, reader)
 {
 }
Пример #4
0
        public Client(string destinationHostNameOrIp, int destinationPort, string originHostNameOrIp, LogProvider logProvider, StoreId storeId, int frameLength, long readTimeout, int maxConcurrentChannels, int chunkSize, ResponseUnpacker responseUnpacker, ByteCounterMonitor byteCounterMonitor, RequestMonitor requestMonitor, LogEntryReader <ReadableClosablePositionAwareChannel> entryReader)
        {
            this._entryReader = entryReader;
            Debug.Assert(byteCounterMonitor != null);
            Debug.Assert(requestMonitor != null);

            this._byteCounterMonitor = byteCounterMonitor;
            this._requestMonitor     = requestMonitor;
            assertChunkSizeIsWithinFrameSize(chunkSize, frameLength);

            this._msgLog      = logProvider.getLog(this.GetType());
            this._storeId     = storeId;
            this._frameLength = frameLength;
            this._readTimeout = readTimeout;
            // ResourcePool no longer controls max concurrent channels. Use this value for the pool size
            this._maxUnusedChannels   = maxConcurrentChannels;
            this._comExceptionHandler = NoOpComExceptionHandler;

            if (destinationHostNameOrIp.Equals("0.0.0.0"))
            {
                // So it turns out that on Windows, connecting to 0.0.0.0 when specifying
                // an origin address will not succeed. But since we know we are
                // connecting to ourselves, and that we are listening on everything,
                // replacing with localhost is the proper thing to do.
                this._destination = new InetSocketAddress(LocalAddress, destinationPort);
            }
            else
            {
                // An explicit destination address is always correct
                this._destination = new InetSocketAddress(destinationHostNameOrIp, destinationPort);
            }

            if (string.ReferenceEquals(originHostNameOrIp, null) || originHostNameOrIp.Equals("0.0.0.0"))
            {
                _origin = null;
            }
            else
            {
                _origin = new InetSocketAddress(originHostNameOrIp, 0);
            }

            ProtocolVersion protocolVersion = ProtocolVersion;

            this._protocol         = CreateProtocol(chunkSize, protocolVersion.ApplicationProtocol);
            this._responseUnpacker = responseUnpacker;

            _msgLog.info(this.GetType().Name + " communication channel created towards " + _destination);
        }
Пример #5
0
 public Server(T requestTarget, Configuration config, LogProvider logProvider, int frameLength, ProtocolVersion protocolVersion, TxChecksumVerifier txVerifier, Clock clock, ByteCounterMonitor byteCounterMonitor, RequestMonitor requestMonitor)
 {
     this._requestTarget = requestTarget;
     this._config        = config;
     this._frameLength   = frameLength;
     this._applicationProtocolVersion = protocolVersion.ApplicationProtocol;
     this._logProvider            = logProvider;
     this._msgLog                 = this._logProvider.getLog(this.GetType());
     this._txVerifier             = txVerifier;
     this._byteCounterMonitor     = byteCounterMonitor;
     this._requestMonitor         = requestMonitor;
     this._connectedSlaveChannels = new IdleChannelReaper(this, logProvider, clock, config.OldChannelThreshold);
     this._chunkSize              = config.ChunkSize;
     assertChunkSizeIsWithinFrameSize(_chunkSize, frameLength);
 }
Пример #6
0
 public SlaveClient(InstanceId machineId, string destinationHostNameOrIp, int destinationPort, string originHostNameOrIp, LogProvider logProvider, StoreId storeId, int maxConcurrentChannels, int chunkSize, ByteCounterMonitor byteCounterMonitor, RequestMonitor requestMonitor, LogEntryReader <ReadableClosablePositionAwareChannel> entryReader) : base(destinationHostNameOrIp, destinationPort, originHostNameOrIp, logProvider, storeId, Protocol.DEFAULT_FRAME_LENGTH, HaSettings.read_timeout.apply(from->null).toMillis(), maxConcurrentChannels, chunkSize, NO_OP_RESPONSE_UNPACKER, byteCounterMonitor, requestMonitor, entryReader)