/// <inheritdoc /> public override void Dispose() { if (m_session != null) { Contract.Assert(m_session.IsClosed, "Cache session must be closed before attempting to dispose the CacheCoreEngineCache."); var loggedCacheStatistics = GetLoggedStatistics(m_session, out var cacheMap); var cacheStatistics = new Dictionary <string, long>(); foreach (var statistic in GetLoggedStatistics(m_session, out var cache)) { cacheStatistics.Add(statistic.qualifiedId, statistic.value); } Subtract(newStats: cacheStatistics, baseline: m_initialStatistics); Logger.Log.CacheBulkStatistics( LoggingContext, cacheStatistics); foreach (var statisticsByCacheId in loggedCacheStatistics.GroupBy(s => s.cacheId)) { Logger.Log.ICacheStatistics( LoggingContext, statisticsByCacheId.Key, cacheMap[statisticsByCacheId.Key], statisticsByCacheId.First().cacheType, statisticsByCacheId.ToDictionary(s => s.id, s => s.value)); } } m_cache?.ShutdownAsync().GetAwaiter().GetResult(); // The base implementation will now dispose anything that was handed to it in startup. base.Dispose(); }
internal static async Task <Possible <CacheCoreCacheInitializer> > TryInitializeCacheInternalAsync( LoggingContext loggingContext, PathTable pathTable, string cacheDirectory, ICacheConfiguration config, bool enableFingerprintLookup, RootTranslator rootTranslator) { Contract.Requires(pathTable != null); Contract.Requires(pathTable.IsValid); Contract.Requires(config != null); Contract.Requires(config.CacheLogFilePath.IsValid); Contract.Requires(config.CacheConfigFile.IsValid); Contract.Requires(!string.IsNullOrWhiteSpace(cacheDirectory)); bool succeeded = false; ICacheCoreCache cache = null; ICacheCoreSession session = null; try { Possible <ICacheConfigData> cacheConfigData = TryGetCacheConfigData(pathTable, cacheDirectory, config, rootTranslator); if (!cacheConfigData.Succeeded) { return(cacheConfigData.Failure); } Possible <ICacheCoreCache> maybeCache = await CacheFactory.InitializeCacheAsync(cacheConfigData.Result, loggingContext.ActivityId, config); if (!maybeCache.Succeeded) { return(maybeCache.Failure); } // We are now responsible for shutting this down (even if something later fails). cache = maybeCache.Result; cache.SuscribeForCacheStateDegredationFailures( failure => { Tracing.Logger.Log.CacheReportedRecoverableError(loggingContext, failure.DescribeIncludingInnerFailures()); }); // Log the cache ID we got. Tracing.Logger.Log.CacheInitialized(loggingContext, cache.CacheId); Possible <ICacheCoreSession> maybeSession = string.IsNullOrWhiteSpace(config.CacheSessionName) ? await cache.CreateSessionAsync() : await cache.CreateSessionAsync(config.CacheSessionName); if (!maybeSession.Succeeded) { return(maybeSession.Failure); } session = maybeSession.Result; succeeded = true; return(new CacheCoreCacheInitializer( loggingContext, cache, session, new List <IDisposable>(), enableFingerprintLookup: enableFingerprintLookup, rootTranslator: rootTranslator, replaceExistingFileOnMaterialization: config.ReplaceExistingFileOnMaterialization)); } finally { if (!succeeded) { // Note that we clean up in reverse order that we initialized things. if (session != null) { Analysis.IgnoreResult(await session.CloseAsync(), justification: "Okay to ignore close"); Analysis.IgnoreResult(await cache.ShutdownAsync(), justification: "Okay to ignore shutdown"); } } } }