Example #1
0
        private async Task CreateTask()
        {
            lock (_locker)
            {
                // Once we've created the requested number of tasks, do not create any more.
                if (_schedulerTokenSource.IsCancellationRequested || _totalStartedTaskCount == _totalRequestedTasks)
                {
                    return;
                }
                _totalStartedTaskCount++;
            }
            Interlocked.Increment(ref _activeTaskCount);
            var task = _taskCreator(_schedulerTokenSource.Token);

            try
            {
                await task;
            }
            catch (Exception e)
            {
                _exceptions.Add(e);
                _schedulerTokenSource.Cancel();
                return;
            }

            TaskCompletedEvent?.Invoke(this, EventArgs.Empty);
        }
Example #2
0
 public async System.Threading.Tasks.Task Handle(TaskCompletedEvent message)
 {
     var msg = new TaskCreatedTimeout()
     {
         TaskId = message.TaskId
     };
     await _bus.Defer(TimeSpan.FromDays(5), msg);
 }
 public async Task ReportTaskCompleted(Guid taskId, TaskResult result, CancellationToken cancellationToken)
 {
     var jobId = this.taskProperties.HubName.Equals("Gates", StringComparison.OrdinalIgnoreCase)
         ? taskId
         : this.taskProperties.JobId;
     var completedEvent = new TaskCompletedEvent(jobId, taskId, result);
     await taskClient.RaisePlanEventAsync(this.taskProperties.ProjectId, this.taskProperties.HubName, this.taskProperties.PlanId, completedEvent, cancellationToken).ConfigureAwait(false);
 }
Example #4
0
        public async System.Threading.Tasks.Task Handle(TaskCompletedEvent message)
        {
            var t = ActiveDbContext.Tasks.Find(message.TaskId);

            t.IsCompleted      = true;
            t.DateOfCompletion = message.DateOfCompletion;
            await ActiveDbContext.SaveChangesAsync();
        }
Example #5
0
        public async Task ReportTaskCompleted(Guid taskId, TaskResult result, CancellationToken cancellationToken)
        {
            var jobId = await GetJobId(this.taskProperties.HubName, this.taskProperties.JobId, taskId);

            taskId = await GetTaskId(this.taskProperties.HubName, taskId);

            var completedEvent = new TaskCompletedEvent(jobId, taskId, result);
            await taskClient.RaisePlanEventAsync(this.taskProperties.ProjectId, this.taskProperties.HubName, this.taskProperties.PlanId, completedEvent, cancellationToken).ConfigureAwait(false);
        }
        public void FinishGate(Result result, string message)
        {
            var taskResult = result == Result.Succeeded ? TaskResult.Succeeded : TaskResult.Failed;

            var jobId = this.HubName.ToLower().Equals("gates", StringComparison.OrdinalIgnoreCase)
                    ? this.TimelineRecord.Id
                    : this.JobGuid;
            var taskCompletedEvent = new TaskCompletedEvent(this.TaskInstanceGuid, Guid.Empty, taskResult);

            this.TaskClient.RaisePlanEventAsync(this.ProjectGuid, this.HubName, this.PlanGuid, taskCompletedEvent).SyncResult();
        }
Example #7
0
        public void HandleTaskCompletedEvent(TaskCompletedEvent completedEvent)
        {
            int taskId = completedEvent.TaskScheduledId;

            if (openTasks.ContainsKey(taskId))
            {
                OpenTaskInfo info = openTasks[taskId];
                info.Result.SetResult(completedEvent.Result);

                openTasks.Remove(taskId);
            }
        }
 public void Handle(TaskCompletedEvent message)
 {
     using (var context = new TaskContext())
     {
         var task = (from t in context.PendingTasks where t.TaskId == message.TaskId select t).SingleOrDefault();
         if (task == null)
         {
             return;
         }
         context.PendingTasks.Remove(task);
         context.SaveChanges();
     }
 }
Example #9
0
            public void TaskCompletedEvent()
            {
                var taskId = Guid.NewGuid();
                var e      = new TaskCompletedEvent()
                {
                    DateOfCompletion = DateTime.Now,
                    TaskId           = taskId
                };
                var task = OTask.Factory.Create(taskId, "Fake");

                task.ApplyEvent(e);
                Assert.Equal(e.DateOfCompletion, task.DateOfCompletion);
            }
Example #10
0
        public void HandleTaskCompletedEvent(TaskCompletedEvent completedEvent)
        {
            int taskId = completedEvent.TaskScheduledId;

            if (this.openTasks.ContainsKey(taskId))
            {
                OpenTaskInfo info = this.openTasks[taskId];
                info.Result.SetResult(completedEvent.Result);

                this.openTasks.Remove(taskId);
            }
            else
            {
                LogDuplicateEvent("TaskCompleted", completedEvent, taskId);
            }
        }
        int GetTaskScheduledId(HistoryEvent historyEvent)
        {
            TaskCompletedEvent tce = historyEvent as TaskCompletedEvent;

            if (tce != null)
            {
                return(tce.TaskScheduledId);
            }

            TaskFailedEvent tfe = historyEvent as TaskFailedEvent;

            if (tfe != null)
            {
                return(tfe.TaskScheduledId);
            }

            return(-1);
        }
        void SpeedStatistics()
        {
            long back = 0;

            while (true)
            {
                if (back == 0)
                {
                    back = downloadLength;
                }
                else
                {
                    speed = downloadLength - back;
                    back  = downloadLength;
                }
                if (State == TaskState.已停止)
                {
                    break;
                }
                if (Complete >= threads.Length)
                {
                    if (Stop)
                    {
                        break;
                    }
                    string[] files = new string[threads.Length];
                    for (int i = 0; i < threads.Length; i++)
                    {
                        files[i] = threads[i].FileName;
                    }
                    State = TaskState.合并文件中;
                    FileOperation.CombineFiles(files, FilePath + "\\" + FileName);
                    Running      = false;
                    TaskComplete = true;
                    State        = TaskState.载完成;
                    TaskCompletedEvent?.Invoke();
                    break;
                }
                Thread.Sleep(1000);
            }
        }
Example #13
0
        public void Handle(TaskCompletedEvent message)
        {
            using (var context = new TaskContext())
            {
                var task = (from t in context.PendingTasks
                            where t.TaskId == message.TaskId
                            select t).SingleOrDefault();
                if (task == null)
                {
                    return;
                }

                task.Status         = Status.Completed;
                task.CompletionDate = message.TimeStamp.Date;
                if (!task.StartDate.HasValue)
                {
                    task.StartDate = message.TimeStamp.Date;
                }
                context.SaveChanges();
            }
        }
        public override async Task <UpdateToDoCommand> HandleAsync(UpdateToDoCommand command,
                                                                   CancellationToken cancellationToken = new CancellationToken())
        {
            string title;

            using (var uow = new ToDoContext(_options))
            {
                var repository = new ToDoItemRepositoryAsync(uow);
                var toDoItem   = await repository.GetAsync(command.ToDoId, cancellationToken);

                if (command.Title != null)
                {
                    toDoItem.Title = command.Title;
                }

                if (command.Complete.HasValue)
                {
                    toDoItem.Completed = command.Complete.Value;
                }

                if (command.Order.HasValue)
                {
                    toDoItem.Order = command.Order.Value;
                }

                await repository.UpdateAsync(toDoItem, cancellationToken);

                title = toDoItem.Title;
            }

            if (command.Complete.HasValue && command.Complete.Value)
            {
                var taskCompleteEvent = new TaskCompletedEvent(title);

                _commandProcessor.Post(taskCompleteEvent);
            }

            return(await base.HandleAsync(command, cancellationToken));
        }
Example #15
0
 private void HttpDownload_DownloadCompletedEvent(DownloadThread thread)
 {
     lock (this)
     {
         bool flag = false;
         foreach (DownloadThread thr in threads)
         {
             if (thr.Equals(thread))
             {
                 continue;
             }
             if (!thr.Completed)
             {
                 flag = true;
             }
         }
         if (flag)
         {
             return;
         }
         if (Stop)
         {
             return;
         }
         string[] files = new string[threads.Length];
         for (int i = 0; i < threads.Length; i++)
         {
             files[i] = threads[i].DownloadPath;
         }
         State = TaskState.合并文件中;
         FileOperation.CombineFiles(files, FilePath + "\\" + FileName);
         Running      = false;
         TaskComplete = true;
         State        = TaskState.载完成;
         TaskCompletedEvent?.Invoke();
     }
 }
Example #16
0
        public void MarkAsCompleted(Guid userId)
        {
            if (userId != this.CreatorId)
            {
                throw new ArgumentException("A task can be marked as completed by its creator only", nameof(userId));
            }
            if (this.DateOfCancellation.HasValue)
            {
                throw new InvalidOperationException("Can't mark as completed a cancelled task.");
            }
            if (this.DateOfCompletion.HasValue)
            {
                throw new InvalidOperationException("Can't mark as completed a closed task.");
            }

            var e = new TaskCompletedEvent()
            {
                DateOfCompletion = DateTime.Now,
                TaskId           = this.Id,
                UserId           = userId
            };

            RaiseEvent(e);
        }
        async Task OnProcessWorkItemAsync(TaskActivityWorkItem workItem)
        {
            Task?renewTask = null;

            using var renewCancellationTokenSource = new CancellationTokenSource();

            TaskMessage           taskMessage           = workItem.TaskMessage;
            OrchestrationInstance orchestrationInstance = taskMessage.OrchestrationInstance;
            TaskScheduledEvent?   scheduledEvent        = null;
            Activity?diagnosticActivity = null;

            try
            {
                if (string.IsNullOrWhiteSpace(orchestrationInstance?.InstanceId))
                {
                    this.logHelper.TaskActivityDispatcherError(
                        workItem,
                        $"The activity worker received a message that does not have any OrchestrationInstance information.");
                    throw TraceHelper.TraceException(
                              TraceEventType.Error,
                              "TaskActivityDispatcher-MissingOrchestrationInstance",
                              new InvalidOperationException("Message does not contain any OrchestrationInstance information"));
                }

                if (taskMessage.Event.EventType != EventType.TaskScheduled)
                {
                    this.logHelper.TaskActivityDispatcherError(
                        workItem,
                        $"The activity worker received an event of type '{taskMessage.Event.EventType}' but only '{EventType.TaskScheduled}' is supported.");
                    throw TraceHelper.TraceException(
                              TraceEventType.Critical,
                              "TaskActivityDispatcher-UnsupportedEventType",
                              new NotSupportedException("Activity worker does not support event of type: " +
                                                        taskMessage.Event.EventType));
                }

                scheduledEvent = (TaskScheduledEvent)taskMessage.Event;
                if (scheduledEvent.Name == null)
                {
                    string message = $"The activity worker received a {nameof(EventType.TaskScheduled)} event that does not specify an activity name.";
                    this.logHelper.TaskActivityDispatcherError(workItem, message);
                    throw TraceHelper.TraceException(
                              TraceEventType.Error,
                              "TaskActivityDispatcher-MissingActivityName",
                              new InvalidOperationException(message));
                }

                this.logHelper.TaskActivityStarting(orchestrationInstance, scheduledEvent);
                TaskActivity?taskActivity = this.objectManager.GetObject(scheduledEvent.Name, scheduledEvent.Version);

                if (workItem.LockedUntilUtc < DateTime.MaxValue)
                {
                    // start a task to run RenewUntil
                    renewTask = Task.Factory.StartNew(
                        () => this.RenewUntil(workItem, renewCancellationTokenSource.Token),
                        renewCancellationTokenSource.Token);
                }

                var dispatchContext = new DispatchMiddlewareContext();
                dispatchContext.SetProperty(taskMessage.OrchestrationInstance);
                dispatchContext.SetProperty(taskActivity);
                dispatchContext.SetProperty(scheduledEvent);

                // correlation
                CorrelationTraceClient.Propagate(() =>
                {
                    workItem.TraceContextBase?.SetActivityToCurrent();
                    diagnosticActivity = workItem.TraceContextBase?.CurrentActivity;
                });

                ActivityExecutionResult?result;
                try
                {
                    await this.dispatchPipeline.RunAsync(dispatchContext, async _ =>
                    {
                        if (taskActivity == null)
                        {
                            // This likely indicates a deployment error of some kind. Because these unhandled exceptions are
                            // automatically retried, resolving this may require redeploying the app code so that the activity exists again.
                            // CONSIDER: Should this be changed into a permanent error that fails the orchestration? Perhaps
                            //           the app owner doesn't care to preserve existing instances when doing code deployments?
                            throw new TypeMissingException($"TaskActivity {scheduledEvent.Name} version {scheduledEvent.Version} was not found");
                        }

                        var context = new TaskContext(taskMessage.OrchestrationInstance);
                        context.ErrorPropagationMode = this.errorPropagationMode;

                        HistoryEvent?responseEvent;

                        try
                        {
                            string?output = await taskActivity.RunAsync(context, scheduledEvent.Input);
                            responseEvent = new TaskCompletedEvent(-1, scheduledEvent.EventId, output);
                        }
                        catch (Exception e) when(e is not TaskFailureException && !Utils.IsFatal(e) && !Utils.IsExecutionAborting(e))
                        {
                            // These are unexpected exceptions that occur in the task activity abstraction. Normal exceptions from
                            // activities are expected to be translated into TaskFailureException and handled outside the middleware
                            // context (see further below).
                            TraceHelper.TraceExceptionInstance(TraceEventType.Error, "TaskActivityDispatcher-ProcessException", taskMessage.OrchestrationInstance, e);
                            string?details = this.IncludeDetails
                                ? $"Unhandled exception while executing task: {e}"
                                : null;
                            responseEvent = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details, new FailureDetails(e));
                            this.logHelper.TaskActivityFailure(orchestrationInstance, scheduledEvent.Name, (TaskFailedEvent)responseEvent, e);
                        }

                        var result = new ActivityExecutionResult {
                            ResponseEvent = responseEvent
                        };
                        dispatchContext.SetProperty(result);
                    });

                    result = dispatchContext.GetProperty <ActivityExecutionResult>();
                }
                catch (TaskFailureException e)
                {
                    // These are normal task activity failures. They can come from Activity implementations or from middleware.
                    TraceHelper.TraceExceptionInstance(TraceEventType.Error, "TaskActivityDispatcher-ProcessTaskFailure", taskMessage.OrchestrationInstance, e);
                    string?details      = this.IncludeDetails ? e.Details : null;
                    var    failureEvent = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details, e.FailureDetails);
                    this.logHelper.TaskActivityFailure(orchestrationInstance, scheduledEvent.Name, failureEvent, e);
                    CorrelationTraceClient.Propagate(() => CorrelationTraceClient.TrackException(e));
                    result = new ActivityExecutionResult {
                        ResponseEvent = failureEvent
                    };
                }
                catch (Exception middlewareException) when(!Utils.IsFatal(middlewareException))
                {
                    // These are considered retriable
                    this.logHelper.TaskActivityDispatcherError(workItem, $"Unhandled exception in activity middleware pipeline: {middlewareException}");
                    throw;
                }

                HistoryEvent?eventToRespond = result?.ResponseEvent;

                if (eventToRespond is TaskCompletedEvent completedEvent)
                {
                    this.logHelper.TaskActivityCompleted(orchestrationInstance, scheduledEvent.Name, completedEvent);
                }
                else if (eventToRespond is null)
                {
                    // Default response if middleware prevents a response from being generated
                    eventToRespond = new TaskCompletedEvent(-1, scheduledEvent.EventId, null);
                }

                var responseTaskMessage = new TaskMessage
                {
                    Event = eventToRespond,
                    OrchestrationInstance = orchestrationInstance
                };

                await this.orchestrationService.CompleteTaskActivityWorkItemAsync(workItem, responseTaskMessage);
            }
            catch (SessionAbortedException e)
            {
                // The activity aborted its execution
                this.logHelper.TaskActivityAborted(orchestrationInstance, scheduledEvent, e.Message);
                TraceHelper.TraceInstance(TraceEventType.Warning, "TaskActivityDispatcher-ExecutionAborted", orchestrationInstance, "{0}: {1}", scheduledEvent?.Name, e.Message);
                await this.orchestrationService.AbandonTaskActivityWorkItemAsync(workItem);
            }
            finally
            {
                diagnosticActivity?.Stop(); // Ensure the activity is stopped here to prevent it from leaking out.
                if (renewTask != null)
                {
                    renewCancellationTokenSource.Cancel();
                    try
                    {
                        // wait the renewTask finish
                        await renewTask;
                    }
                    catch (OperationCanceledException)
                    {
                        // ignore
                    }
                }
            }
        }
        HistoryEvent GenerateAbridgedEvent(HistoryEvent evt)
        {
            HistoryEvent returnedEvent = evt;

            if (evt is TaskScheduledEvent)
            {
                var sourceEvent = (TaskScheduledEvent) evt;
                returnedEvent = new TaskScheduledEvent(sourceEvent.EventId)
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                    Name = sourceEvent.Name,
                    Version = sourceEvent.Version,
                    Input = "[..snipped..]",
                };
            }
            else if (evt is TaskCompletedEvent)
            {
                var sourceEvent = (TaskCompletedEvent) evt;
                returnedEvent = new TaskCompletedEvent(sourceEvent.EventId, sourceEvent.TaskScheduledId, "[..snipped..]")
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            else if (evt is SubOrchestrationInstanceCreatedEvent)
            {
                var sourceEvent = (SubOrchestrationInstanceCreatedEvent) evt;
                returnedEvent = new SubOrchestrationInstanceCreatedEvent(sourceEvent.EventId)
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                    Name = sourceEvent.Name,
                    Version = sourceEvent.Version,
                    Input = "[..snipped..]",
                };
            }
            else if (evt is SubOrchestrationInstanceCompletedEvent)
            {
                var sourceEvent = (SubOrchestrationInstanceCompletedEvent) evt;
                returnedEvent = new SubOrchestrationInstanceCompletedEvent(sourceEvent.EventId,
                    sourceEvent.TaskScheduledId, "[..snipped..]")
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            else if (evt is TaskFailedEvent)
            {
                var sourceEvent = (TaskFailedEvent) evt;
                returnedEvent = new TaskFailedEvent(sourceEvent.EventId,
                    sourceEvent.TaskScheduledId, sourceEvent.Reason, "[..snipped..]")
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            else if (evt is SubOrchestrationInstanceFailedEvent)
            {
                var sourceEvent = (SubOrchestrationInstanceFailedEvent) evt;
                returnedEvent = new SubOrchestrationInstanceFailedEvent(sourceEvent.EventId,
                    sourceEvent.TaskScheduledId, sourceEvent.Reason, "[..snipped..]")
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            else if (evt is ExecutionStartedEvent)
            {
                var sourceEvent = (ExecutionStartedEvent) evt;
                returnedEvent = new ExecutionStartedEvent(sourceEvent.EventId, "[..snipped..]")
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            else if (evt is ExecutionCompletedEvent)
            {
                var sourceEvent = (ExecutionCompletedEvent) evt;
                returnedEvent = new ExecutionCompletedEvent(sourceEvent.EventId, "[..snipped..]",
                    sourceEvent.OrchestrationStatus)
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            else if (evt is ExecutionTerminatedEvent)
            {
                var sourceEvent = (ExecutionTerminatedEvent) evt;
                returnedEvent = new ExecutionTerminatedEvent(sourceEvent.EventId, "[..snipped..]")
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            // ContinueAsNewEvent is covered by the ExecutionCompletedEvent block

            return returnedEvent;
        }
        protected override async Task OnProcessWorkItem(BrokeredMessage message)
        {
            Utils.CheckAndLogDeliveryCount(message, taskHubDescription.MaxTaskActivityDeliveryCount, this.orchestratorQueueName);

            Task renewTask = null;
            var  renewCancellationTokenSource = new CancellationTokenSource();

            try
            {
                TaskMessage taskMessage = await Utils.GetObjectFromBrokeredMessageAsync <TaskMessage>(message);

                OrchestrationInstance orchestrationInstance = taskMessage.OrchestrationInstance;
                if (orchestrationInstance == null || string.IsNullOrWhiteSpace(orchestrationInstance.InstanceId))
                {
                    throw TraceHelper.TraceException(TraceEventType.Error,
                                                     new InvalidOperationException("Message does not contain any OrchestrationInstance information"));
                }
                if (taskMessage.Event.EventType != EventType.TaskScheduled)
                {
                    throw TraceHelper.TraceException(TraceEventType.Critical,
                                                     new NotSupportedException("Activity worker does not support event of type: " +
                                                                               taskMessage.Event.EventType));
                }

                // call and get return message
                var          scheduledEvent = (TaskScheduledEvent)taskMessage.Event;
                TaskActivity taskActivity   = objectManager.GetObject(scheduledEvent.Name, scheduledEvent.Version);
                if (taskActivity == null)
                {
                    throw new TypeMissingException("TaskActivity " + scheduledEvent.Name + " version " +
                                                   scheduledEvent.Version + " was not found");
                }

                renewTask = Task.Factory.StartNew(() => RenewUntil(message, renewCancellationTokenSource.Token));

                // TODO : pass workflow instance data
                var          context        = new TaskContext(taskMessage.OrchestrationInstance);
                HistoryEvent eventToRespond = null;

                try
                {
                    string output = await taskActivity.RunAsync(context, scheduledEvent.Input);

                    eventToRespond = new TaskCompletedEvent(-1, scheduledEvent.EventId, output);
                }
                catch (TaskFailureException e)
                {
                    TraceHelper.TraceExceptionInstance(TraceEventType.Error, taskMessage.OrchestrationInstance, e);
                    string details = IncludeDetails ? e.Details : null;
                    eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details);
                }
                catch (Exception e)
                {
                    TraceHelper.TraceExceptionInstance(TraceEventType.Error, taskMessage.OrchestrationInstance, e);
                    string details = IncludeDetails
                        ? string.Format("Unhandled exception while executing task: {0}\n\t{1}", e, e.StackTrace)
                        : null;
                    eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details);
                }

                var responseTaskMessage = new TaskMessage();
                responseTaskMessage.Event = eventToRespond;
                responseTaskMessage.OrchestrationInstance = orchestrationInstance;

                BrokeredMessage responseMessage = Utils.GetBrokeredMessageFromObject(responseTaskMessage,
                                                                                     settings.MessageCompressionSettings,
                                                                                     orchestrationInstance, "Response for " + message.MessageId);
                responseMessage.SessionId = orchestrationInstance.InstanceId;

                using (var ts = new TransactionScope())
                {
                    workerQueueClient.Complete(message.LockToken);
                    deciderSender.Send(responseMessage);
                    ts.Complete();
                }
            }
            finally
            {
                if (renewTask != null)
                {
                    renewCancellationTokenSource.Cancel();
                    renewTask.Wait();
                }
            }
        }
        async Task OnProcessWorkItemAsync(TaskActivityWorkItem workItem)
        {
            Task renewTask = null;
            var  renewCancellationTokenSource = new CancellationTokenSource();

            TaskMessage           taskMessage           = workItem.TaskMessage;
            OrchestrationInstance orchestrationInstance = taskMessage.OrchestrationInstance;
            TaskScheduledEvent    scheduledEvent        = null;
            Activity diagnosticActivity = null;

            try
            {
                if (string.IsNullOrWhiteSpace(orchestrationInstance?.InstanceId))
                {
                    this.logHelper.TaskActivityDispatcherError(
                        workItem,
                        $"The activity worker received a message that does not have any OrchestrationInstance information.");
                    throw TraceHelper.TraceException(
                              TraceEventType.Error,
                              "TaskActivityDispatcher-MissingOrchestrationInstance",
                              new InvalidOperationException("Message does not contain any OrchestrationInstance information"));
                }

                if (taskMessage.Event.EventType != EventType.TaskScheduled)
                {
                    this.logHelper.TaskActivityDispatcherError(
                        workItem,
                        $"The activity worker received an event of type '{taskMessage.Event.EventType}' but only '{EventType.TaskScheduled}' is supported.");
                    throw TraceHelper.TraceException(
                              TraceEventType.Critical,
                              "TaskActivityDispatcher-UnsupportedEventType",
                              new NotSupportedException("Activity worker does not support event of type: " +
                                                        taskMessage.Event.EventType));
                }

                // call and get return message
                scheduledEvent = (TaskScheduledEvent)taskMessage.Event;
                this.logHelper.TaskActivityStarting(orchestrationInstance, scheduledEvent);
                TaskActivity taskActivity = this.objectManager.GetObject(scheduledEvent.Name, scheduledEvent.Version);
                if (taskActivity == null)
                {
                    throw new TypeMissingException($"TaskActivity {scheduledEvent.Name} version {scheduledEvent.Version} was not found");
                }

                if (workItem.LockedUntilUtc < DateTime.MaxValue)
                {
                    // start a task to run RenewUntil
                    renewTask = Task.Factory.StartNew(
                        () => this.RenewUntil(workItem, renewCancellationTokenSource.Token),
                        renewCancellationTokenSource.Token);
                }

                // TODO : pass workflow instance data
                var          context        = new TaskContext(taskMessage.OrchestrationInstance);
                HistoryEvent eventToRespond = null;

                var dispatchContext = new DispatchMiddlewareContext();
                dispatchContext.SetProperty(taskMessage.OrchestrationInstance);
                dispatchContext.SetProperty(taskActivity);
                dispatchContext.SetProperty(scheduledEvent);

                // correlation
                CorrelationTraceClient.Propagate(() =>
                {
                    workItem.TraceContextBase?.SetActivityToCurrent();
                    diagnosticActivity = workItem.TraceContextBase?.CurrentActivity;
                });

                await this.dispatchPipeline.RunAsync(dispatchContext, async _ =>
                {
                    try
                    {
                        string output  = await taskActivity.RunAsync(context, scheduledEvent.Input);
                        eventToRespond = new TaskCompletedEvent(-1, scheduledEvent.EventId, output);
                    }
                    catch (TaskFailureException e)
                    {
                        TraceHelper.TraceExceptionInstance(TraceEventType.Error, "TaskActivityDispatcher-ProcessTaskFailure", taskMessage.OrchestrationInstance, e);
                        string details = this.IncludeDetails ? e.Details : null;
                        eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details);
                        this.logHelper.TaskActivityFailure(orchestrationInstance, scheduledEvent.Name, (TaskFailedEvent)eventToRespond, e);
                        CorrelationTraceClient.Propagate(() => CorrelationTraceClient.TrackException(e));
                    }
                    catch (Exception e) when(!Utils.IsFatal(e) && !Utils.IsExecutionAborting(e))
                    {
                        TraceHelper.TraceExceptionInstance(TraceEventType.Error, "TaskActivityDispatcher-ProcessException", taskMessage.OrchestrationInstance, e);
                        string details = this.IncludeDetails
                            ? $"Unhandled exception while executing task: {e}\n\t{e.StackTrace}"
                            : null;
                        eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details);
                        this.logHelper.TaskActivityFailure(orchestrationInstance, scheduledEvent.Name, (TaskFailedEvent)eventToRespond, e);
                    }

                    if (eventToRespond is TaskCompletedEvent completedEvent)
                    {
                        this.logHelper.TaskActivityCompleted(orchestrationInstance, scheduledEvent.Name, completedEvent);
                    }
                });

                var responseTaskMessage = new TaskMessage
                {
                    Event = eventToRespond,
                    OrchestrationInstance = orchestrationInstance
                };

                await this.orchestrationService.CompleteTaskActivityWorkItemAsync(workItem, responseTaskMessage);
            }
            catch (SessionAbortedException e)
            {
                // The activity aborted its execution
                this.logHelper.TaskActivityAborted(orchestrationInstance, scheduledEvent, e.Message);
                TraceHelper.TraceInstance(TraceEventType.Warning, "TaskActivityDispatcher-ExecutionAborted", orchestrationInstance, "{0}: {1}", scheduledEvent.Name, e.Message);
                await this.orchestrationService.AbandonTaskActivityWorkItemAsync(workItem);
            }
            finally
            {
                diagnosticActivity?.Stop(); // Ensure the activity is stopped here to prevent it from leaking out.
                if (renewTask != null)
                {
                    renewCancellationTokenSource.Cancel();
                    try
                    {
                        // wait the renewTask finish
                        await renewTask;
                    }
                    catch (OperationCanceledException)
                    {
                        // ignore
                    }
                }
            }
        }
Example #21
0
 public void ApplyEvent([AggregateId("TaskId")] TaskCompletedEvent theEvent)
 {
     Completed = true;
 }
Example #22
0
 internal void MarkAsCompleted()
 {
     { var completed = new TaskCompletedEvent(TaskId); RaiseEvent(completed); }
 }
Example #23
0
        public void MarkAsCompleted()
        {
            var completed = new TaskCompletedEvent(TaskId);

            RaiseEvent(completed);
        }
        async Task OnProcessWorkItemAsync(TaskActivityWorkItem workItem)
        {
            Task renewTask = null;
            var  renewCancellationTokenSource = new CancellationTokenSource();

            try
            {
                TaskMessage           taskMessage           = workItem.TaskMessage;
                OrchestrationInstance orchestrationInstance = taskMessage.OrchestrationInstance;
                if (string.IsNullOrWhiteSpace(orchestrationInstance?.InstanceId))
                {
                    throw TraceHelper.TraceException(
                              TraceEventType.Error,
                              "TaskActivityDispatcher-MissingOrchestrationInstance",
                              new InvalidOperationException("Message does not contain any OrchestrationInstance information"));
                }

                if (taskMessage.Event.EventType != EventType.TaskScheduled)
                {
                    throw TraceHelper.TraceException(
                              TraceEventType.Critical,
                              "TaskActivityDispatcher-UnsupportedEventType",
                              new NotSupportedException("Activity worker does not support event of type: " +
                                                        taskMessage.Event.EventType));
                }

                // call and get return message
                var          scheduledEvent = (TaskScheduledEvent)taskMessage.Event;
                TaskActivity taskActivity   = this.objectManager.GetObject(scheduledEvent.Name, scheduledEvent.Version);
                if (taskActivity == null)
                {
                    throw new TypeMissingException($"TaskActivity {scheduledEvent.Name} version {scheduledEvent.Version} was not found");
                }

                renewTask = Task.Factory.StartNew(() => RenewUntil(workItem, renewCancellationTokenSource.Token), renewCancellationTokenSource.Token);

                // TODO : pass workflow instance data
                var          context        = new TaskContext(taskMessage.OrchestrationInstance);
                HistoryEvent eventToRespond = null;

                var dispatchContext = new DispatchMiddlewareContext();
                dispatchContext.SetProperty(taskMessage.OrchestrationInstance);
                dispatchContext.SetProperty(taskActivity);
                dispatchContext.SetProperty(scheduledEvent);

                await this.dispatchPipeline.RunAsync(dispatchContext, async _ =>
                {
                    try
                    {
                        string output  = await taskActivity.RunAsync(context, scheduledEvent.Input);
                        eventToRespond = new TaskCompletedEvent(-1, scheduledEvent.EventId, output);
                    }
                    catch (TaskFailureException e)
                    {
                        TraceHelper.TraceExceptionInstance(TraceEventType.Error, "TaskActivityDispatcher-ProcessTaskFailure", taskMessage.OrchestrationInstance, e);
                        string details = IncludeDetails ? e.Details : null;
                        eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details);
                    }
                    catch (Exception e) when(!Utils.IsFatal(e))
                    {
                        TraceHelper.TraceExceptionInstance(TraceEventType.Error, "TaskActivityDispatcher-ProcessException", taskMessage.OrchestrationInstance, e);
                        string details = IncludeDetails
                            ? $"Unhandled exception while executing task: {e}\n\t{e.StackTrace}"
                            : null;
                        eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details);
                    }
                });

                var responseTaskMessage = new TaskMessage
                {
                    Event = eventToRespond,
                    OrchestrationInstance = orchestrationInstance
                };

                await this.orchestrationService.CompleteTaskActivityWorkItemAsync(workItem, responseTaskMessage);
            }
            finally
            {
                if (renewTask != null)
                {
                    renewCancellationTokenSource.Cancel();
                    renewTask.Wait(renewCancellationTokenSource.Token);
                }
            }
        }
Example #25
0
 /// <summary>
 /// Logs that a task activity completed successfully.
 /// </summary>
 /// <param name="instance">The orchestration instance that scheduled this task activity.</param>
 /// <param name="name">The name of the task activity.</param>
 /// <param name="taskEvent">The history event associated with this activity completion.</param>
 internal void TaskActivityCompleted(OrchestrationInstance instance, string name, TaskCompletedEvent taskEvent)
 {
     if (this.IsStructuredLoggingEnabled)
     {
         this.WriteStructuredLog(new LogEvents.TaskActivityCompleted(instance, name, taskEvent));
     }
 }
Example #26
0
 public void ApplyEvent(TaskCompletedEvent @event)
 {
     this.DateOfCompletion = @event.DateOfCompletion;
 }
        HistoryEvent GenerateAbridgedEvent(HistoryEvent evt)
        {
            HistoryEvent returnedEvent = evt;

            if (evt is TaskScheduledEvent taskScheduledEvent)
            {
                returnedEvent = new TaskScheduledEvent(taskScheduledEvent.EventId)
                {
                    Timestamp = taskScheduledEvent.Timestamp,
                    IsPlayed  = taskScheduledEvent.IsPlayed,
                    Name      = taskScheduledEvent.Name,
                    Version   = taskScheduledEvent.Version,
                    Input     = "[..snipped..]",
                };
            }
            else if (evt is TaskCompletedEvent taskCompletedEvent)
            {
                returnedEvent = new TaskCompletedEvent(taskCompletedEvent.EventId, taskCompletedEvent.TaskScheduledId, "[..snipped..]")
                {
                    Timestamp = taskCompletedEvent.Timestamp,
                    IsPlayed  = taskCompletedEvent.IsPlayed,
                };
            }
            else if (evt is SubOrchestrationInstanceCreatedEvent subOrchestrationInstanceCreatedEvent)
            {
                returnedEvent = new SubOrchestrationInstanceCreatedEvent(subOrchestrationInstanceCreatedEvent.EventId)
                {
                    Timestamp = subOrchestrationInstanceCreatedEvent.Timestamp,
                    IsPlayed  = subOrchestrationInstanceCreatedEvent.IsPlayed,
                    Name      = subOrchestrationInstanceCreatedEvent.Name,
                    Version   = subOrchestrationInstanceCreatedEvent.Version,
                    Input     = "[..snipped..]",
                };
            }
            else if (evt is SubOrchestrationInstanceCompletedEvent subOrchestrationInstanceCompletedEvent)
            {
                returnedEvent = new SubOrchestrationInstanceCompletedEvent(subOrchestrationInstanceCompletedEvent.EventId,
                                                                           subOrchestrationInstanceCompletedEvent.TaskScheduledId, "[..snipped..]")
                {
                    Timestamp = subOrchestrationInstanceCompletedEvent.Timestamp,
                    IsPlayed  = subOrchestrationInstanceCompletedEvent.IsPlayed,
                };
            }
            else if (evt is TaskFailedEvent taskFailedEvent)
            {
                returnedEvent = new TaskFailedEvent(taskFailedEvent.EventId,
                                                    taskFailedEvent.TaskScheduledId, taskFailedEvent.Reason, "[..snipped..]")
                {
                    Timestamp = taskFailedEvent.Timestamp,
                    IsPlayed  = taskFailedEvent.IsPlayed,
                };
            }
            else if (evt is SubOrchestrationInstanceFailedEvent subOrchestrationInstanceFailedEvent)
            {
                returnedEvent = new SubOrchestrationInstanceFailedEvent(subOrchestrationInstanceFailedEvent.EventId,
                                                                        subOrchestrationInstanceFailedEvent.TaskScheduledId, subOrchestrationInstanceFailedEvent.Reason, "[..snipped..]")
                {
                    Timestamp = subOrchestrationInstanceFailedEvent.Timestamp,
                    IsPlayed  = subOrchestrationInstanceFailedEvent.IsPlayed,
                };
            }
            else if (evt is ExecutionStartedEvent executionStartedEvent)
            {
                returnedEvent = new ExecutionStartedEvent(executionStartedEvent.EventId, "[..snipped..]")
                {
                    Timestamp = executionStartedEvent.Timestamp,
                    IsPlayed  = executionStartedEvent.IsPlayed,
                };
            }
            else if (evt is ExecutionCompletedEvent executionCompletedEvent)
            {
                returnedEvent = new ExecutionCompletedEvent(executionCompletedEvent.EventId, "[..snipped..]",
                                                            executionCompletedEvent.OrchestrationStatus)
                {
                    Timestamp = executionCompletedEvent.Timestamp,
                    IsPlayed  = executionCompletedEvent.IsPlayed,
                };
            }
            else if (evt is ExecutionTerminatedEvent executionTerminatedEvent)
            {
                returnedEvent = new ExecutionTerminatedEvent(executionTerminatedEvent.EventId, "[..snipped..]")
                {
                    Timestamp = executionTerminatedEvent.Timestamp,
                    IsPlayed  = executionTerminatedEvent.IsPlayed,
                };
            }
            // ContinueAsNewEvent is covered by the ExecutionCompletedEvent block

            return(returnedEvent);
        }
Example #28
0
        public static HistoryEvent GetHistoryEvent(this DbDataReader reader, bool isOrchestrationHistory = false)
        {
            string eventTypeString = (string)reader["EventType"];

            if (!Enum.TryParse(eventTypeString, out EventType eventType))
            {
                throw new InvalidOperationException($"Unknown event type '{eventTypeString}'.");
            }

            int eventId = GetTaskId(reader);

            HistoryEvent historyEvent;

            switch (eventType)
            {
            case EventType.ContinueAsNew:
                historyEvent = new ContinueAsNewEvent(eventId, GetPayloadText(reader));
                break;

            case EventType.EventRaised:
                historyEvent = new EventRaisedEvent(eventId, GetPayloadText(reader))
                {
                    Name = GetName(reader),
                };
                break;

            case EventType.EventSent:
                historyEvent = new EventSentEvent(eventId)
                {
                    Input      = GetPayloadText(reader),
                    Name       = GetName(reader),
                    InstanceId = GetInstanceId(reader),
                };
                break;

            case EventType.ExecutionCompleted:
                historyEvent = new ExecutionCompletedEvent(
                    eventId,
                    result: GetPayloadText(reader),
                    orchestrationStatus: OrchestrationStatus.Completed);
                break;

            case EventType.ExecutionFailed:
                historyEvent = new ExecutionCompletedEvent(
                    eventId,
                    result: GetPayloadText(reader),
                    orchestrationStatus: OrchestrationStatus.Failed);
                break;

            case EventType.ExecutionStarted:
                historyEvent = new ExecutionStartedEvent(eventId, GetPayloadText(reader))
                {
                    Name = GetName(reader),
                    OrchestrationInstance = new OrchestrationInstance
                    {
                        InstanceId  = GetInstanceId(reader),
                        ExecutionId = GetExecutionId(reader),
                    },
                    Tags    = null,  // TODO
                    Version = GetVersion(reader),
                };
                string?parentInstanceId = GetParentInstanceId(reader);
                if (parentInstanceId != null)
                {
                    ((ExecutionStartedEvent)historyEvent).ParentInstance = new ParentInstance
                    {
                        OrchestrationInstance = new OrchestrationInstance
                        {
                            InstanceId = parentInstanceId
                        },
                        TaskScheduleId = GetTaskId(reader)
                    };
                }
                break;

            case EventType.ExecutionTerminated:
                historyEvent = new ExecutionTerminatedEvent(eventId, GetPayloadText(reader));
                break;

            case EventType.GenericEvent:
                historyEvent = new GenericEvent(eventId, GetPayloadText(reader));
                break;

            case EventType.OrchestratorCompleted:
                historyEvent = new OrchestratorCompletedEvent(eventId);
                break;

            case EventType.OrchestratorStarted:
                historyEvent = new OrchestratorStartedEvent(eventId);
                break;

            case EventType.SubOrchestrationInstanceCompleted:
                historyEvent = new SubOrchestrationInstanceCompletedEvent(eventId, GetTaskId(reader), GetPayloadText(reader));
                break;

            case EventType.SubOrchestrationInstanceCreated:
                historyEvent = new SubOrchestrationInstanceCreatedEvent(eventId)
                {
                    Input      = GetPayloadText(reader),
                    InstanceId = null,     // TODO
                    Name       = GetName(reader),
                    Version    = null,
                };
                break;

            case EventType.SubOrchestrationInstanceFailed:
                historyEvent = new SubOrchestrationInstanceFailedEvent(
                    eventId,
                    taskScheduledId: GetTaskId(reader),
                    reason: GetReason(reader),
                    details: GetPayloadText(reader));
                break;

            case EventType.TaskCompleted:
                historyEvent = new TaskCompletedEvent(
                    eventId,
                    taskScheduledId: GetTaskId(reader),
                    result: GetPayloadText(reader));
                break;

            case EventType.TaskFailed:
                historyEvent = new TaskFailedEvent(
                    eventId,
                    taskScheduledId: GetTaskId(reader),
                    reason: GetReason(reader),
                    details: GetPayloadText(reader));
                break;

            case EventType.TaskScheduled:
                historyEvent = new TaskScheduledEvent(eventId)
                {
                    Input   = GetPayloadText(reader),
                    Name    = GetName(reader),
                    Version = GetVersion(reader),
                };
                break;

            case EventType.TimerCreated:
                historyEvent = new TimerCreatedEvent(eventId)
                {
                    FireAt = GetVisibleTime(reader),
                };
                break;

            case EventType.TimerFired:
                historyEvent = new TimerFiredEvent(eventId)
                {
                    FireAt  = GetVisibleTime(reader),
                    TimerId = GetTaskId(reader),
                };
                break;

            default:
                throw new InvalidOperationException($"Don't know how to interpret '{eventType}'.");
            }

            historyEvent.Timestamp = GetTimestamp(reader);
            historyEvent.IsPlayed  = isOrchestrationHistory && (bool)reader["IsPlayed"];
            return(historyEvent);
        }
        public async Task MockActivityOrchestration()
        {
            // Orchestrator middleware mocks an orchestration that calls one activity
            // and returns the activity result as its own result
            this.worker.AddOrchestrationDispatcherMiddleware((context, next) =>
            {
                OrchestrationRuntimeState state = context.GetProperty <OrchestrationRuntimeState>();

                if (state.NewEvents.OfType <ExecutionStartedEvent>().Any())
                {
                    // Manually schedule an activity execution
                    context.SetProperty(new OrchestratorExecutionResult
                    {
                        Actions = new[]
                        {
                            new ScheduleTaskOrchestratorAction
                            {
                                Name    = "FakeActivity",
                                Version = "FakeActivityVersion",
                                Input   = "SomeInput",
                            }
                        }
                    });
                }
                else
                {
                    // If we get here, it's because the activity completed
                    TaskCompletedEvent taskCompletedEvent = state.NewEvents.OfType <TaskCompletedEvent>().Single();

                    // We know the activity completed at this point
                    context.SetProperty(new OrchestratorExecutionResult
                    {
                        Actions = new[]
                        {
                            new OrchestrationCompleteOrchestratorAction
                            {
                                OrchestrationStatus = OrchestrationStatus.Completed,
                                Result = taskCompletedEvent?.Result,
                            },
                        },
                    });
                }


                // don't call next() - we're short-circuiting the actual orchestration executor logic
                return(Task.FromResult(0));
            });

            // Activity middleware returns a result immediately
            this.worker.AddActivityDispatcherMiddleware((context, next) =>
            {
                TaskScheduledEvent taskScheduledEvent = context.GetProperty <TaskScheduledEvent>();

                // Use the activity parameters as the activity output
                string output = $"{taskScheduledEvent.Name},{taskScheduledEvent.Version},{taskScheduledEvent.Input}";

                context.SetProperty(new ActivityExecutionResult
                {
                    ResponseEvent = new TaskCompletedEvent(-1, taskScheduledEvent.EventId, output),
                });

                // don't call next() - we're short-circuiting the actual activity executor logic
                return(Task.FromResult(0));
            });

            OrchestrationInstance instance = await this.client.CreateOrchestrationInstanceAsync(
                name : "FakeName",
                version : "FakeVersion",
                input : null);

            TimeSpan           timeout = TimeSpan.FromSeconds(Debugger.IsAttached ? 1000 : 5);
            OrchestrationState state   = await this.client.WaitForOrchestrationAsync(instance, timeout);

            Assert.AreEqual(OrchestrationStatus.Completed, state.OrchestrationStatus);
            Assert.AreEqual("FakeActivity,FakeActivityVersion,SomeInput", state.Output);
        }
Example #30
0
        public void FinishGate(Result result, string message)
        {
            String logMessage;

            if (this.TimelineRecord == null)
            {
                logMessage = "GateHelper.FinishGate(): Skipping for TimelineRecord is null";
                this.Log.Info(logMessage);
                SendLiveLogMessage(logMessage);
                return;
            }
            if (this.JobGuid == null)
            {
                logMessage = "GateHelper.FinishGate(): Skipping for JobGuid is null";
                this.Log.Info(logMessage);
                SendLiveLogMessage(logMessage);
                return;
            }
            if (this.HubName == null)
            {
                logMessage = "GateHelper.FinishGate(): Skipping for HubName is null";
                this.Log.Info(logMessage);
                SendLiveLogMessage(logMessage);
                return;
            }

            logMessage = "GateHelper.FinishGate(): Starting for HubName: " + this.HubName;
            this.Log.Info(logMessage);
            SendLiveLogMessage(logMessage);

            var taskResult = result == Result.Succeeded ? TaskResult.Succeeded : TaskResult.Failed;

            var jobId = this.HubName.ToLower().Equals("gates", StringComparison.OrdinalIgnoreCase)
                    ? this.TimelineRecord.Id
                    : this.JobGuid;

            logMessage = "GateHelper.FinishGate(): Using HubName: " + this.HubName + " and jobId: " + jobId + " taskResult: " + taskResult.ToString();
            this.Log.Info(logMessage);
            SendLiveLogMessage(logMessage);

            var taskCompletedEvent = new TaskCompletedEvent();

            try
            {
                logMessage = "GateHelper.FinishGate(): Attempting to create TaskCompletedEvent for TaskInstanceGuid: " + this.TaskInstanceGuid;
                this.Log.Info(logMessage);
                SendLiveLogMessage(logMessage);

                taskCompletedEvent = new TaskCompletedEvent(this.TaskInstanceGuid, Guid.Empty, taskResult);
            }
            catch (Exception e)
            {
                logMessage = "GateHelper.FinishGate(): Exception creating TaskCompletedEvent: " + e.Message;
                this.Log.Info(logMessage);
                SendLiveLogMessage(logMessage);
                throw;
            }

            try
            {
                logMessage = "GateHelper.FinishGate(): Attempting to call TaskClient.RaisePlanEventAsync() method with ProjectGuid: " + this.ProjectGuid + " and PlanGuid: " + this.PlanGuid;
                this.Log.Info(logMessage);
                SendLiveLogMessage(logMessage);

                this.TaskClient.RaisePlanEventAsync(this.ProjectGuid, this.HubName, this.PlanGuid, taskCompletedEvent).SyncResult();

                logMessage = "GateHelper.FinishGate(): Complete";
                this.Log.Info(logMessage);
                SendLiveLogMessage(logMessage);
            }
            catch (Exception e)
            {
                logMessage = "GateHelper.FinishGate(): Exception calling TaskClient.RaisePlanEventAsync: " + e.Message;
                this.Log.Info(logMessage);
                SendLiveLogMessage(logMessage);
                throw;
            }
        }
Example #31
0
 public void ApplyEvent(
     [AggregateId("TaskId")] TaskCompletedEvent @event)
 {
     Status = Status.Completed;
 }