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(); }
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(); }