private TcpPackage Pack(Guid corrId, VerificationEvent evnt) { var writeDto = new ClientMessageDto.WriteEvents(corrId, evnt.EventStreamId, evnt.ExpectedVersion, new[] { new ClientMessageDto.Event(evnt.Event) }); return(new TcpPackage(TcpCommand.WriteEvents, writeDto.Serialize())); }
private static TcpPackage WrapWriteEvents(ClientMessage.WriteEvents msg) { var dto = new ClientMessageDto.WriteEvents( msg.EventStreamId, msg.ExpectedVersion, msg.Events.Select(x => new ClientMessageDto.Event(x.EventId, x.EventType, x.Data, x.Metadata)).ToArray()); return(new TcpPackage(TcpCommand.WriteEvents, msg.CorrelationId, dto.Serialize())); }
public Task <WriteResult> AppendToStreamAsync(string stream, int expectedVersion, IEnumerable <Event> events) { var correlationId = Guid.NewGuid(); var eventDtos = events.Select(x => new ClientMessageDto.Event(x.EventId, x.Type, x.Data, x.Metadata)).ToArray(); var dto = new ClientMessageDto.WriteEvents(correlationId, stream, expectedVersion, eventDtos); var package = new TcpPackage(TcpCommand.WriteEvents, correlationId, dto.Serialize()); var taskCompletionSource = new TaskCompletionSource <WriteResult>(); var taskWrapper = new WriteTaskCompletionWrapper(taskCompletionSource); RegisterHandler(correlationId, taskWrapper); EnqueueForSend(package); return(taskCompletionSource.Task); }
public override TcpPackage CreateNetworkPackage(Guid correlationId) { lock (_stepMoveLock) { switch (_step) { case 0: var writeDto = new ClientMessageDto.WriteEvents(correlationId, _event.EventStreamId, _event.ExpectedVersion, new[] { new ClientMessageDto.Event(_event.Event) }); return(new TcpPackage(TcpCommand.WriteEvents, correlationId, writeDto.Serialize())); case 1: var readDto = new ClientMessageDto.ReadEvent(correlationId, _event.EventStreamId, _event.ShouldBeVersion); return(new TcpPackage(TcpCommand.ReadEvent, correlationId, readDto.Serialize())); default: throw new ArgumentOutOfRangeException("_step", "step can be 0 or 1 for write task"); } } }
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 <ClientMessageDto.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 corrid = Guid.NewGuid(); var write = new ClientMessageDto.WriteEvents( Guid.Empty, streams[rnd.Next(streamsCnt)], ExpectedVersion.Any, new[] { new ClientMessageDto.Event(Guid.NewGuid(), "TakeSomeSpaceEvent", Encoding.UTF8.GetBytes("DATA" + new string('*', 256)), Encoding.UTF8.GetBytes("METADATA" + new string('$', 100))) }); var package = new TcpPackage(TcpCommand.WriteEvents, corrid, 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)); context.Success(); }
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); }
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 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 <ClientMessageDto.WriteEventsCompleted>(); if (dto.ErrorCode == (int)OperationErrorCode.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 (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 ClientMessageDto.WriteEvents( eventStreamId, ExpectedVersion.Any, new[] { new ClientMessageDto.Event(Guid.NewGuid(), "TakeSomeSpaceEvent", Encoding.UTF8.GetBytes("DATA" + new string('*', 256)), Encoding.UTF8.GetBytes("METADATA" + new string('$', 100))) }); 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, AutoResetEvent finish) { TcpTypedConnection <byte[]> connection; var iteration = new AutoResetEvent(false); var sent = 0; var prepareTimeouts = 0; var commitTimeouts = 0; var forwardTimeouts = 0; var wrongExpctdVersions = 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 <ClientMessageDto.WriteEventsCompleted>(); switch ((OperationErrorCode)dto.ErrorCode) { case OperationErrorCode.Success: lock (_heads) { var currentHead = _heads[streamIdx]; Ensure.Equal(currentHead, head); _heads[streamIdx]++; } break; case OperationErrorCode.PrepareTimeout: prepareTimeouts++; failed++; break; case OperationErrorCode.CommitTimeout: commitTimeouts++; failed++; break; case OperationErrorCode.ForwardTimeout: forwardTimeouts++; failed++; break; case OperationErrorCode.WrongExpectedVersion: wrongExpctdVersions++; failed++; break; case OperationErrorCode.StreamDeleted: streamsDeleted++; failed++; break; default: throw new ArgumentOutOfRangeException(); } sent++; if (sent % 1000 == 0) { status.ReportWritesProgress(writerIdx, sent, prepareTimeouts, commitTimeouts, forwardTimeouts, wrongExpctdVersions, 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 corrid = Guid.NewGuid(); var evnt = CreateEvent(_streams[streamIdx], head + 2); var write = new ClientMessageDto.WriteEvents(corrid, _streams[streamIdx], head == -1 ? head : head + 1, new[] { new ClientMessageDto.Event(evnt) }); var package = new TcpPackage(TcpCommand.WriteEvents, corrid, write.Serialize()); connection.EnqueueSend(package.AsByteArray()); iteration.WaitOne(); } status.ReportWritesProgress(writerIdx, sent, prepareTimeouts, commitTimeouts, forwardTimeouts, wrongExpctdVersions, streamsDeleted, failed, requests); status.FinilizeStatus(writerIdx, failed != sent); connection.Close(); }
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 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; var watchLockRoot = new object(); var sw = Stopwatch.StartNew(); for (int i = 0; i < clientsCnt; i++) { int sent = 0; int received = 0; 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 <ClientMessageDto.WriteEventsCompleted>(); if (dto.ErrorCode == (int)OperationErrorCode.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 ClientMessageDto.WriteEvents( Guid.Empty, esId, ExpectedVersion.Any, new[] { new ClientMessageDto.Event( Guid.NewGuid(), "TakeSomeSpaceEvent", Encoding.UTF8.GetBytes("DATA" + dataSize.ToString(" 00000 ") + new string('*', dataSize)), Encoding.UTF8.GetBytes("METADATA" + new string('$', 100))) }); var package = new TcpPackage(TcpCommand.WriteEvents, write.Serialize()); client.EnqueueSend(package.AsByteArray()); 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(); 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(); }