/// <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));
        }
Esempio n. 2
0
        /// <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));
            }
        }
Esempio n. 3
0
        /// <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));
        }
Esempio n. 4
0
        /// <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));
        }
Esempio n. 5
0
        /// <inheritdoc />
        public void Dispose()
        {
            if (_disposed)
            {
                return;
            }

            Flush();

            if (!_synchronous)
            {
                _flushTimer?.Dispose();
                _requests?.Add(new ShutdownRequest());
                _writerTask?.Wait();
                _requests?.Dispose();
                _requests = null;
            }

            _disposed = true;
        }
Esempio n. 6
0
 public void Dispose()
 => timer.Dispose();