private async Task HandleShutdownDanglingSessionsAsync(Context context) { try { if (_sessionHandles.Any()) { var sessionInfoList = new List <HibernatedSessionInfo>(_sessionHandles.Count); foreach (var(sessionId, handle) in _sessionHandles) { TSession session = handle.Session; if (session is IHibernateContentSession hibernateSession) { var pinnedContentHashes = hibernateSession.EnumeratePinnedContentHashes().Select(x => x.Serialize()).ToList(); Tracer.Debug(context, $"Hibernating session {DescribeSession(sessionId, handle)}."); sessionInfoList.Add(new HibernatedSessionInfo( sessionId, handle.SessionName, handle.ImplicitPin, handle.CacheName, pinnedContentHashes, handle.SessionExpirationUtcTicks, handle.SessionCapabilities)); } else { Tracer.Warning(context, $"Shutdown of non-hibernating dangling session id={sessionId}"); } await session.ShutdownAsync(context).ThrowIfFailure(); session.Dispose(); } if (sessionInfoList.Any()) { var hibernatedSessions = new HibernatedSessions(sessionInfoList); try { var sw = Stopwatch.StartNew(); await hibernatedSessions.WriteAsync(FileSystem, Config.DataRootPath); sw.Stop(); Tracer.Debug( context, $"Wrote hibernated sessions to root=[{Config.DataRootPath}] in {sw.Elapsed.TotalMilliseconds}ms"); } catch (Exception exception) { Tracer.Warning(context, $"Failed to write hibernated sessions root=[{Config.DataRootPath}]: {exception.ToString()}"); Tracer.Error(context, exception); } } _sessionHandles.Clear(); } } catch (Exception exception) { Tracer.Error(context, exception, "Failed to store hibernated sessions"); } }
/// <nodoc /> public static async Task HibernateSessionsAsync( Context context, IDictionary <int, ISessionHandle <IContentSession, LocalContentServerSessionData> > sessionHandles, LocalServerConfiguration config, Tracer tracer, IAbsFileSystem fileSystem) { var sessionInfoList = new List <HibernatedContentSessionInfo>(sessionHandles.Count); foreach (var(sessionId, handle) in sessionHandles) { IContentSession session = handle.Session; if (session is IHibernateContentSession hibernateSession) { if (config.ShutdownEvictionBeforeHibernation) { // Calling shutdown of eviction before hibernating sessions to prevent possible race condition of evicting pinned content await hibernateSession.ShutdownEvictionAsync(context).ThrowIfFailure(); } var pinnedContentHashes = hibernateSession.EnumeratePinnedContentHashes().Select(x => x.Serialize()).ToList(); tracer.Debug(context, $"Hibernating session {handle.ToString(sessionId)}."); sessionInfoList.Add(new HibernatedContentSessionInfo( sessionId, handle.SessionData.Name, handle.SessionData.ImplicitPin, handle.CacheName, pinnedContentHashes, handle.SessionExpirationUtcTicks, handle.SessionData.Capabilities)); } else { tracer.Warning(context, $"Shutdown of non-hibernating dangling session id={sessionId}"); } await session.ShutdownAsync(context).ThrowIfFailure(); session.Dispose(); } if (sessionInfoList.Any()) { var hibernatedSessions = new HibernatedSessions <HibernatedContentSessionInfo>(sessionInfoList); try { var sw = Stopwatch.StartNew(); await hibernatedSessions.WriteAsync(fileSystem, config.DataRootPath, HibernatedSessionsFileName); sw.Stop(); tracer.Debug( context, $"Wrote hibernated sessions to root=[{config.DataRootPath}] in {sw.Elapsed.TotalMilliseconds}ms"); } catch (Exception exception) { tracer.Warning(context, $"Failed to write hibernated sessions root=[{config.DataRootPath}]: {exception}"); tracer.Error(context, exception); } } }