public async Task RequestContext_MultiThreads_ExportToMessage() { const int NumLoops = 50; string id = "key" + random.Next(); Message msg = new Message(); Task[] promises = new Task[NumLoops]; ManualResetEventSlim flag = new ManualResetEventSlim(false); for (int i = 0; i < NumLoops; i++) { string key = id + "-" + i; RequestContext.Set(key, i); promises[i] = Task.Run(() => { flag.Wait(); msg.RequestContextData = RequestContextExtensions.Export(this.fixture.SerializationManager); }); flag.Set(); Thread.Sleep(1); RequestContext.Remove(key); } await Task.WhenAll(promises); }
/// <inheritdoc /> public bool TryReadEvents(int maxCount, out IEnumerable <EventData> events) { if (!this.ShouldProduce) { events = null; return(false); } int count = maxCount; List <EventData> eventDataList = new List <EventData>(); while (count-- > 0) { this.SequenceNumberCounter.Increment(); var eventData = EventHubBatchContainer.ToEventData <int>( this.serializationManager, this.StreamId, this.GenerateEvent(this.SequenceNumberCounter.Value), RequestContextExtensions.Export(this.serializationManager)); var wrapper = new WrappedEventData( eventData.Body, eventData.Properties, eventData.SystemProperties, partitionKey: StreamId.GetKeyAsString(), offset: DateTime.UtcNow.Ticks, sequenceNumber: this.SequenceNumberCounter.Value); eventDataList.Add(wrapper); this.logger.Info($"Generate data of SequemceNumber {SequenceNumberCounter.Value} for stream {this.StreamId}"); } events = eventDataList; return(eventDataList.Count > 0); }
private async Task SendAndReceiveFromQueueAdapter(IQueueAdapterFactory adapterFactory, IProviderConfiguration config) { IQueueAdapter adapter = await adapterFactory.CreateAdapter(); IQueueAdapterCache cache = adapterFactory.GetQueueAdapterCache(); // Create receiver per queue IStreamQueueMapper mapper = adapterFactory.GetStreamQueueMapper(); Dictionary <QueueId, IQueueAdapterReceiver> receivers = mapper.GetAllQueues().ToDictionary(queueId => queueId, adapter.CreateReceiver); Dictionary <QueueId, IQueueCache> caches = mapper.GetAllQueues().ToDictionary(queueId => queueId, cache.CreateQueueCache); await Task.WhenAll(receivers.Values.Select(receiver => receiver.Initialize(TimeSpan.FromSeconds(5)))); // test using 2 streams Guid streamId1 = Guid.NewGuid(); Guid streamId2 = Guid.NewGuid(); int receivedBatches = 0; var streamsPerQueue = new ConcurrentDictionary <QueueId, HashSet <IStreamIdentity> >(); // reader threads (at most 2 active queues because only two streams) var work = new List <Task>(); foreach (KeyValuePair <QueueId, IQueueAdapterReceiver> receiverKvp in receivers) { QueueId queueId = receiverKvp.Key; var receiver = receiverKvp.Value; var qCache = caches[queueId]; Task task = Task.Factory.StartNew(() => { while (receivedBatches < NumBatches) { var messages = receiver.GetQueueMessagesAsync(CloudQueueMessage.MaxNumberOfMessagesToPeek).Result.ToArray(); if (!messages.Any()) { continue; } foreach (IBatchContainer message in messages) { streamsPerQueue.AddOrUpdate(queueId, id => new HashSet <IStreamIdentity> { new StreamIdentity(message.StreamGuid, message.StreamGuid.ToString()) }, (id, set) => { set.Add(new StreamIdentity(message.StreamGuid, message.StreamGuid.ToString())); return(set); }); output.WriteLine("Queue {0} received message on stream {1}", queueId, message.StreamGuid); Assert.Equal(NumMessagesPerBatch / 2, message.GetEvents <int>().Count()); // "Half the events were ints" Assert.Equal(NumMessagesPerBatch / 2, message.GetEvents <string>().Count()); // "Half the events were strings" } Interlocked.Add(ref receivedBatches, messages.Length); qCache.AddToCache(messages); } }); work.Add(task); } // send events List <object> events = CreateEvents(NumMessagesPerBatch); work.Add(Task.Factory.StartNew(() => Enumerable.Range(0, NumBatches) .Select(i => i % 2 == 0 ? streamId1 : streamId2) .ToList() .ForEach(streamId => adapter.QueueMessageBatchAsync(streamId, streamId.ToString(), events.Take(NumMessagesPerBatch).ToArray(), null, RequestContextExtensions.Export(this.fixture.SerializationManager)).Wait()))); await Task.WhenAll(work); // Make sure we got back everything we sent Assert.Equal(NumBatches, receivedBatches); // check to see if all the events are in the cache and we can enumerate through them StreamSequenceToken firstInCache = new EventSequenceTokenV2(0); foreach (KeyValuePair <QueueId, HashSet <IStreamIdentity> > kvp in streamsPerQueue) { var receiver = receivers[kvp.Key]; var qCache = caches[kvp.Key]; foreach (IStreamIdentity streamGuid in kvp.Value) { // read all messages in cache for stream IQueueCacheCursor cursor = qCache.GetCacheCursor(streamGuid, firstInCache); int messageCount = 0; StreamSequenceToken tenthInCache = null; StreamSequenceToken lastToken = firstInCache; while (cursor.MoveNext()) { Exception ex; messageCount++; IBatchContainer batch = cursor.GetCurrent(out ex); output.WriteLine("Token: {0}", batch.SequenceToken); Assert.True(batch.SequenceToken.CompareTo(lastToken) >= 0, $"order check for event {messageCount}"); lastToken = batch.SequenceToken; if (messageCount == 10) { tenthInCache = batch.SequenceToken; } } output.WriteLine("On Queue {0} we received a total of {1} message on stream {2}", kvp.Key, messageCount, streamGuid); Assert.Equal(NumBatches / 2, messageCount); Assert.NotNull(tenthInCache); // read all messages from the 10th cursor = qCache.GetCacheCursor(streamGuid, tenthInCache); messageCount = 0; while (cursor.MoveNext()) { messageCount++; } output.WriteLine("On Queue {0} we received a total of {1} message on stream {2}", kvp.Key, messageCount, streamGuid); const int expected = NumBatches / 2 - 10 + 1; // all except the first 10, including the 10th (10 + 1) Assert.Equal(expected, messageCount); } } }
public void RequestContext_ActivityId_ExportToMessage() { Guid activityId = Guid.NewGuid(); Guid activityId2 = Guid.NewGuid(); Guid nullActivityId = Guid.Empty; Message msg = new Message(); msg.RequestContextData = RequestContextExtensions.Export(this.fixture.SerializationManager); if (msg.RequestContextData != null) { foreach (var kvp in msg.RequestContextData) { headers.Add(kvp.Key, kvp.Value); } } ; Assert.False(headers.ContainsKey(RequestContext.E2_E_TRACING_ACTIVITY_ID_HEADER), "ActivityId should not be be present " + headers.ToStrings(separator: ",")); TestCleanup(); RequestContextTestUtils.SetActivityId(activityId); msg = new Message(); msg.RequestContextData = RequestContextExtensions.Export(this.fixture.SerializationManager); if (msg.RequestContextData != null) { foreach (var kvp in msg.RequestContextData) { headers.Add(kvp.Key, kvp.Value); } } ; Assert.True(headers.ContainsKey(RequestContext.E2_E_TRACING_ACTIVITY_ID_HEADER), "ActivityId #1 should be present " + headers.ToStrings(separator: ",")); object result = headers[RequestContext.E2_E_TRACING_ACTIVITY_ID_HEADER]; Assert.NotNull(result); // ActivityId #1 should not be null Assert.Equal(activityId, result); // "E2E ActivityId #1 not propagated correctly" Assert.Equal(activityId, RequestContextTestUtils.GetActivityId()); // "Original E2E ActivityId #1 should not have changed" TestCleanup(); RequestContextTestUtils.SetActivityId(nullActivityId); msg = new Message(); msg.RequestContextData = RequestContextExtensions.Export(this.fixture.SerializationManager); if (msg.RequestContextData != null) { foreach (var kvp in msg.RequestContextData) { headers.Add(kvp.Key, kvp.Value); } } ; Assert.False(headers.ContainsKey(RequestContext.E2_E_TRACING_ACTIVITY_ID_HEADER), "Null ActivityId should not be present " + headers.ToStrings(separator: ",")); TestCleanup(); RequestContextTestUtils.SetActivityId(activityId2); msg = new Message(); msg.RequestContextData = RequestContextExtensions.Export(this.fixture.SerializationManager); foreach (var kvp in msg.RequestContextData) { headers.Add(kvp.Key, kvp.Value); } ; Assert.True(headers.ContainsKey(RequestContext.E2_E_TRACING_ACTIVITY_ID_HEADER), "ActivityId #2 should be present " + headers.ToStrings(separator: ",")); result = headers[RequestContext.E2_E_TRACING_ACTIVITY_ID_HEADER]; Assert.NotNull(result); // ActivityId #2 should not be null Assert.Equal(activityId2, result); // "E2E ActivityId #2 not propagated correctly" Assert.Equal(activityId2, RequestContextTestUtils.GetActivityId()); // "Original E2E ActivityId #2 should not have changed" TestCleanup(); }
public void RequestContext_ActivityId_ExportImport() { Guid activityId = Guid.NewGuid(); Guid activityId2 = Guid.NewGuid(); Guid nullActivityId = Guid.Empty; Message msg = new Message(); msg.RequestContextData = RequestContextExtensions.Export(this.fixture.DeepCopier); RequestContext.Clear(); RequestContextExtensions.Import(msg.RequestContextData); var actId = RequestContext.Get(RequestContext.E2_E_TRACING_ACTIVITY_ID_HEADER); Assert.Null(actId); TestCleanup(); RequestContextTestUtils.SetActivityId(activityId); msg = new Message(); msg.RequestContextData = RequestContextExtensions.Export(this.fixture.DeepCopier); RequestContext.Clear(); RequestContextExtensions.Import(msg.RequestContextData); actId = RequestContext.Get(RequestContext.E2_E_TRACING_ACTIVITY_ID_HEADER); if (msg.RequestContextData != null) { foreach (var kvp in msg.RequestContextData) { headers.Add(kvp.Key, kvp.Value); } } ; Assert.NotNull(actId); // "ActivityId #1 should be present " + headers.ToStrings(separator: ",") object result = headers[RequestContext.E2_E_TRACING_ACTIVITY_ID_HEADER]; Assert.NotNull(result); // "ActivityId #1 should not be null" Assert.Equal(activityId, result); // "E2E ActivityId #1 not propagated correctly" Assert.Equal(activityId, RequestContextTestUtils.GetActivityId()); // "Original E2E ActivityId #1 should not have changed" TestCleanup(); RequestContextTestUtils.SetActivityId(nullActivityId); msg = new Message(); msg.RequestContextData = RequestContextExtensions.Export(this.fixture.DeepCopier); RequestContext.Clear(); RequestContextExtensions.Import(msg.RequestContextData); actId = RequestContext.Get(RequestContext.E2_E_TRACING_ACTIVITY_ID_HEADER); Assert.Null(actId); TestCleanup(); RequestContextTestUtils.SetActivityId(activityId2); msg = new Message(); msg.RequestContextData = RequestContextExtensions.Export(this.fixture.DeepCopier); RequestContext.Clear(); RequestContextExtensions.Import(msg.RequestContextData); actId = RequestContext.Get(RequestContext.E2_E_TRACING_ACTIVITY_ID_HEADER); if (msg.RequestContextData != null) { foreach (var kvp in msg.RequestContextData) { headers.Add(kvp.Key, kvp.Value); } } ; Assert.NotNull(actId); // "ActivityId #2 should be present " + headers.ToStrings(separator: ",") result = headers[RequestContext.E2_E_TRACING_ACTIVITY_ID_HEADER]; Assert.NotNull(result); // "ActivityId #2 should not be null" Assert.Equal(activityId2, result); // "E2E ActivityId #2 not propagated correctly Assert.Equal(activityId2, RequestContextTestUtils.GetActivityId()); // "Original E2E ActivityId #2 should not have changed" TestCleanup(); }
public Task OnNextBatchAsync(IEnumerable <T> batch, StreamSequenceToken token) { return(this.queueAdapter.QueueMessageBatchAsync(this.stream.StreamId.Guid, this.stream.StreamId.Namespace, batch, token, RequestContextExtensions.Export(this.serializationManager))); }
public Task OnNextAsync(T item, StreamSequenceToken token) { return(this.queueAdapter.QueueMessageAsync(this.stream.StreamId.Guid, this.stream.StreamId.Namespace, item, token, RequestContextExtensions.Export(this.serializationManager))); }
/// <inheritdoc /> public bool TryReadEvents(int maxCount, out IEnumerable <EventData> events) { if (!this.ShouldProduce) { events = null; return(false); } int count = maxCount; List <EventData> eventDataList = new List <EventData>(); while (count-- > 0) { this.SequenceNumberCounter.Increment(); var eventData = EventHubBatchContainer.ToEventData <int>(this.serializationManager, this.StreamId.Guid, this.StreamId.Namespace, this.GenerateEvent(this.SequenceNumberCounter.Value), RequestContextExtensions.Export(this.serializationManager)); //set partition key eventData.SetPartitionKey(this.StreamId.Guid.ToString()); //set offset DateTime now = DateTime.UtcNow; var offSet = this.StreamId.Guid.ToString() + now.ToString(); eventData.SetOffset(offSet); //set sequence number eventData.SetSequenceNumber(this.SequenceNumberCounter.Value); //set enqueue time eventData.SetEnqueuedTimeUtc(now); eventDataList.Add(eventData); this.logger.Info($"Generate data of SequemceNumber {SequenceNumberCounter.Value} for stream {this.StreamId.Namespace}-{this.StreamId.Guid}"); } events = eventDataList; return(eventDataList.Count > 0); }
public Task OnNextBatchAsync(IEnumerable <T> batch, StreamSequenceToken token) { return(this.queueAdapter.QueueMessageBatchAsync(this.stream.StreamId, batch, token, RequestContextExtensions.Export(this.deepCopier))); }
public Task OnNextAsync(T item, StreamSequenceToken token) { return(this.queueAdapter.QueueMessageAsync(this.stream.StreamId, item, token, RequestContextExtensions.Export(this.deepCopier))); }