private static Possible <ICache, Failure> InitializeCache(ICacheConfigData cacheData, Guid activityId) { using (var eventing = new InitializeCacheActivity(BasicFilesystemCache.EventSource, activityId, typeof(BasicFilesystemCache).FullName)) { eventing.Start(cacheData); var possibleCacheConfig = cacheData.Create <Config>(); if (!possibleCacheConfig.Succeeded) { return(eventing.StopFailure(possibleCacheConfig.Failure)); } Config cacheConfig = possibleCacheConfig.Result; // instantiate new BasicFilesystemCache try { return(eventing.Returns(new BasicFilesystemCache( cacheConfig.CacheId, cacheConfig.CacheRootPath, cacheConfig.ReadOnly, cacheConfig.StrictMetadataCasCoupling, cacheConfig.IsAuthoritative, cacheConfig.ContentionBackoffMaxMilliseonds, cacheConfig.DefaultFingerprintMinimumAgeMinutes))); } catch (Exception e) { return(eventing.StopFailure(new CacheConstructionFailure(cacheConfig.CacheId, e))); } } }
/// <inheritdoc /> public async Task <Possible <ICache, Failure> > InitializeCacheAsync(ICacheConfigData cacheData, Guid activityId) { Contract.Requires(cacheData != null); using (var eventing = new InitializeCacheActivity(VerticalCacheAggregator.EventSource, activityId, typeof(VerticalCacheAggregator).FullName)) { eventing.Start(cacheData); var possibleCacheConfig = cacheData.Create <Config>(); if (!possibleCacheConfig.Succeeded) { return(eventing.StopFailure(possibleCacheConfig.Failure)); } Config cacheAggregatorConfig = possibleCacheConfig.Result; // temporary if (cacheAggregatorConfig.PreFetchCasData == true) { throw new NotImplementedException(); } // initialize local cache var maybeCache = await CacheFactory.InitializeCacheAsync(cacheAggregatorConfig.LocalCache, activityId); if (!maybeCache.Succeeded) { return(eventing.StopFailure(maybeCache.Failure)); } ICache local = maybeCache.Result; if (local.IsReadOnly) { Analysis.IgnoreResult(await local.ShutdownAsync(), justification: "Okay to ignore shutdown status"); return(eventing.StopFailure(new VerticalCacheAggregatorNeedsWriteableLocalFailure(local.CacheId))); } maybeCache = await CacheFactory.InitializeCacheAsync(cacheAggregatorConfig.RemoteCache, activityId); if (!maybeCache.Succeeded) { eventing.Write(CacheActivity.CriticalDataOptions, new { RemoteCacheFailed = maybeCache.Failure }); if (cacheAggregatorConfig.FailIfRemoteFails) { Analysis.IgnoreResult(await local.ShutdownAsync(), justification: "Okay to ignore shutdown status"); return(eventing.StopFailure(maybeCache.Failure)); } // If the remote cache does not construct, we fall back to just the local. // This is basically like a disconnected state only we are starting disconnnected // and thus are just the local cache now. We can just return the local and // not add the overhead of the aggregator. string failureMessage = string.Format( System.Globalization.CultureInfo.InvariantCulture, RemoteConstructionFailureWarning, local.CacheId); // Note: Compiler is confused and needs help converting ICache to Possible here but not a few lines below. return(eventing.Returns(new MessageForwardingCache(new Failure[] { maybeCache.Failure.Annotate(failureMessage) }, local))); } ICache remote = maybeCache.Result; bool readOnlyRemote = remote.IsReadOnly || cacheAggregatorConfig.RemoteIsReadOnly; try { // instantiate new VerticalCacheAggregator return(eventing.Returns(new VerticalCacheAggregator( local, remote, readOnlyRemote, cacheAggregatorConfig.WriteThroughCasData, cacheAggregatorConfig.RemoteContentIsReadOnly))); } catch (Exception e) { string cacheId = local.CacheId + "_" + remote.CacheId; Analysis.IgnoreResult(await local.ShutdownAsync(), justification: "Okay to ignore shutdown status"); Analysis.IgnoreResult(await remote.ShutdownAsync(), justification: "Okay to ignore shutdown status"); return(eventing.StopFailure(new CacheConstructionFailure(cacheId, e))); } } }