private async Task <bool> ProcessNextMessageAsync(PerWorkerContext workerContext, int batchSize) { var batchContext = new PerBatchContext(workerContext, UniqueName.New("batch")); var packageIdentities = new HashSet <string>(StringComparer.OrdinalIgnoreCase); var messages = new List <StorageQueueMessage <PackageMessage> >(); var packageContexts = new List <PerPackageContext>(); StorageQueueMessage <PackageMessage> lastMessage; do { lastMessage = await _queue.GetNextAsync(CancellationToken.None); if (lastMessage != null) { var packageId = lastMessage.Contents.PackageId.Trim(); var packageVersion = NuGetVersion.Parse(lastMessage.Contents.PackageVersion.Trim()).ToNormalizedString(); var packageIdentity = $"{packageId}/{packageVersion}"; // If this is a duplicate package, complete it and skip it. if (!packageIdentities.Add(packageIdentity)) { await _queue.RemoveAsync(lastMessage, CancellationToken.None); continue; } messages.Add(lastMessage); packageContexts.Add(new PerPackageContext(batchContext, packageId, packageVersion)); } }while (messages.Count < batchSize && lastMessage != null && lastMessage.DequeueCount < 10); if (packageContexts.Count == 0) { return(false); } var complete = await ProcessPackagesAsync(batchContext, packageContexts); if (complete) { foreach (var message in messages) { try { await _queue.RemoveAsync(message, CancellationToken.None); } catch (StorageException ex) when(ex.RequestInformation?.HttpStatusCode == (int)HttpStatusCode.NotFound) { // Ignore this error. The message has already been removed. } } } return(true); }
public async Task ProcessAsync(PerWorkerContext workerContext, int messageCount) { bool hasMoreMessages; var processed = 0; do { var currentBatchSize = Math.Min(workerContext.Process.BatchSize, messageCount - processed); hasMoreMessages = await ProcessNextMessageAsync(workerContext, currentBatchSize); processed += currentBatchSize; }while (hasMoreMessages && processed < messageCount); }
private async Task ProcessPerWorkerAsync(PerProcessContext processContext, int messageCount) { var context = new PerWorkerContext(processContext, UniqueName.New("worker")); await _perWorkerProcessor.ProcessAsync(context, messageCount); }