/// <summary> /// Removes the handlers and stops the engine /// </summary> /// <returns>Returns task to wait for until shutdown has completed</returns> public static async Task ShutdownAsync() { await lockShutdown.WaitAsync(); logger.Info("Shutdown..."); if (!IsRunning()) { lockShutdown.Release(); return; } var db = Pool.Database.Get(); await db.ControllerLog(Id, "Shutdown Initiated", CancellationToken); State = EngineState.Stopping; // Stop jobs AutomaticJobsManager.Stop(); // Disconnect connections connectionManagmentTimer.Stop(); var connectionsToStop = new List <Task>(); var registeredConnections = nodeConnections.Select(nc => nc.Value).ToList(); foreach (var node in registeredConnections) { if (node.IsConnected) { connectionsToStop.Add(_Disconnect(node.Id)); } } await Task.WhenAll(connectionsToStop); connectionsToStop = null; // Signal completition of message processing and wait for buffer to complete, max. 5 seconds messageBuffer.Complete(); int timeout = 0; while (messageBuffer.InputCount > 0 && timeout < 20) { await Task.Delay(250); timeout++; } // Cancel parallel operations in Main logger.Debug("Cancelling processes, may take up to two minutes."); cancellationToken.Cancel(); /// Wait 10 seconds await Task.Delay(10000); var databaseCancellationTokenSource = new CancellationTokenSource(); databaseCancellationTokenSource.CancelAfter(30000); await db.ControllerLog(Id, "Remaining Connections terminated", databaseCancellationTokenSource.Token); await db.ControllerLog(Id, "Shutdown Completed", databaseCancellationTokenSource.Token); await db.ControllerShutdown(Id, databaseCancellationTokenSource.Token); Pool.Database.Put(db); databaseCancellationTokenSource.Dispose(); databaseCancellationTokenSource = null; // Shutdown the Cache Cache.Shutdown(); State = EngineState.Stopped; logger.Info("Shutdown completed"); messageBuffer = null; cancellationToken.Dispose(); cancellationToken = null; connectionManagmentTimer.Dispose(); connectionManagmentTimer = null; lockShutdown.Release(); lockShutdown.Dispose(); lockShutdown = null; logger = null; }