/// <summary> /// Gets the file corresponding to the given CasHash and checks /// to see if the file contents hash to the same CasHash value /// </summary> /// <param name="originalCasHash">CasHash value to check</param> /// <param name="errors">Where any cache errors found get stored</param> private async Task RehashContentsAsync(CasHash originalCasHash, ConcurrentDictionary <CacheError, int> errors) { if (originalCasHash.Equals(CasHash.NoItem)) { // No need to rehash the NoItem cas hash return; } Possible <StreamWithLength, Failure> possibleStream = await m_readOnlySession.GetStreamAsync(originalCasHash); if (!possibleStream.Succeeded) { errors.TryAdd(new CacheError(CacheErrorType.CasHashError, "CasHash " + originalCasHash + " not found in CAS"), 0); return; } using (StreamWithLength stream = possibleStream.Result) { ContentHash contentHash = await ContentHashingUtilities.HashContentStreamAsync(stream); Hash newHash = new Hash(contentHash); CasHash newCasHash = new CasHash(newHash); if (!originalCasHash.Equals(newCasHash)) { errors.TryAdd(new CacheError(CacheErrorType.CasHashError, "The data of CasHash " + originalCasHash + " has been altered in the CAS"), 0); } } }
/// <summary> /// Gets a file stream from the CAS either directly or by materlializing a file in the temp path and then opening it for read. /// </summary> /// <param name="hash">Hash for CAS entry</param> /// <param name="method">Method used to access CAS</param> /// <param name="session">Cache session</param> /// <returns>A stream pointing to the file contents, or a failure.</returns> private static async Task <Possible <StreamWithLength, Failure> > GetStreamAsync(CasHash hash, CasAccessMethod method, ICacheReadOnlySession session) { switch (method) { case CasAccessMethod.Stream: return(await session.GetStreamAsync(hash)); case CasAccessMethod.FileSystem: string filePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); string placedFilePath = await session.ProduceFileAsync(hash, filePath, FileState.ReadOnly).SuccessAsync(); XAssert.AreEqual(filePath, placedFilePath); FileStream fs = new FileStream(placedFilePath, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read); File.Delete(placedFilePath); return(fs.WithLength()); default: throw new NotImplementedException(); } }
public async Task <Possible <Stream, Failure> > GetStreamAsync(CasHash hash, UrgencyHint urgencyHint, Guid activityId) { using (var eventing = new GetStreamActivity(CompositingCache.EventSource, activityId, this)) { eventing.Start(hash, urgencyHint); return(eventing.Returns(await m_casSession.GetStreamAsync(hash, urgencyHint, eventing.Id))); } }
public Task <Possible <StreamWithLength, Failure> > GetStreamAsync(CasHash hash, UrgencyHint urgencyHint, Guid activityId) { var callback = GetStreamAsyncCallback; if (callback != null) { return(callback(hash, urgencyHint, activityId, m_realSession)); } else { return(m_realSession.GetStreamAsync(hash, urgencyHint, activityId)); } }
private async Task <long> PinAndGetStreamSize(ICacheReadOnlySession session, CasHash hash) { long result; await session.PinToCasAsync(hash, CancellationToken.None).SuccessAsync(); using (var stream = await session.GetStreamAsync(hash).SuccessAsync()) { result = stream.Length; } return(result); }
internal static async Task <Tuple <CasHash, long> > GetContentSizeAsync(this ICacheReadOnlySession session, CasHash casHash) { var possibleString = await session.PinToCasAsync(casHash); if (!possibleString.Succeeded) { return(new Tuple <CasHash, long>(casHash, (long)ContentError.UnableToPin)); } var possibleStream = await session.GetStreamAsync(casHash); if (!possibleStream.Succeeded) { return(new Tuple <CasHash, long>(casHash, (long)ContentError.UnableToStream)); } long length = possibleStream.Result.Length; possibleStream.Result.Dispose(); return(new Tuple <CasHash, long>(casHash, length)); }
public Task <Possible <StreamWithLength, Failure> > GetStreamAsync(CasHash hash, UrgencyHint urgencyHint, Guid activityId) { return(m_session.GetStreamAsync(hash, urgencyHint, activityId)); }
/// <summary> /// Takes a strong fingerprint and returns the deserialized contents of /// the input assertion list file that corresponds to it /// </summary> /// <param name="sfp">The strong fingerprint to get the input assertion /// list file contents for</param> /// <param name="cacheErrors">Any cache errors that are found will be /// added to this collection</param> /// <returns>Deserialized contents of the input assertion list file /// corresponding to the specified strong fingerprint</returns> private async Task <string> GetInputAssertionListFileContentsAsync(StrongFingerprint sfp, ConcurrentDictionary <CacheError, int> cacheErrors) { // Check for the NoItem if (sfp.CasElement.Equals(CasHash.NoItem)) { return(string.Empty); } // Pin the input assertion list file Possible <string, Failure> possibleString = await m_readOnlySession.PinToCasAsync(sfp.CasElement).ConfigureAwait(false); if (!possibleString.Succeeded) { return(string.Empty); } // Get the stream for the input assertion list file Possible <Stream, Failure> possibleStream = await m_readOnlySession.GetStreamAsync(sfp.CasElement).ConfigureAwait(false); if (!possibleStream.Succeeded) { cacheErrors.TryAdd( new CacheError( CacheErrorType.CasHashError, "The input assertion list for SFP " + sfp.ToString() + " was not found in CAS"), 0); return(string.Empty); } // Read the stream contents while hashing return(await Task.Run(() => { using (var hasher = ContentHashingUtilities.HashInfo.CreateContentHasher()) { using (var hashingStream = hasher.CreateReadHashingStream(possibleStream.Result)) { using (var reader = new BuildXLReader(false, hashingStream, false)) { var maybePathSet = ObservedPathSet.TryDeserialize(s_pathTable, reader); // Check if deserialization was successful if (!maybePathSet.Succeeded) { // Deserialization failed cacheErrors.TryAdd( new CacheError( CacheErrorType.CasHashError, "The input assertion list for SFP " + sfp.ToString() + " could not be deserialized"), 0); return string.Empty; } CasHash newCasHash = new CasHash(hashingStream.GetContentHash()); // Check if the hashes match if (!sfp.CasElement.Equals(newCasHash)) { cacheErrors.TryAdd( new CacheError( CacheErrorType.CasHashError, "The input assertion list for SFP " + sfp.ToString() + " has been altered in the CAS"), 0); return string.Empty; } // Deserialization was successful and file was unaltered StringBuilder fileContents = new StringBuilder(); foreach (ObservedPathEntry entry in maybePathSet.Result.Paths) { fileContents.Append(entry.Path.ToString(s_pathTable)).Append(Environment.NewLine); } return fileContents.ToString(); } } } }).ConfigureAwait(false)); }