示例#1
0
            // Process all messages for a particular client
            async Task <ISinkResult <IRoutingMessage> > ProcessClientMessages(string id, List <IRoutingMessage> routingMessages, CancellationToken token)
            {
                var succeeded = new List <IRoutingMessage>();
                var failed    = new List <IRoutingMessage>();
                var invalid   = new List <InvalidDetails <IRoutingMessage> >();

                Devices.Routing.Core.Util.Option <SendFailureDetails> sendFailureDetails =
                    Option.None <SendFailureDetails>();

                // Find the maximum message size, and divide messages into largest batches
                // not exceeding max allowed IoTHub message size.
                long maxMessageSize = routingMessages.Select(r => r.Size()).Max();
                int  batchSize      = GetBatchSize(Math.Min(this.cloudEndpoint.maxBatchSize, routingMessages.Count), maxMessageSize);

                foreach (IEnumerable <IRoutingMessage> batch in routingMessages.Batch(batchSize))
                {
                    ISinkResult res = await this.ProcessClientMessagesBatch(id, batch.ToList(), token);

                    succeeded.AddRange(res.Succeeded);
                    failed.AddRange(res.Failed);
                    invalid.AddRange(res.InvalidDetailsList);
                    sendFailureDetails = res.SendFailureDetails;
                }

                return(new SinkResult <IRoutingMessage>(
                           succeeded,
                           failed,
                           invalid,
                           sendFailureDetails.GetOrElse(null)));
            }
示例#2
0
            public async Task <ISinkResult> ProcessAsync(ICollection <IRoutingMessage> routingMessages, CancellationToken token)
            {
                Preconditions.CheckNotNull(routingMessages, nameof(routingMessages));
                var succeeded = new List <IRoutingMessage>();
                var failed    = new List <IRoutingMessage>();
                var invalid   = new List <InvalidDetails <IRoutingMessage> >();

                Devices.Routing.Core.Util.Option <SendFailureDetails> sendFailureDetails =
                    Option.None <SendFailureDetails>();

                Events.ProcessingMessages(routingMessages);
                foreach (IRoutingMessage routingMessage in routingMessages)
                {
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }

                    ISinkResult res = await this.ProcessAsync(routingMessage, token);

                    succeeded.AddRange(res.Succeeded);
                    failed.AddRange(res.Failed);
                    invalid.AddRange(res.InvalidDetailsList);
                    sendFailureDetails = res.SendFailureDetails;
                }

                return(new SinkResult <IRoutingMessage>(
                           succeeded,
                           failed,
                           invalid,
                           sendFailureDetails.GetOrElse(null)));
            }
示例#3
0
            async Task <ISinkResult> ProcessByClients(ICollection <IRoutingMessage> routingMessages, CancellationToken token)
            {
                var routingMessageGroups = (from r in routingMessages
                                            group r by this.GetIdentity(r)
                                            into g
                                            select new { Id = g.Key, RoutingMessages = g.ToList() })
                                           .ToList();

                var succeeded = new List <IRoutingMessage>();
                var failed    = new List <IRoutingMessage>();
                var invalid   = new List <InvalidDetails <IRoutingMessage> >();

                Devices.Routing.Core.Util.Option <SendFailureDetails> sendFailureDetails =
                    Option.None <SendFailureDetails>();

                Events.ProcessingMessageGroups(routingMessages, routingMessageGroups.Count, this.cloudEndpoint.FanOutFactor);

                foreach (var groupBatch in routingMessageGroups.Batch(this.cloudEndpoint.FanOutFactor))
                {
                    IEnumerable <Task <ISinkResult <IRoutingMessage> > > sendTasks = groupBatch
                                                                                     .Select(item => this.ProcessClientMessages(item.Id, item.RoutingMessages, token));
                    ISinkResult <IRoutingMessage>[] sinkResults = await Task.WhenAll(sendTasks);

                    foreach (ISinkResult <IRoutingMessage> res in sinkResults)
                    {
                        succeeded.AddRange(res.Succeeded);
                        failed.AddRange(res.Failed);
                        invalid.AddRange(res.InvalidDetailsList);
                        // Different branches could have different results, but only the first one will be reported
                        if (!sendFailureDetails.HasValue)
                        {
                            sendFailureDetails = res.SendFailureDetails;
                        }
                    }
                }

                return(new SinkResult <IRoutingMessage>(
                           succeeded,
                           failed,
                           invalid,
                           sendFailureDetails.GetOrElse(null)));
            }