//Tracking the commit messages. public Task TrackingCommitMessages(StreamMessage msg) { if (commitTrackingMap.ContainsKey(msg.BatchID)) { var targetBatch = commitTrackingMap[msg.BatchID]; Functions.CheckNotNull(msg.barrierOrCommitInfo); targetBatch.AddBarrierOrCommitMsgTrackingHelper(msg.barrierOrCommitInfo); } else if (msg.BatchID >= 0 && !committedBatch.Contains(msg.BatchID)) { PrettyConsole.Line("Committing a new batch" + msg.BatchID); StreamBatch newBatch = new StreamBatch(msg.BatchID); //The name should be changed Functions.CheckNotNull(msg.barrierOrCommitInfo); newBatch.AddBarrierOrCommitMsgTrackingHelper(msg.barrierOrCommitInfo); commitTrackingMap.Add(msg.BatchID, newBatch); //PrettyConsole.Line("Add batch " + msg.BatchID + " to the commitTrackingMap"); } else { throw new InvalidOperationException("Batch ID less 0 or the message of that batch ahs been committed"); } return(Task.CompletedTask); }
//Recovery public async Task <Task> CompleteOneOperatorRecovery(BarrierOrCommitMsgTrackingInfo msgInfo) { if (!recoveryTrackingMap.ContainsKey(msgInfo.BatchID)) { //Multiple batch has that problem PrettyConsole.Line("The recovery key " + msgInfo.BatchID + " is not exist"); } else { //PrettyConsole.Line("Finish Tracking one message in batchID: " + msgInfo.BatchID); StreamBatch targetBatch = recoveryTrackingMap[msgInfo.BatchID]; targetBatch.CompleteOneMessageTracking(msgInfo); if (targetBatch.readForCommitting) { if (batchCoordinator != null) { PrettyConsole.Line("Batch: " + msgInfo.BatchID + " commit has been successfully recoveryed"); await batchCoordinator.CompleteRecovery(msgInfo.BatchID); recoveryTrackingMap.Remove(msgInfo.BatchID); } } } return(Task.CompletedTask); }
public async Task By_default_Aggregator_Trace_writes_exceptions_to_trace_output() { var aggregagator = Aggregator.Create <Projection <int, int>, string>((p, es) => { throw new Exception("OUCH!"); return(p); }).Trace(); try { await aggregagator.Aggregate(new Projection <int, int> { Value = 1 }, StreamBatch.Create(new[] { "hi", "there" }, Cursor.New(0))); } catch (Exception) { } traceListener.Messages .Should() .Contain(m => m.Contains("[Aggregate] Exception:")) .And .Contain(m => m.Contains("OUCH!")); }
public async Task <IStreamMetadata> WriteAsync( StreamBatch batch, CancellationToken cancellationToken) { var pk = new PartitionKey(batch.Metadata.StreamId.Value); var tx = containerProvider .GetStreamContainer() .CreateTransactionalBatch(pk); tx.UpsertItem( batch.Metadata, new TransactionalBatchItemRequestOptions { IfMatchEtag = batch.Metadata.ETag }); foreach (var document in batch.Documents) { tx.CreateItem( document, new TransactionalBatchItemRequestOptions { EnableContentResponseOnWrite = false }); } if (IsEmptyStream(batch.Metadata)) { await containerProvider .GetIndexContainer() .UpsertItemAsync( new StreamIndex { StreamId = batch.Metadata.StreamId.Value, Timestamp = dateTimeProvider.GetDateTime(), IsActive = true, }, new PartitionKey(nameof(StreamIndex)), new ItemRequestOptions { EnableContentResponseOnWrite = false }, cancellationToken) .ConfigureAwait(false); } using var batchResponse = await tx .ExecuteAsync(cancellationToken) .ConfigureAwait(false); EnsureSuccess(batchResponse, batch.Metadata); return(GetMetadataFromResponse(batchResponse)); }
public async Task By_default_Aggregator_Trace_writes_projections_and_batches_to_trace_output() { var aggregagator = Aggregator.Create <Projection <int, int>, string>((p, es) => { p.Value += es.Count; return(p); }).Trace(); await aggregagator.Aggregate(new Projection <int, int> { Value = 1 }, StreamBatch.Create(new[] { "hi", "there" }, Cursor.New(0))); traceListener.Messages .Should() .Contain("[Aggregate] Projection(Int32,Int32): 1 @ cursor 0 / batch of 2 starts @ 0"); }
public async Task Aggregator_Trace_default_behavior_can_be_overridden() { var receivedProjection = 0; IStreamBatch <int> receivedBatch = null; var aggregator = Aggregator.Create <int, int>((p, b) => { }) .Trace((i, b) => { receivedProjection = i; receivedBatch = b; }); var sentBatch = new StreamBatch <int>(Enumerable.Range(1, 10).ToArray(), 0); await aggregator.Aggregate(41, sentBatch); receivedProjection.Should().Be(41); receivedBatch.Should().BeSameAs(sentBatch); }
public async Task <IStreamBatch <EventMessage> > Fetch(IStreamQuery <string> query) { var commits = store.Advanced.GetFrom(query.Cursor.Position); var batchSize = query.BatchSize ?? 100; var actualCount = 0; var events = new List <EventMessage>(); var cursorPosition = query.Cursor.Position; foreach (var commit in commits) { actualCount += commit.Events.Count; if (actualCount > batchSize) { break; } events.AddRange(commit.Events); foreach (var @event in commit.Events.Select(e => e.Body).OfType <IDomainEvent>()) { @event.StreamRevision = commit.StreamRevision; @event.CheckpointToken = commit.CheckpointToken; } cursorPosition = commit.CheckpointToken; } var batch = StreamBatch.Create(events, query.Cursor); if (batch.Count > 0) { query.Cursor.AdvanceTo(cursorPosition); } return(batch); }
public Task TrackingBarrierMessages(StreamMessage msg) { if (batchTrackingMap.ContainsKey(msg.BatchID)) { var targetBatch = batchTrackingMap[msg.BatchID]; Functions.CheckNotNull(msg.barrierOrCommitInfo); targetBatch.AddBarrierOrCommitMsgTrackingHelper(msg.barrierOrCommitInfo); } else if (msg.BatchID >= 0 && !completedBatch.Contains(msg.BatchID)) { PrettyConsole.Line("Tracking new batch ID " + msg.BatchID); StreamBatch newBatch = new StreamBatch(msg.BatchID); Functions.CheckNotNull(msg.barrierOrCommitInfo); newBatch.AddBarrierOrCommitMsgTrackingHelper(msg.barrierOrCommitInfo); batchTrackingMap.Add(msg.BatchID, newBatch); } else { throw new InvalidOperationException(); } return(Task.CompletedTask); }
//Tracking the Recovery messages. public Task TrackingRecoveryMessages(StreamMessage msg) { if (recoveryTrackingMap.ContainsKey(msg.BatchID)) { var targetBatch = recoveryTrackingMap[msg.BatchID]; Functions.CheckNotNull(msg.barrierOrCommitInfo); targetBatch.AddBarrierOrCommitMsgTrackingHelper(msg.barrierOrCommitInfo); throw new InvalidOperationException("Should not recovery different batch at same time"); } else if (recoveryTrackingMap.Count == 0) { PrettyConsole.Line("Recovery batch" + msg.BatchID); StreamBatch newBatch = new StreamBatch(msg.BatchID); //The name should be changed Functions.CheckNotNull(msg.barrierOrCommitInfo); newBatch.AddBarrierOrCommitMsgTrackingHelper(msg.barrierOrCommitInfo); recoveryTrackingMap.Add(msg.BatchID, newBatch); return(Task.CompletedTask); } else { throw new InvalidOperationException("Should not recovery different batch at same time"); } }
//Should find the target task in the currentBatch public Task CompleteOneOperatorBarrier(BarrierOrCommitMsgTrackingInfo msgInfo) { if (!batchTrackingMap.ContainsKey(msgInfo.BatchID)) { PrettyConsole.Line("Complete Barrier, but The key " + msgInfo.BatchID + " is not exist"); } else { //PrettyConsole.Line("Finish Tracking one message in batchID: " + msgInfo.BatchID); StreamBatch targetBatch = batchTrackingMap[msgInfo.BatchID]; targetBatch.CompleteOneMessageTracking(msgInfo); if (targetBatch.readForCommitting) { if (batchCoordinator != null) { PrettyConsole.Line("Commit Batch: " + msgInfo.BatchID); SetBatchAsCompleted(msgInfo.BatchID); batchCoordinator.StartCommit(msgInfo.BatchID); batchTrackingMap.Remove(msgInfo.BatchID); } } } return(Task.CompletedTask); }
/// <summary> /// Fetches a batch of data from the stream. /// </summary> /// <param name="query">The query to apply to the stream.</param> /// <returns></returns> public async Task <IStreamBatch <EventMessage> > Fetch(IStreamQuery <int> query) { var minRevisionToFetch = Math.Max(query.Cursor.Position, 0); int maxRevisionToFetch; checked { maxRevisionToFetch = minRevisionToFetch + query.BatchSize ?? 100000; } var maxExistingRevision = store.Advanced .GetFrom(bucketId, streamId, minRevisionToFetch, int.MaxValue) .Select(c => c.StreamRevision) .LastOrDefault(); if (maxExistingRevision <= minRevisionToFetch) { return(query.Cursor.EmptyBatch <EventMessage, int>()); } var events = new List <EventMessage>(); checked { for (var i = minRevisionToFetch + 1; i <= maxRevisionToFetch; i++) { try { using (var stream = store.OpenStream(streamId: streamId, minRevision: i, maxRevision: i, bucketId: bucketId)) { if (stream.CommittedEvents.Count == 0) { break; } events.AddRange(stream.CommittedEvents .Select(e => { e.SetStreamRevision(stream.StreamRevision); return(e); })); } } catch (StreamNotFoundException) { break; } } } var batch = StreamBatch.Create(events, query.Cursor); if (batch.Count > 0) { query.Cursor.AdvanceTo(batch.Max(i => i.StreamRevision())); } return(batch); }
public async Task Aggregator_Trace_default_behavior_can_be_overridden() { var receivedProjection = 0; IStreamBatch<int> receivedBatch = null; var aggregator = Aggregator.Create<int, int>((p, b) => { }) .Trace((i, b) => { receivedProjection = i; receivedBatch = b; }); var sentBatch = new StreamBatch<int>(Enumerable.Range(1, 10).ToArray(), 0); await aggregator.Aggregate(41, sentBatch); receivedProjection.Should().Be(41); receivedBatch.Should().BeSameAs(sentBatch); }
Task <IStreamMetadata> IStreamBatchWriter.WriteAsync( StreamBatch batch, CancellationToken cancellationToken) => throw new NotImplementedException();