/// <inheritdoc /> protected override async Task <BoolResult> ShutdownCoreAsync(OperationContext context) { _serviceReadinessChecker.Reset(); _portDisposer?.Dispose(); if (_grpcServer != null) { await _grpcServer.KillAsync(); } _logIncrementalStatsTimer?.Dispose(); await LogIncrementalStatsAsync(context); // Stop the session expiration timer. _sessionExpirationCheckTimer?.Dispose(); // Hibernate dangling sessions in case we are shutdown unexpectedly to live clients. await HandleShutdownDanglingSessionsAsync(context); // Cleaning up all the temp directories associated with sessions (they'll be recreated during the next startup when hibernated sessions are recreated). CleanSessionTempDirectories(context); // Now the stores, without active users, can be shut down. return(await ShutdownStoresAsync(context)); }
/// <inheritdoc /> public async Task <BoolResult> ShutdownAsync(Context context) { ShutdownStarted = true; try { _heartbeatTimer?.Dispose(); if (_sessionState == null) { // _sessionState is null if initialization has failed. return(BoolResult.Success); } StructResult <int> sessionResult = await _sessionState.GetIdAsync(); if (!sessionResult.Succeeded) { return(new BoolResult(sessionResult)); } int sessionId = sessionResult.Data; if (_serviceUnavailable) { context.Debug("Skipping session shutdown because service is unavailable."); } else { try { await _client.ShutdownSessionAsync(new ShutdownRequest { Header = new RequestHeader(context.Id, sessionId) }); } catch (RpcException e) { context.Error($"Failed to shut down session with error: {e}"); } } await _channel.ShutdownAsync(); ShutdownCompleted = true; return(BoolResult.Success); } catch (Exception ex) { // Catching all exceptions, even ClientCanRetryExceptions, because the teardown steps aren't idempotent. // In the worst case, the shutdown call comes while the service is offline, the service never receives it, // and then the service times out the session 10 minutes later (by default). ShutdownCompleted = true; return(new BoolResult(ex)); } }
/// <inheritdoc /> protected override async Task <BoolResult> ShutdownCoreAsync(OperationContext context) { _serviceReadinessChecker.Reset(); _portDisposer?.Dispose(); await _grpcServer.KillAsync(); _logIncrementalStatsTimer?.Dispose(); await LogIncrementalStatsAsync(context); // Stop the session expiration timer. _sessionExpirationCheckTimer?.Dispose(); // Hibernate dangling sessions in case we are shutdown unexpectedly to live clients. await HandleShutdownDanglingSessionsAsync(context); // Now the stores, without active users, can be shut down. return(await ShutdownStoresAsync(context)); }
/// <inheritdoc /> protected override async Task <BoolResult> ShutdownCoreAsync(OperationContext context) { _serviceReadinessChecker.Reset(); _portDisposer?.Dispose(); if (_grpcServer != null) { await _grpcServer.KillAsync(); } var success = BoolResult.Success; foreach (var endpoint in _additionalEndpoints) { success &= await endpoint.ShutdownAsync(context); } _logIncrementalStatsTimer?.Dispose(); _logMachineStatsTimer?.Dispose(); // Don't trace statistics if configured and only if startup was successful. if (Tracer.EnableTraceStatisticsAtShutdown && StartupCompleted) { await LogIncrementalStatsAsync(context, logAtShutdown : false); } // Stop the session expiration timer. _sessionExpirationCheckTimer?.Dispose(); // Hibernate dangling sessions in case we are shutdown unexpectedly to live clients. await HandleShutdownDanglingSessionsAsync(context); // Cleaning up all the temp directories associated with sessions (they'll be recreated during the next startup when hibernated sessions are recreated). CleanSessionTempDirectories(context); // Now the stores, without active users, can be shut down. return(success & await ShutdownStoresAsync(context)); }
/// <inheritdoc /> public void Dispose() { if (_disposed) { return; } Flush(); if (!_synchronous) { _flushTimer?.Dispose(); _requests?.Add(new ShutdownRequest()); _writerTask?.Wait(); _requests?.Dispose(); _requests = null; } _disposed = true; }
public void Dispose() => timer.Dispose();