public bool Execute(CommandProcessorContext context, string[] args) { var eventStreamId = "test-stream"; var fromNumber = 0; const bool resolveLinkTos = false; var requireLeader = false; if (args.Length > 0) { if (args.Length > 3) { return(false); } eventStreamId = args[0]; if (args.Length >= 2) { fromNumber = int.Parse(args[1]); } if (args.Length >= 3) { requireLeader = bool.Parse(args[2]); } } context.IsAsync(); var sw = new Stopwatch(); context._tcpTestClient.CreateTcpConnection( context, connectionEstablished: conn => { context.Log.Information("[{remoteEndPoint}, L{localEndPoint}]: Reading...", conn.RemoteEndPoint, conn.LocalEndPoint); var readDto = new ReadEvent(eventStreamId, fromNumber, resolveLinkTos, requireLeader); var package = new TcpPackage(TcpCommand.ReadEvent, Guid.NewGuid(), readDto.Serialize()).AsByteArray(); sw.Start(); conn.EnqueueSend(package); }, handlePackage: (conn, pkg) => { sw.Stop(); context.Log.Information("Read request took: {elapsed}.", sw.Elapsed); if (pkg.Command != TcpCommand.ReadEventCompleted) { context.Fail(reason: string.Format("Unexpected TCP package: {0}.", pkg.Command)); return; } var dto = pkg.Data.Deserialize <ReadEventCompleted>(); context.Log.Information("READ events from <{stream}>:\n\n" + "\tEventStreamId: {stream}\n" + "\tEventNumber: {eventNumber}\n" + "\tReadResult: {readResult}\n" + "\tEventType: {eventType}\n" + "\tData: {data}\n" + "\tMetadata: {metadata}\n", eventStreamId, eventStreamId, dto.Event.Event.EventNumber, dto.Result, dto.Event.Event.EventType, Helper.UTF8NoBom.GetString(dto.Event.Event.Data.ToByteArray()), Helper.UTF8NoBom.GetString(dto.Event.Event.Metadata.ToByteArray())); if (dto.Result == ReadEventCompleted.Types.ReadEventResult.Success) { PerfUtils.LogTeamCityGraphData(string.Format("{0}-latency-ms", Keyword), (int)Math.Round(sw.Elapsed.TotalMilliseconds)); context.Success(); } else { context.Fail(); } conn.Close(); }, connectionClosed: (connection, error) => context.Fail(reason: "Connection was closed prematurely.")); 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(readerIdx); var streamIdx = -1; var eventidx = -1; Action <TcpTypedConnection <byte[]>, TcpPackage> packageReceived = (conn, pkg) => { var dto = pkg.Data.Deserialize <ReadEventCompleted>(); switch (dto.Result) { case ReadEventCompleted.Types.ReadEventResult.Success: if (Equal(_streams[streamIdx], eventidx, dto.Event.Event.EventType, dto.Event.Event.Data.ToByteArray())) { successes++; if (successes % 1000 == 0) { status.ReportReadsProgress(readerIdx, successes, fails); } } else { fails++; status.ReportReadError(readerIdx, _streams[streamIdx], eventidx); } break; case ReadEventCompleted.Types.ReadEventResult.NotFound: case ReadEventCompleted.Types.ReadEventResult.NoStream: case ReadEventCompleted.Types.ReadEventResult.StreamDeleted: case ReadEventCompleted.Types.ReadEventResult.Error: case ReadEventCompleted.Types.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 = (_, __) => { if (!context._tcpTestClient.Options.Reconnect) { return; } Thread.Sleep(TimeSpan.FromSeconds(1)); connection = context._tcpTestClient.CreateTcpConnection(context, packageReceived, cn => iteration.Set(), closed, false); }; connection = context._tcpTestClient.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 ReadEvent(stream, eventidx, resolveLinkTos: false, requireLeader: 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); context._tcpTestClient.Options.Reconnect = false; connection.Close(); finishedEvent.Set(); }
private void ReadFlood(CommandProcessorContext context, string streamPrefix, int clientsCnt, long requestsCnt, int streamsCnt, bool resolveLinkTos, bool requireLeader, RequestMonitor monitor) { context.IsAsync(); string[] streams = streamsCnt == 1 ? new[] { streamPrefix } : Enumerable.Range(0, streamsCnt).Select(x => $"{streamPrefix}-{x}").ToArray(); context.Log.Information("Reading streams {first} through to {last}", streams.FirstOrDefault(), streams.LastOrDefault()); 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._tcpTestClient.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 <ReadEventCompleted>(); monitor.EndOperation(pkg.CorrelationId); if (dto.Result == ReadEventCompleted.Types.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.Verbose("\nDONE TOTAL {reads} READS IN {elapsed} ({rate: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); var clientNum = i; threads.Add(new Thread(() => { int streamIndex = (streamsCnt / clientsCnt) * clientNum; context.Log.Information("Reader #{clientNum} performing {count} reads on {streamsCnt} streams starting at stream index {streamIndex}", clientNum, count, streamsCnt, streamIndex); for (int j = 0; j < count; ++j) { var corrId = Guid.NewGuid(); var eventStreamId = streams[streamIndex++]; if (streamIndex >= streamsCnt) { streamIndex = 0; } var read = new ReadEvent(eventStreamId, 0, resolveLinkTos, requireLeader); 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._tcpTestClient.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.Information("Completed. READS succ: {success}, fail: {failures}.", Interlocked.Read(ref succ), Interlocked.Read(ref fail)); context.Log.Information("{requests} requests completed in {elapsed}ms ({rate: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(); } }