public async Task TestIisHostReceiver() { touched = 0; CancellationTokenSource tokenSource = new CancellationTokenSource(); // Start the listener on another thread. Task t = await Task.Factory.StartNew(Listener2, tokenSource.Token); var stopwatch = new Stopwatch(); Assert.Equal(0, Interlocked.Read(ref touched)); var messages = new List <Message>(); var tags = new Dictionary <string, string> { { "key", "value" } }; for (int i = 0; i < 1000; i++) { messages.Add( new Message("Order.Test.OutQ.Listener", Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()), string.Empty, Guid.NewGuid().ToString(), tags) ); } Assert.Equal(0, Interlocked.Read(ref touched)); QueueStream queue = new QueueStream("localhost:50000", "Demo.Test.IISHost", null); stopwatch.Start(); await queue.Send(new SendRequest(messages)); stopwatch.Stop(); Logger.Technical().Debug($"Messages sent in {stopwatch.ElapsedMilliseconds} ms.").Log(); stopwatch.Reset(); stopwatch.Start(); do { await Task.Delay(10); } while (Interlocked.Read(ref touched) < 1000 && stopwatch.ElapsedMilliseconds < 10000); stopwatch.Stop(); Logger.Technical().Debug($"Messages read in {stopwatch.ElapsedMilliseconds} ms.").Log(); tokenSource.Cancel(); await Task.Delay(150); Assert.Equal(1000, Interlocked.Read(ref touched)); Task.WaitAll(t); queue.Close(); }
/// <summary> /// All the messages must be of the same type. /// </summary> /// <param name="messages"></param> private void SendToQueueInBatch(IEnumerable <QueueMessage> messages) { using (var activity = _activitySource?.StartActivity("Send messages to KubeMQ", ActivityKind.Producer)) { var definition = GetDefiniton(messages.First().Value.GetType()); var policy = definition.RetryPolicy(Policy.Handle <Exception>()); QueueStream queue = null; policy.Execute(() => queue = _queueStreamManager.Get(definition)); if (null == queue) { throw new NullReferenceException($"No queue was created for Address: {definition.Address} and Identitfier {definition.Identifier}"); } var serializer = GetSerializer(definition); var _messages = new List <Message>(messages.Count()); string activityId = _applicationContext?.Principal?.ActivityID.ToString() ?? Guid.NewGuid().ToString(); using (var serializerActivity = _activitySource?.StartActivity("Serialize.", ActivityKind.Producer)) { serializerActivity?.AddTag("Count", messages.Count()); // I use messageType because we consider that we send a message of the same type... // Doing it by ChannelParameter will be more efficient... foreach (var message in messages) { _messages.Add( new Message(definition.Namespace, serializer.Serialize(message.Value), String.Empty, Guid.NewGuid().ToString(), BuildTags(message.Value.GetType(), message.Tags, activityId)) { Policy = BuildPolicy(definition, message.SendAfterSeconds, message.ExpireAfterSeconds) } ); } } policy.Execute(() => { using (var sendActivity = _activitySource?.StartActivity("Send to KubeMQ", ActivityKind.Producer)) queue.Send(new SendRequest(_messages)); }); } }
public void Send <TMessage>(TMessage message, Dictionary <string, string> tags = null, uint?sendAfterSeconds = null, uint?expireAfterSeconds = null) where TMessage : notnull { using (var activity = _activitySource?.StartActivity("Send message to KubeMQ", ActivityKind.Producer)) { activity?.AddTag("Delay message [s]", sendAfterSeconds); activity?.AddTag("Expire message after [s]", expireAfterSeconds); if (message is IEnumerable) { throw new ArgumentException("Collection are not accepted!"); } var messageType = typeof(TMessage); var definition = GetDefiniton(messageType); var policy = definition.RetryPolicy(Policy.Handle <Exception>()); QueueStream queue = null; policy.Execute(() => queue = _queueStreamManager.Get(definition)); if (null == queue) { throw new NullReferenceException($"No queue was created for Address: {definition.Address} and Identitfier {definition.Identifier}"); } var serializer = GetSerializer(definition); string activityId = _applicationContext?.Principal?.ActivityID.ToString() ?? Guid.NewGuid().ToString(); Message _message = null; using (var serializerActivity = _activitySource?.StartActivity("Serialize.", ActivityKind.Producer)) _message = new Message(definition.Namespace, serializer.Serialize(message), String.Empty, Guid.NewGuid().ToString(), BuildTags(messageType, tags, activityId)) { Policy = BuildPolicy(definition, sendAfterSeconds, expireAfterSeconds) }; using (var sendActivity = _activitySource?.StartActivity("Send to KubeMQ", ActivityKind.Producer)) queue.Send(new SendRequest(new List <Message>(1) { _message })); } }
public async Task TestBasicSendAndReceive() { QueueStream queue = new QueueStream("localhost:50000", "Demo.Test.Basic", null); var messages = new List <Message>(); var tags = new Dictionary <string, string> { { "key", "value" } }; for (int i = 0; i < 1000; i++) { messages.Add( new Message("Order.Test.OutQ.Basic", Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()), string.Empty, Guid.NewGuid().ToString(), tags) ); } var res = await queue.Send(new SendRequest(messages)); PollRequest pollRequest = new() { Queue = "Order.Test.OutQ.Basic", WaitTimeout = 1000, MaxItems = 100, AutoAck = false }; var read = 0; while (read < 1000) { PollResponse response = await queue.Poll(pollRequest); if (!response.HasMessages) { continue; } Logger.Technical().Debug($"{response.Messages.Count()} message(s) received from the PollResponse.").Log(); Parallel.ForEach(response.Messages, msg => { try { Assert.Equal(1, msg.Tags.Count()); Assert.True(Guid.TryParse(Encoding.UTF8.GetString(msg.Body), out var guid)); msg.Ack(); } catch (Exception) { msg.NAck(); } }); read += response.Messages.Count(); } Assert.Equal(1000, read); queue.Close(); }
private void SendToQueueInBatch(IEnumerable <QueueMessage> messages, int splitByQueues) { using (var activity = _activitySource?.StartActivity("Send messages to KubeMQ", ActivityKind.Producer)) { activity?.AddTag("Split", splitByQueues); if (splitByQueues < 2) { throw new ArgumentOutOfRangeException("Number of queues must be greater than 1!"); } if (splitByQueues > 10) { splitByQueues = 10; _logger.Technical().Warning("Cap the number of queues to 10").Log(); } var messageType = messages.First().Value.GetType(); // All the messages are assumed to be of the same type. var definition = GetDefiniton(messageType); var policy = definition.RetryPolicy(Policy.Handle <Exception>()); QueueStream queue = null; policy.Execute(() => queue = _queueStreamManager.Get(definition)); if (null == queue) { throw new NullReferenceException($"No queue was created for Address: {definition.Address} and Identitfier {definition.Identifier}"); } var serializer = GetSerializer(definition); string activityId = _applicationContext?.Principal?.ActivityID.ToString() ?? Guid.NewGuid().ToString(); var messagesByQueue = Math.DivRem(messages.Count(), splitByQueues, out var rem); var _messages = new List <Message>(messagesByQueue + rem); int idx = 0; int queueIdx = 1; foreach (var message in messages) { using (var createactivity = _activitySource?.StartActivity("Create KubeMQ messages", ActivityKind.Producer)) { createactivity?.AddTag("Count", messages.Count()); createactivity?.AddTag("QueueName", $"{definition.Namespace}.{queueIdx}"); _messages.Add( new Message($"{definition.Namespace}.{queueIdx}", serializer.Serialize(message.Value), String.Empty, Guid.NewGuid().ToString(), BuildTags(messageType, message.Tags, activityId)) { Policy = BuildPolicy(definition, message.SendAfterSeconds, message.ExpireAfterSeconds) } ); } idx++; if (0 == idx % messagesByQueue) // we have on batch. { policy.Execute(() => { using (var sendActivity = _activitySource?.StartActivity("Send to KubeMQ", ActivityKind.Producer)) queue.Send(new SendRequest(_messages)); }); queueIdx++; idx = 0; _messages.Clear(); } } } }