/// <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 async Task <Possible <CasEntries, Failure> > GetCacheEntryAsync(StrongFingerprint strong, UrgencyHint urgencyHint, Guid activityId) { var hashListResult = await ReadOnlyCacheSession.GetContentHashListAsync( new Context(Logger), new BuildXL.Cache.MemoizationStore.Interfaces.Sessions.StrongFingerprint( strong.WeakFingerprint.ToMemoization(), new Selector(strong.CasElement.ToMemoization(), strong.HashElement.RawHash.ToByteArray())), CancellationToken.None); if (hashListResult.Succeeded) { if (hashListResult.ContentHashListWithDeterminism.ContentHashList == null) { return(new NoMatchingFingerprintFailure(strong)); } SessionEntries?.TryAdd(strong, 1); return(hashListResult.ContentHashListWithDeterminism.FromMemoization()); } else { return(new CacheFailure(hashListResult.ErrorMessage)); } }