private void ContinueOnFault(Task task, ActiveTaskContext context) { const string messageFormat = "Fatal error occured with task \"{0}\" for Client {1}."; logger.ErrorFormat(task.Exception, messageFormat, context.TaskName, context.ClientId); publisher.PublishException(context.ClientId, context.TaskId, DateTime.Now, task.Exception); publisher.PublishStatusFailed(context.ClientId, context.TaskId, DateTime.Now); var taskShouldBeConsidered = FaultIsSqlTimeout(task.Exception); ActiveTaskContext existing; if (!contextProvider.TryRemove(context.TaskId, out existing)) { logger.WarnFormat( "Unable to remove task \"{0}\" for Client {1}. This may occur if the task was already removed or evicted from the dictionary.", context.TaskName, context.ClientId); return; } if (taskShouldBeConsidered) { scheduleProvider.PushTaskForConsideration(context.TaskId); } else { logger.WarnFormat("Removed task \"{0}\" attached to ClientId {1} from the dictionary.", context.TaskName, context.ClientId); } context.Dispose(); }
private void ContinueOnComplete(ActiveTaskContext context) { var messageFormat = (!context.WasTaskCancelled) ? "Task \"{0}\" for Client {1} completed." : "Task \"{0}\" for Client {1} was cancelled. This task may not have completed."; logger.InfoFormat(messageFormat, context.TaskName, context.ClientId); if (context.WasTaskCancelled) { publisher.PublishStatusCanceled(context.ClientId, context.TaskId, DateTime.Now); } else { publisher.PublishStatusComplete(context.ClientId, context.TaskId, DateTime.Now); } ActiveTaskContext existingContext; if (!contextProvider.TryRemove(context.TaskId, out existingContext)) { logger.WarnFormat( "Unable to remove task \"{0}\" for Client {1}. This may occur if the task was already removed or evicted from the dictionary.", context.TaskName, context.ClientId); return; } if (!context.WasTaskCancelled) { scheduleProvider.PushTaskForConsideration(context.TaskId); } context.Dispose(); }
public void ExecuteTaskContainer(ActiveTaskContext context, TaskConfigurationModel[] models, CancellationToken token) { var task = new Task(() => { var info = adminDataAccess.LoadClientInfo(context.ClientId); if (info == null) { var message = string.Format("Unable to load configuration for Client \"{0}\". Tasks will not execute.", context.ClientId); throw new InvalidOperationException(message); } try { publisher.PublishStatusActive(context.ClientId, context.TaskId, DateTime.Now); foreach (var model in models) { if (context.ServiceToken.IsCancellationRequested) { context.ServiceToken.ThrowIfCancellationRequested(); } if (context.Token.IsCancellationRequested) { break; } var instance = LoadTaskInstance(info, model); logger.InfoFormat("Executing task \"{0}\" for Client \"{1}\".", model.TaskName, model.ClientId); publisher.PublishStatusActive(context.ClientId, model.TaskId, DateTime.Now); instance.Execute(context.Token); publisher.PublishStatusComplete(context.ClientId, model.TaskId, DateTime.Now); } } catch (OperationCanceledException) { if (context.ServiceToken.IsCancellationRequested) { context.ServiceToken.ThrowIfCancellationRequested(); } } }, token, TaskCreationOptions.LongRunning); task.ContinueWith(x => ContinueOnComplete(context), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith(x => ContinueOnCancellation(context), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith(x => ContinueOnFault(x, context), TaskContinuationOptions.OnlyOnFaulted); contextProvider.TryAdd(context.TaskId, context); context.SetActiveTask(task, token); task.Start(); }
public void ExecuteTask(string taskId, CancellationToken token) { scheduleProvider.PopTaskFromConsideration(taskId); var model = taskProvider.LoadTaskConfiguration(taskId); if (model == null) { logger.WarnFormat("Unable to identify configuration for task \"{0}\".", taskId); return; } var context = ActiveTaskContext.Create(model.ClientId, model.TaskId, model.TaskName); if (!model.IsContainer) { ExecuteTask(context, model, token); return; } var collection = model.SubTasks; var executionPlan = scheduleProvider.IdentifyExecutionPlan(model.TaskId); if (executionPlan.Any()) { collection = collection .Join(executionPlan, o => o.TaskId, i => i, (o, i) => o) .ToArray(); var invalidEntries = executionPlan .Except(model.SubTasks.Select(x => x.TaskId)) .ToArray(); if (invalidEntries.Any()) { logger.WarnFormat( "Invalid execution plan found for task \"{0}\". The following tasks are invalid for this configuration: \"{1}\".", model.TaskId, string.Join(", ", invalidEntries)); } } ExecuteTaskContainer(context, collection, token); }
private void ContinueOnCancellation(ActiveTaskContext context) { const string messageFormat = "Task \"{0}\" for Client {1} was asked to stop. This task shut down gracefully."; logger.InfoFormat(messageFormat, context.TaskName, context.ClientId); publisher.PublishStatusCanceled(context.ClientId, context.TaskId, DateTime.Now); ActiveTaskContext existingContext; if (!contextProvider.TryRemove(context.TaskId, out existingContext)) { logger.WarnFormat( "Unable to remove task \"{0}\" for Client {1}. This may occur if the task was already removed or evicted from the dictionary.", context.TaskName, context.ClientId); return; } logger.WarnFormat("Removed task \"{0}\" attached to ClientId {1} from the dictionary.", context.TaskName, context.ClientId); context.Dispose(); }
public bool TryRemove(string taskId, out ActiveTaskContext context) { return(collection.TryRemove(taskId, out context)); }
public bool TryAdd(string taskId, ActiveTaskContext context) { return(collection.TryAdd(taskId, context)); }