private Task <ProactiveReplicationResult> ProactiveReplicationIterationAsync( OperationContext context, ReadOnlyDistributedContentSession <T> proactiveCopySession, ILocalContentStore localContentStore, TransitioningContentLocationStore contentLocationStore) { return(context.PerformOperationAsync( Tracer, async() => { // Important to yield as GetContentInfoAsync has a synchronous implementation. await Task.Yield(); var localContent = (await localContentStore.GetContentInfoAsync(context.Token)) .OrderByDescending(info => info.LastAccessTimeUtc) // GetHashesInEvictionOrder expects entries to already be ordered by last access time. .Select(info => new ContentHashWithLastAccessTimeAndReplicaCount(info.ContentHash, info.LastAccessTimeUtc)) .ToArray(); var contents = contentLocationStore.GetHashesInEvictionOrder(context, localContent, reverse: true); var succeeded = 0; var failed = 0; var skipped = 0; var scanned = 0; var rejected = 0; var delayTask = Task.CompletedTask; var wasPreviousCopyNeeded = true; ContentEvictionInfo?lastVisited = default; IEnumerable <ContentEvictionInfo> getReplicableHashes() { foreach (var content in contents) { scanned++; if (content.ReplicaCount < _settings.ProactiveCopyLocationsThreshold) { yield return content; } else { CounterCollection[Counters.ProactiveReplication_Skipped].Increment(); skipped++; } } } foreach (var page in getReplicableHashes().GetPages(_settings.ProactiveCopyGetBulkBatchSize)) { var contentInfos = await proactiveCopySession.GetLocationsForProactiveCopyAsync(context, page.SelectList(c => c.ContentHash)); for (int i = 0; i < contentInfos.Count; i++) { context.Token.ThrowIfCancellationRequested(); var contentInfo = contentInfos[i]; lastVisited = page[i]; if (wasPreviousCopyNeeded) { await delayTask; delayTask = Task.Delay(_settings.DelayForProactiveReplication, context.Token); } var result = await proactiveCopySession.ProactiveCopyIfNeededAsync( context, contentInfo, tryBuildRing: false, reason: CopyReason.Replication); wasPreviousCopyNeeded = true; switch (result.Status) { case ProactiveCopyStatus.Success: CounterCollection[Counters.ProactiveReplication_Succeeded].Increment(); succeeded++; break; case ProactiveCopyStatus.Skipped: CounterCollection[Counters.ProactiveReplication_Skipped].Increment(); skipped++; wasPreviousCopyNeeded = false; break; case ProactiveCopyStatus.Rejected: rejected++; CounterCollection[Counters.ProactiveReplication_Rejected].Increment(); break; case ProactiveCopyStatus.Error: CounterCollection[Counters.ProactiveReplication_Failed].Increment(); failed++; break; } if ((succeeded + failed) >= _settings.ProactiveReplicationCopyLimit) { break; } } if ((succeeded + failed) >= _settings.ProactiveReplicationCopyLimit) { break; } } return new ProactiveReplicationResult(succeeded, failed, skipped, rejected, localContent.Length, scanned, lastVisited); },
private Task <ProactiveReplicationResult> ProactiveReplicationIterationAsync( OperationContext context, ILocalContentStore localContentStore, TransitioningContentLocationStore contentLocationStore) { return(context.PerformOperationAsync( Tracer, async() => { // Important to yield as GetContentInfoAsync has a synchronous implementation. await Task.Yield(); var localContent = (await localContentStore.GetContentInfoAsync(context.Token)) .OrderByDescending(info => info.LastAccessTimeUtc) // GetHashesInEvictionOrder expects entries to already be ordered by last access time. .Select(info => new ContentHashWithLastAccessTimeAndReplicaCount(info.ContentHash, info.LastAccessTimeUtc)) .ToArray(); var contents = contentLocationStore.GetHashesInEvictionOrder(context, localContent, reverse: true); var succeeded = 0; var failed = 0; var skipped = 0; var scanned = 0; var rejected = 0; var delayTask = Task.CompletedTask; var wasPreviousCopyNeeded = true; ContentEvictionInfo?lastVisited = default; foreach (var content in contents) { context.Token.ThrowIfCancellationRequested(); lastVisited = content; scanned++; if (content.ReplicaCount < _settings.ProactiveCopyLocationsThreshold) { if (wasPreviousCopyNeeded) { await delayTask; delayTask = Task.Delay(_settings.DelayForProactiveReplication, context.Token); } var result = await ProactiveCopyIfNeededAsync(context, content.ContentHash); wasPreviousCopyNeeded = true; switch (result.Status) { case ProactiveCopyStatus.Success: CounterCollection[Counters.ProactiveReplication_Succeeded].Increment(); succeeded++; break; case ProactiveCopyStatus.Skipped: CounterCollection[Counters.ProactiveReplication_Skipped].Increment(); skipped++; wasPreviousCopyNeeded = false; break; case ProactiveCopyStatus.Rejected: rejected++; CounterCollection[Counters.ProactiveReplication_Succeeded].Increment(); break; case ProactiveCopyStatus.Error: CounterCollection[Counters.ProactiveReplication_Failed].Increment(); failed++; break; } if ((succeeded + failed) >= _settings.ProactiveReplicationCopyLimit) { break; } } } return new ProactiveReplicationResult(succeeded, failed, skipped, rejected, localContent.Length, scanned, lastVisited); },