public async Task <Possible <CasHash, Failure> > AddToCasAsync(Stream filestream, CasHash?hash, UrgencyHint urgencyHint, Guid activityId) { using (var eventing = new AddToCasStreamActivity(CompositingCache.EventSource, activityId, this)) { eventing.Start(filestream, urgencyHint); var result = await m_casSession.AddToCasAsync(filestream, hash, urgencyHint, eventing.Id); if (result.Succeeded) { PinnedToCas.TryAdd(result.Result, 0); } return(eventing.Returns(result)); } }
public async Task <Possible <FullCacheRecordWithDeterminism, Failure> > AddOrGetAsync(WeakFingerprintHash weak, CasHash casElement, Hash hashElement, CasEntries hashes, UrgencyHint urgencyHint, Guid activityId) { using (var eventing = new AddOrGetActivity(CompositingCache.EventSource, activityId, this)) { eventing.Start(weak, casElement, hashElement, hashes, urgencyHint); // First, check if all the content has been pinned. if (Cache.StrictMetadataCasCoupling) { List <CasHash> referencedHashes = new List <CasHash>(hashes); referencedHashes.Add(casElement); foreach (CasHash oneHash in referencedHashes) { if (!PinnedToCas.ContainsKey(oneHash)) { return(eventing.StopFailure(new UnpinnedCasEntryFailure(Cache.CacheId, oneHash))); } } } // Then check the determinism bit... var testStrongFingerprint = new StrongFingerprint(weak, casElement, hashElement, Cache.CacheId); var existRecordCheck = await m_metadataSession.GetCacheEntryAsync(testStrongFingerprint, urgencyHint, eventing.Id); if (existRecordCheck.Succeeded) { // There's an existing record, so we need the rules for determinism upgrade / downgrade. Which are complicated by the existance // (or lack there of) of the associated content. // First we'll check for determinism upgrades or other situations that don't require content probes. var existingRecord = existRecordCheck.Result; // If the determinsim is going from no determinism to some determinism OR the record is going from a non-tool // determinism to a tool determinism, replace if ((existingRecord.Determinism.IsNone && hashes.Determinism.IsDeterministic) || (hashes.Determinism.IsDeterministicTool && !existingRecord.Determinism.IsDeterministicTool)) { return(eventing.Returns(await m_metadataSession.AddOrGetAsync(weak, casElement, hashElement, hashes, urgencyHint, eventing.Id))); } // Before trying to probe for files, see if the entries are identical. // If so, tell the caller we stored their record. if (hashes == existingRecord && hashes.Determinism.EffectiveGuid == existingRecord.Determinism.EffectiveGuid) { return(eventing.Returns(new FullCacheRecordWithDeterminism(CacheDeterminism.None))); } // The rest of the determinism moves depend on if the files exist or not. bool foundAllFiles = true; var pinCheck = await m_casSession.PinToCasAsync(existRecordCheck.Result, urgencyHint, eventing.Id); foreach (var oneOutput in pinCheck) { if (!oneOutput.Succeeded) { foundAllFiles = false; } } // Ok, so now with the knowledge of file existance, if we're missing files, allow the call through no matter what. if (!foundAllFiles) { return(eventing.Returns(await m_metadataSession.AddOrGetAsync(weak, casElement, hashElement, hashes, urgencyHint, eventing.Id))); } // If the existing entry is more deterministic than what we're being given or // the records are the same level, unless tool deterministic or single phase. if ((existingRecord.Determinism.IsDeterministic && !hashes.Determinism.IsDeterministic) || (existingRecord.Determinism.IsDeterministicTool && !hashes.Determinism.IsDeterministicTool) || (existingRecord.Determinism.EffectiveGuid == hashes.Determinism.EffectiveGuid && !existingRecord.Determinism.IsDeterministicTool && !existingRecord.Determinism.IsSinglePhaseNonDeterministic)) { // If the records are identical except for determinsim, return null. if (existingRecord == hashes) { return(eventing.Returns(new FullCacheRecordWithDeterminism(CacheDeterminism.None))); } return(eventing.Returns(new FullCacheRecordWithDeterminism(new FullCacheRecord(testStrongFingerprint, existingRecord)))); } // And now the error conditions. // If a tool determinism collection, or an attempt to go from deterministic to not deterministic. if (existingRecord.Determinism.IsDeterministicTool && hashes.Determinism.IsDeterministicTool) { return(eventing.StopFailure(new NotDeterministicFailure(Cache.CacheId, new FullCacheRecord(testStrongFingerprint, existingRecord), new FullCacheRecord(testStrongFingerprint, hashes)))); } } return(eventing.Returns(await m_metadataSession.AddOrGetAsync(weak, casElement, hashElement, hashes, urgencyHint, eventing.Id))); } }