private void Flood(CommandProcessorContext context, string eventStreamId, int clientsCnt, int minPerSecond, int maxPerSecond, int runTimeMinutes, int dataSize) { context.IsAsync(); var threads = new List<Thread>(); var doneEvent = new ManualResetEvent(false); var succ = 0; var fail = 0; var requestsCnt = 0; var watchLockRoot = new object(); var sw = Stopwatch.StartNew(); for (int i = 0; i < clientsCnt; i++) { int sent = 0; int received = 0; threads.Add(new Thread(() => { var esId = eventStreamId ?? "Stream-" + Thread.CurrentThread.ManagedThreadId % 3; var client = new HttpAsyncClient(); Action<HttpResponse> succHandler = response => { if (response.HttpStatusCode == HttpStatusCode.Created) { var succDone = Interlocked.Increment(ref succ); if (succDone % maxPerSecond == 0) Console.Write("."); } else { if (Interlocked.Increment(ref fail) % 10 == 0) { context.Log.Info("ANOTHER 10th WRITE FAILED. [{0}] - [{1}]", response.HttpStatusCode, response.StatusDescription); } } Interlocked.Increment(ref requestsCnt); Interlocked.Increment(ref received); }; 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) { 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 url = context.Client.HttpEndpoint.ToHttpUrl("/streams/{0}", esId); var dataResultingSize = dataSizeCoefficient * dataSize; var write = new ClientMessageDto.WriteEventText( Guid.Empty, ExpectedVersion.Any, new[] { new ClientMessageDto.EventText( Guid.NewGuid(), "type", "DATA" + dataResultingSize.ToString(" 00000 ") + new string('*', dataResultingSize), "METADATA" + new string('$', 100)) }); var request = Codec.Xml.To(write); client.Post(url, request, Codec.Xml.ContentType, succHandler, exc => { Interlocked.Increment(ref fail); Interlocked.Increment(ref requestsCnt); context.Log.ErrorException(exc, "Error during POST."); }); Interlocked.Increment(ref sent); Thread.Sleep(sleepTime); sentCount -= 1; while (sent - received > context.Client.Options.WriteWindow) Thread.Sleep(1); } })); } foreach (var thread in threads) { thread.IsBackground = true; thread.Start(); } doneEvent.WaitOne(); sw.Stop(); 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}-{3}-{4}-reqPerSec", Keyword, clientsCnt, minPerSecond, maxPerSecond, runTimeMinutes), (int)reqPerSec); PerfUtils.LogTeamCityGraphData( string.Format("{0}-{1}-{2}-failureSuccessRate", Keyword, clientsCnt, requestsCnt), 100 * fail / (fail + succ)); context.Success(); }
private void WriteFlood(CommandProcessorContext context, int clientsCnt, int requestsCnt) { context.IsAsync(); var threads = new List<Thread>(); var autoResetEvent = new AutoResetEvent(false); var succ = 0; var fail = 0; var all = 0; var sw = Stopwatch.StartNew(); for (int i = 0; i < clientsCnt; i++) { var count = requestsCnt / clientsCnt + ((i == clientsCnt - 1) ? requestsCnt % clientsCnt : 0); threads.Add(new Thread(() => { var autoEvent = new AutoResetEvent(false); var eventStreamId = "es" + Guid.NewGuid(); var client = new HttpAsyncClient(); var url = context.Client.HttpEndpoint.ToHttpUrl("/streams/{0}", eventStreamId); Action<HttpResponse> succHandler = response => { if (response.HttpStatusCode == HttpStatusCode.Created) { if (Interlocked.Increment(ref succ) % 1000 == 0) Console.Write("."); } else { if (Interlocked.Increment(ref fail) % 10 == 0) { context.Log.Info("ANOTHER 10th WRITE FAILED. [{0}] - [{1}]", response.HttpStatusCode, response.StatusDescription); } } if (Interlocked.Increment(ref all) == requestsCnt) autoResetEvent.Set(); autoEvent.Set(); }; for (int j = 0; j < count; ++j) { var write = new ClientMessageDto.WriteEventText( Guid.Empty, ExpectedVersion.Any, new[] { new ClientMessageDto.EventText(Guid.NewGuid(), "type", "DATA" + new string('*', 256), "METADATA" + new string('$', 100)) }); var request = Codec.Xml.To(write); client.Post(url, request, Codec.Xml.ContentType, succHandler, exc => { context.Log.ErrorException(exc, "Error during POST."); Interlocked.Increment(ref fail); if (Interlocked.Increment(ref all) == requestsCnt) autoResetEvent.Set(); autoEvent.Set(); }); autoEvent.WaitOne(); } })); } foreach (var thread in threads) { thread.IsBackground = true; thread.Start(); } autoResetEvent.WaitOne(); sw.Stop(); 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)); PerfUtils.LogTeamCityGraphData(string.Format("{0}-latency-ms", Keyword), (int)(sw.ElapsedMilliseconds / requestsCnt)); context.Success(); }