/// <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()}")));
        }
예제 #2
0
        /// <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));
            }
        }