internal void TerminateDispatcher(string dispatcherId) { Thread.Sleep(3000); var poisonPill = new PoisonPill { EffectOnCurrentWork = PoisonPillEffect.Kill, DispatcherId = DispatcherId.FromString(dispatcherId) }; SendingBus.Send(poisonPill, poisonPill.DispatcherId.PoisonPillSubscriptionId, StorageType.NonPersistent); Thread.Sleep(10000); }
private void TakePoisonPill(PoisonPill poisonPill) { try { if (IsDisposed) return; Log.DispatcherActivity(Repository.Settings.DispatcherId, DispatcherActivity.PoisonPillWasReceived, poisonPill); if (poisonPill.DispatcherId != Repository.Settings.DispatcherId) return; // Kill the process imediatelly non-gracefully if (poisonPill.EffectOnCurrentWork == PoisonPillEffect.Kill) { Log.Error("Poison Pill with Kill request received! Terminating the process now..."); Environment.Exit(0); } // If another poison pill request is already being processed if (CancellationTokenForCheckIfDispatcherShouldBeKeptAliveThatMuchTimeAfterInitialized.IsCancellationRequested) return; IsTakingPoisonPill = true; // Stop checking if can still be alive CancellationTokenForCheckIfDispatcherShouldBeKeptAliveThatMuchTimeAfterInitialized.Cancel(); // Stop receiving pending work requests. CancellationTokenForCheckingPendingJobs.Cancel(); // Wait the execution of the current work requests if (poisonPill.EffectOnCurrentWork == PoisonPillEffect.Wait) { Thread.CurrentThread.SleepWhile( () => ExecutingWorkers.Count > 0, Repository.Settings.MaximumExecutionTime, TimeoutWaitingWorkerToFinish); } // Abort the execution of the current work requests if (poisonPill.EffectOnCurrentWork == PoisonPillEffect.Abort) { CancellationTokenForExecutionOfJob.Cancel(); Log.DispatcherActivity(Repository.Settings.DispatcherId, DispatcherActivity.AbortedAllWorkerThreads); } // Cancel the execution of the current work requests if (poisonPill.EffectOnCurrentWork == PoisonPillEffect.Cancel) { CancellationTokenForExecutionOfJob.Cancel(); Thread.CurrentThread.SleepWhile( () => ExecutingWorkers.Count > 0, Repository.Settings.MaximumExecutionTime, TimeoutWaitingWorkerToFinish); } Log.DispatcherActivity(Repository.Settings.DispatcherId, DispatcherActivity.PoisonPillWasTaken, poisonPill); // Must dispose in another thread to allow the handler that received the poison pill // to acknoledge the message before the connection is disposed DisposeAsync(); } catch (ThreadAbortException tae) { Log.Info(tae as Exception, "ThreadAbortException while taking poison pill!"); } catch (Exception e) { Log.Error(e, "Exception taking poison pill!"); Environment.Exit(0); } }
internal static void DispatcherActivity(this Logger log, DispatcherId dispatcherId, DispatcherActivity activity, PoisonPill poisonPill = null, Exception exception = null, bool logAsError = true) { var logEntry = new DispatcherActivityLogEntry { DispatcherId = dispatcherId, Activity = activity, PoisonPill = poisonPill, Exception = exception }; if (exception == null) { if (activity == Dispatching.DispatcherActivity.CheckingForUnfinishedJobs) log.Debug(logEntry); else log.Info(logEntry); } else if (logAsError) log.Error(exception, logEntry.ToString()); else log.Info(exception, logEntry.ToString()); }
internal void TerminateApplication() { ReceivingBus.Receive<LifeSignal>(ComputationalUnit.Settings.DispatcherId.FromString(DispatcherId).LifeSignalSubscriptionId, message => { lock (LatestLifeSignals) { LatestLifeSignals[DispatcherId] = (LifeSignal)message; } }); var settings = BootstrapSettings.DispatcherSettings.Single(s => s.DispatcherId.Value.StartsWith(DispatcherId)); lock (LatestLifeSignals) { LifeSignal latestLifeSignal; if (LatestLifeSignals.TryGetValue(settings.DispatcherId.Value, out latestLifeSignal)) { if ((DateTime.Now - latestLifeSignal.CreationDate) >= MaxTimeDispatcherCanBeSilent) throw new Exception("Dispatcher is already stopped."); } LatestLifeSignals[settings.DispatcherId.Value] = new LifeSignal { SourceId = ComputationalUnit.Settings.DispatcherId.FromString("FirstChanceForLifeSignalNotReceived") }; } var poisonPill = new PoisonPill { EffectOnCurrentWork = PoisonPillEffect.Cancel, DispatcherId = settings.DispatcherId }; SendingBus.Send(poisonPill, settings.DispatcherId.PoisonPillSubscriptionId, StorageType.NonPersistent); }