// Process all messages for a particular client async Task <ISinkResult <IRoutingMessage> > ProcessClientMessages(string id, List <IRoutingMessage> routingMessages, CancellationToken token) { var result = new MergingSinkResult <IRoutingMessage>(); // 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); var iterator = routingMessages.Batch(batchSize).GetEnumerator(); while (iterator.MoveNext()) { result.Merge(await this.ProcessClientMessagesBatch(id, iterator.Current.ToList(), token)); if (!result.IsSuccessful) { break; } } // if failed earlier, fast-fail the rest while (iterator.MoveNext()) { result.AddFailed(iterator.Current); } return(result); }
async Task <ISinkResult> ProcessByClients(ICollection <IRoutingMessage> routingMessages, CancellationToken token) { var result = new MergingSinkResult <IRoutingMessage>(); var routingMessageGroups = (from r in routingMessages group r by this.GetIdentity(r) into g select new { Id = g.Key, RoutingMessages = g.ToList() }) .ToList(); 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 (var res in sinkResults) { result.Merge(res); } } return(result); }