/// <summary> /// Processes a single task and updates the queue accordingly. /// </summary> /// <param name="task"></param> protected internal void ProcessTask(TaskMessage task) { // Get the state of the task into the performer. Performer.TaskStorage = task.Storage; // Let the performer have a go with the task. try { Performer.Perform(task.Parameters); } catch (Exception exception) { // The performer has raised an exception while processing // the task. We do what we can to preserve the task, // and set it back as failed. try { task.Storage = Performer.TaskStorage; } catch {} var message = "The performer raised an exception: " + exception.Message + "\n" + exception.StackTrace; MonitorClient.Fail(message); Log.Error(message); return; } // Collect the task's state and save it back to the task. task.Storage = Performer.TaskStorage; // Collect the result of the perfomer's work and act on it. var result = Performer.Status; switch (result.Outcome) { case Outcome.Success: MonitorClient.Succeed(); Log.Info("Task succeeded."); break; case Outcome.Failure: MonitorClient.Fail(result.Reason); Log.InfoFormat("Task failed. Reason: {0}", result.Reason); if (result.Data is Exception) { Log.Error("Exception associated with task failure:", result.Data as Exception); } if (result.Data is string) { Log.InfoFormat("Additional Information: {0}", result.Data); } break; case Outcome.CriticalFailure: MonitorClient.CriticalFail(result.Reason); Log.InfoFormat("Task failed critically. Reason: {0}", result.Reason); if (result.Data is string) { Log.InfoFormat("Additional Information: {0}", result.Data); } break; case Outcome.Defer: MonitorClient.Defer(result.Reason); Log.InfoFormat("Task deferred. Reason: {0}", result.Reason); if (result.Data is string) { Log.InfoFormat("Additional Information: {0}", result.Data); } break; } }