/// <inheritdoc /> protected override Task <IEnumerable <Task <Indexed <PlaceFileResult> > > > PlaceFileCoreAsync(OperationContext operationContext, IReadOnlyList <ContentHashWithPath> hashesWithPaths, FileAccessMode accessMode, FileReplacementMode replacementMode, FileRealizationMode realizationMode, UrgencyHint urgencyHint, Counter retryCounter) => Task.FromResult(hashesWithPaths.Select((hash, i) => Task.FromResult(new PlaceFileResult(PlaceFileResult.ResultCode.NotPlacedContentNotFound).WithIndex(i))));
public async Task <Possible <FullCacheRecordWithDeterminism, Failure> > AddOrGetAsync(WeakFingerprintHash weak, CasHash casElement, Hash hashElement, CasEntries hashes, UrgencyHint urgencyHint, Guid activityId) { Contract.Requires(!IsClosed); Contract.Requires(hashes.IsValid); Contract.Assert(!IsReadOnly); using (var counter = m_counters.AddOrGetCounter()) { using (var eventing = new AddOrGetActivity(BasicFilesystemCache.EventSource, activityId, this)) { eventing.Start(weak, casElement, hashElement, hashes, urgencyHint); counter.SetEntriesCount(hashes.Count); // The size of what we are adding (effectively) // We check the Cas entries if we are strict if (StrictMetadataCasCoupling) { // Check that the content is valid. if (!m_pinnedToCas.ContainsKey(casElement)) { counter.Failed(); return(eventing.StopFailure(new UnpinnedCasEntryFailure(CacheId, casElement))); } foreach (CasHash hash in hashes) { if (!m_pinnedToCas.ContainsKey(hash)) { counter.Failed(); return(eventing.StopFailure(new UnpinnedCasEntryFailure(CacheId, hash))); } } } StrongFingerprint strong = new StrongFingerprint(weak, casElement, hashElement, CacheId); // Assume we accepted the Add and there is nothing to return FullCacheRecord result = null; string strongFingerprintName = m_cache.GetStrongFingerprintFilename(strong); try { using (FileStream file = await m_cache.ContendedOpenStreamAsync(strongFingerprintName, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { // The compiler thinks that it is not assigned down below at the end // even though it would be set by the writeEntries being true in that case CasEntries oldCasEntries = hashes; // Assume we will write our new enties to the file. bool writeEntries = true; // If there is some data in the file already, we need to try to read it. if (file.Length > 0) { var possibleOldCasEntries = await m_cache.ReadCacheEntryAsync(file); // Only if it was formatted correctly do we continue to check if // we should replace it. if (possibleOldCasEntries.Succeeded) { oldCasEntries = possibleOldCasEntries.Result; writeEntries = false; // We can only replace if both or neither is SinglePhaseNonDeterministic if (oldCasEntries.Determinism.IsSinglePhaseNonDeterministic != hashes.Determinism.IsSinglePhaseNonDeterministic) { counter.Failed(); return(eventing.StopFailure(new SinglePhaseMixingFailure(CacheId))); } // Should we replace? if (hashes.Determinism.IsSinglePhaseNonDeterministic || (!oldCasEntries.Determinism.IsDeterministicTool && (hashes.Determinism.IsDeterministic && !oldCasEntries.Determinism.Equals(hashes.Determinism)))) { // We are replacing due to determinism counter.Det(); writeEntries = true; } else if (HasMissingContent(oldCasEntries)) { counter.Repair(); writeEntries = true; } else if (oldCasEntries.Determinism.IsDeterministicTool && hashes.Determinism.IsDeterministicTool && !oldCasEntries.Equals(hashes)) { // We have a non-deterministic tool! counter.Failed(); return(eventing.StopFailure(new NotDeterministicFailure(CacheId, new FullCacheRecord(strong, oldCasEntries), new FullCacheRecord(strong, hashes)))); } } } // Are we going to write the entries? if (writeEntries) { // We are writing so the old entries don't count oldCasEntries = hashes; // Write from the front file.SetLength(0); await m_cache.WriteCacheEntryAsync(file, hashes); } else { counter.Dup(); } // If what is in the cache is different than what we are // asking to add, build a FullCacheRecord to return what // is in the cache. if (!oldCasEntries.Equals(hashes)) { counter.Get(); result = new FullCacheRecord(strong, oldCasEntries); } } } catch (Exception e) { counter.Failed(); return(eventing.StopFailure(new StrongFingerprintAccessFailure(m_cache.CacheId, strong, e))); } AddSessionRecord(strong); if (result != null) { return (eventing.Returns( new FullCacheRecordWithDeterminism( new FullCacheRecord( result.StrongFingerprint, result.CasEntries.GetModifiedCasEntriesWithDeterminism( m_cache.IsAuthoritative, m_cache.CacheGuid, CacheDeterminism.NeverExpires))))); } else { return(eventing.Returns(new FullCacheRecordWithDeterminism(hashes.GetFinalDeterminism(m_cache.IsAuthoritative, m_cache.CacheGuid, DateTime.UtcNow.Add(m_cache.TimeToLive))))); } } } }
/// <inheritdoc /> public Task <GetContentHashListResult> GetContentHashListAsync( Context context, StrongFingerprint strongFingerprint, CancellationToken cts, UrgencyHint urgencyHint) { return(_memoizationReadOnlySession.GetContentHashListAsync(context, strongFingerprint, cts, urgencyHint)); }
public async Task <Possible <string, Failure>[]> PinToCasAsync(CasEntries casEntries, UrgencyHint urgencyHint, Guid activityId) { Contract.Requires(!IsClosed); Contract.Requires(casEntries.IsValid); using (var eventing = new PinToCasMultipleActivity(BasicFilesystemCache.EventSource, activityId, this)) { eventing.Start(casEntries, urgencyHint); // First, initiate all of the operations var taskValues = new Task <Possible <string, Failure> > [casEntries.Count]; for (int i = 0; i < casEntries.Count; i++) { taskValues[i] = PinToCasAsync(casEntries[i], urgencyHint, activityId); } // Now await them all (since they can run in parallel var results = new Possible <string, Failure> [casEntries.Count]; for (int i = 0; i < casEntries.Count; i++) { results[i] = await taskValues[i]; } // All return results are actually traced via the per-hash call of PinToCas return(eventing.Returns(results)); } }
public async Task <Possible <CasHash, Failure> > AddToCasAsync(Stream filestream, CasHash?hash, UrgencyHint urgencyHint, Guid activityId) { Contract.Requires(!IsClosed); Contract.Requires(filestream != null); Contract.Assert(!IsReadOnly); // We have this interesting issue - we are not sure if the stream is rewindable // and the target CAS may not be local so we will end up streaming this to // a temporary file just to pass it up. (Implementation detail) using (var counter = m_counters.AddToCasCounterStream()) { using (var eventing = new AddToCasStreamActivity(BasicFilesystemCache.EventSource, activityId, this)) { eventing.Start(filestream, urgencyHint); Possible <CasHash, Failure> result; string tmpFile = await m_cache.CreateTempFile(); // Since these are longer operations that are synchronous, we wrap them // into a task for potential parallelism try { CasHash casHash = await HashStreamToFileAsync(filestream, tmpFile); try { counter.ContentSize(new FileInfo(tmpFile).Length); if (!await m_cache.AddToCasAsync(tmpFile, casHash)) { counter.DuplicatedContent(); } // Pin it and return the hash m_pinnedToCas.TryAdd(casHash, 0); result = casHash; } catch (Exception e) { counter.Failed(); result = new AddToCasFailure(CacheId, casHash, "<stream>", e); } } catch (Exception e) { counter.Failed(); result = new HashFailure(CacheId, "<stream>", e); } finally { try { File.Delete(tmpFile); } #pragma warning disable ERP022 // TODO: This should really handle specific errors catch { // Ignore the failure - it is likely caused by // a semantic breaking tool such as most virus scanners // or disk indexers. The file was a local teporary file // in the temp directory } #pragma warning restore ERP022 // Unobserved exception in generic exception handler } return(eventing.Returns(result)); } } }
protected override async Task <IEnumerable <Task <Indexed <PinResult> > > > PinCoreAsync(OperationContext context, IReadOnlyList <ContentHash> contentHashes, UrgencyHint urgencyHint, Counter retryCounter, Counter fileCounter) { try { var endDateTime = DateTime.UtcNow + TimeToKeepContent; return(await Workflows.RunWithFallback( contentHashes, hashes => CheckInMemoryCaches(hashes, endDateTime), hashes => UpdateBlobStoreAsync(context, hashes, endDateTime), result => result.Succeeded)); } catch (Exception ex) { context.TracingContext.Warning($"Exception when querying pins against the VSTS services {ex}"); return(contentHashes.Select((_, index) => Task.FromResult(new PinResult(ex).WithIndex(index)))); } }
public IEnumerable <Task <Possible <StrongFingerprint, Failure> > > EnumerateStrongFingerprints(WeakFingerprintHash weak, UrgencyHint urgencyHint, Guid activityId) { Contract.Requires(!IsClosed); using (var counter = m_counters.EnumerateStrongFingerprintsCounter()) { using (var eventing = new EnumerateStrongFingerprintsActivity(BasicFilesystemCache.EventSource, activityId, this)) { eventing.Start(weak, urgencyHint); // It's possible the cache could encounter an IO error when attempting to enumerate the fingerprints. // This shouldn't be a fatal error. we just want to catch and record it, then continue on. // Due to the use of yield a foreach loop can't be used here while still handling the error, // so the enumation must be done manually. using (var enumerator = m_cache.EnumerateStrongFingerprints(weak).GetEnumerator()) { while (true) { StrongFingerprint strong = null; try { if (!enumerator.MoveNext()) { break; } strong = enumerator.Current; } catch (IOException ex) { eventing.StopFailure(new StrongFingerprintEnumerationFailure(m_cache.CacheId, weak, ex)); yield break; } catch (UnauthorizedAccessException ex) { eventing.StopFailure(new StrongFingerprintEnumerationFailure(m_cache.CacheId, weak, ex)); yield break; } counter.YieldReturn(); yield return(Task.FromResult(new Possible <StrongFingerprint, Failure>(strong))); } } eventing.Stop(); } } }
/// <inheritdoc /> public Task <GetContentHashListResult> GetContentHashListAsync(Context context, StrongFingerprint strongFingerprint, CancellationToken cts, UrgencyHint urgencyHint = UrgencyHint.Nominal) { return(PerformOperationAsync( context, cts, (ctx, client) => client.GetContentHashListAsync(ctx, strongFingerprint), counter: _memoizationCounters[MemoizationStoreCounters.GetContentHashList], retryCounter: _memoizationCounters[MemoizationStoreCounters.GetContentHashListRetries])); }
/// <inheritdoc /> public Task <GetContentHashListResult> GetContentHashListAsync(Context context, StrongFingerprint strongFingerprint, CancellationToken cts, UrgencyHint urgencyHint) { return(WithOperationContext( context, cts, operationContext => operationContext.PerformOperationAsync( DistributedTracer, operation: async() => { GetContentHashListResult innerResult = null; // Get the value from the metadata cache or load the current inner value into it (and then return it) var existing = await MetadataCache.GetOrAddContentHashListAsync( context, strongFingerprint, async fingerprint => { innerResult = await _innerCacheSession.GetContentHashListAsync(context, fingerprint, cts, urgencyHint); return innerResult; }); // Check to see if we need to need to read through to the inner value. if (_readThroughMode == ReadThroughMode.ReadThrough && existing.Succeeded && !(existing.ContentHashListWithDeterminism.Determinism.IsDeterministic && existing.ContentHashListWithDeterminism.Determinism.Guid == _innerCacheId)) { // Read through to the inner cache because the metadata cache's value is not guaranteed to be backed. if (innerResult == null) { // We did not already query the inner cache as part of the original query, so do that now. innerResult = await _innerCacheSession.GetContentHashListAsync( context, strongFingerprint, cts, urgencyHint); } if (innerResult != null && innerResult.Succeeded && innerResult.ContentHashListWithDeterminism.Determinism.IsDeterministic) { // If the inner cache's value is now backed, clear the value from the metadata cache so that the // next read will load the backed value into the metadata cache (preventing the need for future read-throughs). await MetadataCache.DeleteFingerprintAsync(context, strongFingerprint).IgnoreFailure(); } return innerResult; } else { // Return the existing value in the metadata cache, or any error. return existing; } }, traceOperationStarted: true, extraStartMessage: $"StrongFingerprint=({strongFingerprint})", extraEndMessage: result => $"StrongFingerprint=({strongFingerprint}) {result.ContentHashListWithDeterminism.ToTraceString()}"))); }
/// <inheritdoc /> public System.Collections.Generic.IAsyncEnumerable <GetSelectorResult> GetSelectors(Context context, Fingerprint weakFingerprint, CancellationToken cts, UrgencyHint urgencyHint = UrgencyHint.Nominal) { _memoizationCounters[MemoizationStoreCounters.GetSelectorsCalls].Increment(); return(this.GetSelectorsAsAsyncEnumerable(context, weakFingerprint, cts, urgencyHint)); }
/// <inheritdoc /> public Task <BoolResult> IncorporateStrongFingerprintsAsync(Context context, IEnumerable <Task <StrongFingerprint> > strongFingerprints, CancellationToken cts, UrgencyHint urgencyHint = UrgencyHint.Nominal) { return(PerformOperationAsync( context, cts, (ctx, client) => client.IncorporateStrongFingerprintsAsync(ctx, strongFingerprints), counter: _memoizationCounters[MemoizationStoreCounters.IncorporateStrongFingerprints], retryCounter: _memoizationCounters[MemoizationStoreCounters.IncorporateStrongFingerprintsRetries])); }
/// <inheritdoc /> protected override async Task <PutResult> PutStreamCoreAsync(OperationContext context, HashType hashType, Stream stream, UrgencyHint urgencyHint, Counter retryCounter) { if (!hashType.IsValidDedup()) { return(new PutResult( new ContentHash(hashType), $"DedupStore client requires a HashType that supports dedup. Given hash type: {hashType}")); } try { var tempFile = TempDirectory.CreateRandomFileName().Path; using (Stream writer = new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.Asynchronous | FileOptions.SequentialScan)) { await stream.CopyToAsync(writer); } // Cast is necessary because ContentSessionBase implements IContentSession explicitly return(await(this as IContentSession).PutFileAsync(context, hashType, new AbsolutePath(tempFile), FileRealizationMode.None, context.Token, urgencyHint)); } catch (Exception e) { return(new PutResult(e, new ContentHash(hashType))); } }
/// <inheritdoc /> protected override Task <PutResult> PutStreamCoreAsync(OperationContext operationContext, HashType hashType, Stream stream, UrgencyHint urgencyHint, Counter retryCounter) => Task.FromResult(new PutResult(new BoolResult(ErrorMessage)));
/// <inheritdoc /> protected override Task <PutResult> PutFileCoreAsync(OperationContext operationContext, ContentHash contentHash, AbsolutePath path, FileRealizationMode realizationMode, UrgencyHint urgencyHint, Counter retryCounter) => Task.FromResult(new PutResult(contentHash, ErrorMessage));
/// <inheritdoc /> public Task <BoolResult> TrimBulkAsync(Context context, IReadOnlyList <ContentHashAndLocations> contentHashToLocationMap, CancellationToken cts, UrgencyHint urgencyHint) { if (_redisContentLocationStore == null) { return(BoolResult.SuccessTask); } return(_redisContentLocationStore.TrimBulkAsync(context, contentHashToLocationMap, cts, urgencyHint)); }
/// <inheritdoc /> public Task <OpenStreamResult> OpenStreamAsync(Context context, ContentHash contentHash, CancellationToken cts, UrgencyHint urgencyHint) { return(_innerCacheSession.OpenStreamAsync(context, contentHash, cts, urgencyHint)); }
/// <inheritdoc /> protected override async Task <OpenStreamResult> OpenStreamCoreAsync( OperationContext context, ContentHash contentHash, UrgencyHint urgencyHint, Counter retryCounter) { if (contentHash.HashType != RequiredHashType) { return(new OpenStreamResult( $"BuildCache client requires HashType '{RequiredHashType}'. Cannot take HashType '{contentHash.HashType}'.")); } string tempFile = null; try { if (ImplicitPin == ImplicitPin.PutAndGet) { var pinResult = await PinAsync(context, contentHash, context.Token, urgencyHint).ConfigureAwait(false); if (!pinResult.Succeeded) { if (pinResult.Code == PinResult.ResultCode.ContentNotFound) { return(new OpenStreamResult(null)); } return(new OpenStreamResult(pinResult)); } } tempFile = TempDirectory.CreateRandomFileName().Path; var possibleLength = await PlaceFileInternalAsync(context, contentHash, tempFile, FileMode.Create).ConfigureAwait(false); if (possibleLength.HasValue) { return(new OpenStreamResult(new FileStream( tempFile, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete, StreamBufferSize, FileOptions.DeleteOnClose))); } return(new OpenStreamResult(null)); } catch (Exception e) { return(new OpenStreamResult(e)); } finally { if (tempFile != null) { try { File.Delete(tempFile); } catch (Exception e) { Tracer.Warning(context, $"Error deleting temporary file at {tempFile}: {e}"); } } } }
/// <inheritdoc /> public Task <PlaceFileResult> PlaceFileAsync(Context context, ContentHash contentHash, AbsolutePath path, FileAccessMode accessMode, FileReplacementMode replacementMode, FileRealizationMode realizationMode, CancellationToken cts, UrgencyHint urgencyHint) { return(_innerCacheSession.PlaceFileAsync(context, contentHash, path, accessMode, replacementMode, realizationMode, cts, urgencyHint)); }
/// <inheritdoc /> protected override Task <IEnumerable <Task <Indexed <PlaceFileResult> > > > PlaceFileCoreAsync(OperationContext context, IReadOnlyList <ContentHashWithPath> hashesWithPaths, FileAccessMode accessMode, FileReplacementMode replacementMode, FileRealizationMode realizationMode, UrgencyHint urgencyHint, Counter retryCounter) => throw new NotImplementedException();
/// <inheritdoc /> public Task <IEnumerable <Task <Indexed <PlaceFileResult> > > > PlaceFileAsync(Context context, IReadOnlyList <ContentHashWithPath> hashesWithPaths, FileAccessMode accessMode, FileReplacementMode replacementMode, FileRealizationMode realizationMode, CancellationToken cts, UrgencyHint urgencyHint = UrgencyHint.Nominal) { return(_innerCacheSession.PlaceFileAsync(context, hashesWithPaths, accessMode, replacementMode, realizationMode, cts, urgencyHint)); }
public async Task <Possible <CasEntries, Failure> > GetCacheEntryAsync(StrongFingerprint strong, UrgencyHint urgencyHint, Guid activityId) { Contract.Requires(!IsClosed); Contract.Requires(strong != null); using (var counter = m_counters.GetCacheEntryCounter()) { using (var eventing = new GetCacheEntryActivity(BasicFilesystemCache.EventSource, activityId, this)) { eventing.Start(strong, urgencyHint); var result = await m_cache.ReadCacheEntryAsync(strong); if (result.Succeeded) { AddSessionRecord(strong); counter.CacheHit(); result = result.Result.GetModifiedCasEntriesWithDeterminism(m_cache.IsAuthoritative, m_cache.CacheGuid, DateTime.UtcNow.Add(m_cache.TimeToLive)); } return(eventing.Returns(result)); } } }
/// <inheritdoc /> public Task <GetBulkLocationsResult> GetBulkAsync(Context context, IReadOnlyList <ContentHash> contentHashes, CancellationToken cts, UrgencyHint urgencyHint, GetBulkOrigin origin) { var operationContext = new OperationContext(context, cts); if (!_configuration.HasReadMode(ContentLocationMode.Redis) || (origin == GetBulkOrigin.Local && _configuration.HasReadMode(ContentLocationMode.LocalLocationStore))) { return(_localLocationStore.GetBulkAsync(operationContext, contentHashes, origin)); } Contract.Assert(_redisContentLocationStore != null, "Read or Write mode should support ContentLocationMode.Redis."); return(_redisContentLocationStore.GetBulkAsync(context, contentHashes, cts, urgencyHint, origin)); }
public async Task <Possible <ValidateContentStatus, Failure> > ValidateContentAsync(CasHash hash, UrgencyHint urgencyHint, Guid activityId) { Contract.Requires(!IsClosed); using (var counter = m_counters.ValidateSessionCounter()) { using (var eventing = new ValidateContentActivity(BasicFilesystemCache.EventSource, activityId, this)) { eventing.Start(hash, urgencyHint); if (CasHash.NoItem.Equals(hash)) { return(eventing.Returns(counter.Ok())); } string path = m_cache.ToPath(hash); try { // We don't use ProduceStream as this operation does not pin or cause pinning // and we want to have FileShare.Delete in case we need to delete this entry // due to it being corrupt. This way there is no race as to which file is // being deleted - it will be the one that was just determined to be corrupt. using (Stream fileData = await m_cache.ContendedOpenStreamAsync(path, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete, useAsync: true, handlePendingDelete: true)) { // Size of the file counter.FileSize(fileData.Length); CasHash contentHash = new CasHash(await ContentHashingUtilities.HashContentStreamAsync(fileData)); if (contentHash.Equals(hash)) { return(eventing.Returns(counter.Ok())); } // Remove it from pinned as it is being removed int junk; m_pinnedToCas.TryRemove(hash, out junk); // Now, we try to remediate - This is a simple delete attempt with any error // saying that we could not delete it try { File.Delete(path); eventing.Write(CacheActivity.CriticalDataOptions, new { RemovedCorruptedEntry = path }); return(eventing.Returns(counter.Remediated())); } catch (Exception e) { // Could not delete it (for what ever reason) eventing.Write(CacheActivity.CriticalDataOptions, new { FailedToRemovedCorruptedEntry = path, Reason = e.Message }); // The file failed to be deleted, so we need to say that it is still there return(eventing.Returns(counter.Invalid())); } } } catch (FileNotFoundException) { // Not found (either type) is the same as Remediated return(eventing.Returns(counter.Remediated())); } catch (DirectoryNotFoundException) { // Not found (either type) is the same as Remediated return(eventing.Returns(counter.Remediated())); } catch (Exception e) { // Other errors are reported as a failure to produce a stream of the data return(eventing.Returns(new ProduceStreamFailure(CacheId, hash, e))); } } } }
/// <inheritdoc /> public Task <BoolResult> TouchBulkAsync(Context context, IReadOnlyList <ContentHashWithSize> contentHashes, CancellationToken cts, UrgencyHint urgencyHint) { var operationContext = new OperationContext(context, cts); return(MultiExecuteAsync( executeLegacyStore: () => _redisContentLocationStore.TouchBulkAsync(context, contentHashes, cts, urgencyHint), executeLocalLocationStore: () => _localLocationStore.TouchBulkAsync(operationContext, contentHashes.SelectList(c => c.Hash)))); }
public async Task <Possible <CasHash, Failure> > AddToCasAsync( string filename, FileState fileState, CasHash?hash, UrgencyHint urgencyHint, Guid activityId) { Contract.Requires(!IsClosed); Contract.Requires(filename != null); Contract.Assert(!IsReadOnly); using (var counter = m_counters.AddToCasCounterFile()) { using (var eventing = new AddToCasFilenameActivity(BasicFilesystemCache.EventSource, activityId, this)) { eventing.Start(filename, fileState, urgencyHint); Possible <CasHash, Failure> result; // First we need to do the hash of the file // We do this "in place" since the CAS may be // on "slow" storage and this is local try { // We keep the file open during this such that others can't modify it // until the add-to-cas has completed. It also happens to be needed // in order to compute the hash. using (var fileData = await m_cache.ContendedOpenStreamAsync(filename, FileMode.Open, FileAccess.Read, FileShare.Read, handlePendingDelete: false)) { counter.ContentSize(fileData.Length); CasHash casHash = new CasHash(await ContentHashingUtilities.HashContentStreamAsync(fileData)); try { if (!await m_cache.AddToCasAsync(filename, casHash)) { counter.DuplicatedContent(); } // Pin it and return the hash m_pinnedToCas.TryAdd(casHash, 0); result = casHash; } catch (Exception e) { counter.Failed(); result = new AddToCasFailure(CacheId, casHash, filename, e); } } } catch (Exception e) { counter.Failed(); result = new HashFailure(CacheId, filename, e); } return(eventing.Returns(result)); } } }
/// <inheritdoc /> public Task <ObjectResult <IList <ContentHashWithLastAccessTimeAndReplicaCount> > > TrimOrGetLastAccessTimeAsync(Context context, IList <Tuple <ContentHashWithLastAccessTimeAndReplicaCount, bool> > contentHashesWithInfo, CancellationToken cts, UrgencyHint urgencyHint) { Contract.Assert(_redisContentLocationStore != null, "Read or Write mode should support ContentLocationMode.Redis."); return(_redisContentLocationStore.TrimOrGetLastAccessTimeAsync(context, contentHashesWithInfo, cts, urgencyHint)); }
/// <inheritdoc /> public IAsyncEnumerable <GetSelectorResult> GetSelectors(Context context, Fingerprint weakFingerprint, CancellationToken cts, UrgencyHint urgencyHint = UrgencyHint.Nominal) { return(this.GetSelectorsAsAsyncEnumerable(context, weakFingerprint, cts, urgencyHint)); }
/// <inheritdoc /> public Task <BoolResult> UpdateBulkAsync(Context context, IReadOnlyList <ContentHashWithSizeAndLocations> contentHashesWithSizeAndLocations, CancellationToken cts, UrgencyHint urgencyHint, LocationStoreOption locationStoreOption) { Contract.Assert(_redisContentLocationStore != null, "Read or Write mode should support ContentLocationMode.Redis."); return(_redisContentLocationStore.UpdateBulkAsync(context, contentHashesWithSizeAndLocations, cts, urgencyHint, locationStoreOption)); }
/// <inheritdoc /> public Task <PinResult> PinAsync(Context context, ContentHash contentHash, CancellationToken cts, UrgencyHint urgencyHint) { return(_contentReadOnlySession.PinAsync(context, contentHash, cts, urgencyHint)); }
/// <inheritdoc /> protected override Task <PlaceFileResult> PlaceFileCoreAsync(OperationContext operationContext, ContentHash contentHash, AbsolutePath path, FileAccessMode accessMode, FileReplacementMode replacementMode, FileRealizationMode realizationMode, UrgencyHint urgencyHint, Counter retryCounter) => Task.FromResult(new PlaceFileResult(PlaceFileResult.ResultCode.NotPlacedContentNotFound));