예제 #1
0
        /// <summary>
        /// Immediately processes the specified task.
        /// </summary>
        /// <param name="task"></param>
        /// <returns></returns>
        public async Task ProcessSkraprTask(ISkraprTask task)
        {
            if (CancellationToken.IsCancellationRequested)
            {
                m_logger.LogDebug("{functionName} Cancellation requested. Skipping task {taskName}", nameof(ProcessSkraprTask), task.Name);
                return;
            }

            m_logger.LogDebug("{functionName} performing task {taskName}", nameof(ProcessSkraprTask), task.Name);

            if (task.Disabled)
            {
                m_logger.LogDebug("{functionName} Task {taskName} was marked as disabled. Skipping.", nameof(ProcessSkraprTask), task.Name);
                return;
            }

            if (task is IConditionalExpressionTask conditionalExpressionTask && !String.IsNullOrWhiteSpace(conditionalExpressionTask.Condition))
            {
                m_logger.LogDebug("{functionName} Task {taskName} is a conditional task. Evaluating expression {expression}.", nameof(ProcessSkraprTask), task.Name, conditionalExpressionTask.Condition);
                var conditionResponse = await Session.Runtime.EvaluateCondition(conditionalExpressionTask.Condition, contextId : DevTools.CurrentFrameContext.Id);

                if (conditionResponse == false)
                {
                    m_logger.LogDebug("{functionName} Condition result was false - skipping task {taskName}.", nameof(ProcessSkraprTask), task.Name);
                    return;
                }
                m_logger.LogDebug("{functionName} Condition result was true - processing task {taskName}.", nameof(ProcessSkraprTask), task.Name);
            }

            //Perform the task
            await task.PerformTask(this);

            m_logger.LogDebug("{functionName} Completed task {taskName}", nameof(ProcessSkraprTask), task.Name);
        }
예제 #2
0
        /// <summary>
        /// Adds the specified target to the queue.
        /// </summary>
        /// <param name="target"></param>
        public void Post(ISkraprTask task)
        {
            if (task == null)
            {
                throw new ArgumentNullException(nameof(task));
            }

            if (m_disposed)
            {
                return;
            }

            Logger.LogDebug("{functionName} Added task {taskName} to the main flow. ({details})", nameof(Post), task.Name, task.ToString());
            m_mainFlow.Post(task);
        }
예제 #3
0
        /// <summary>
        /// Processes the specified task on the main skrapr flow.
        /// </summary>
        /// <param name="task"></param>
        /// <returns></returns>
        private async Task ProcessMainSkraprTask(ISkraprTask task)
        {
            try
            {
                await ProcessSkraprTask(task);
            }
            catch (Exception ex) when(ex is AssertionFailedException || ex is NavigationFailedException)
            {
                //Add it back into the queue.
                m_mainFlow.Post(task);
            }
            catch (Exception ex) when(ex is OperationCanceledException || ex is TaskCanceledException)
            {
                m_logger.LogWarning("{functionName} is terminating due to a cancellation request.", nameof(ProcessMainSkraprTask));
                throw;
            }
            catch (Exception ex)
            {
                m_logger.LogError("{functionName} An unhandled error occurred while performing task {taskName} on frame {frameId}: {exception}", nameof(ProcessMainSkraprTask), task.Name, DevTools.CurrentFrameId, ex);
                throw;
            }

            //Get matching rules for the state of the session.
            var matchingRules = await GetMatchingRules();

            foreach (var rule in matchingRules)
            {
                m_logger.LogDebug("{functionName} Found rule that matches current frame state: ({ruleType} - {details})", nameof(ProcessSkraprTask), rule.Type, rule.ToString());
                var ruleSubflow = new Tasks.SubFlowTask()
                {
                    Tasks = rule.Tasks
                };

                Post(ruleSubflow);
                if (rule.Max.HasValue)
                {
                    rule.Max -= 1;
                }
            }

            if (matchingRules.Count() == 0)
            {
                m_logger.LogDebug("{functionName} A rule was not found that matches the current frame state for task {taskName}: ({details})", nameof(ProcessSkraprTask), task.Name, task.ToString());
            }

            //If there are no more tasks in the main flow...
            if (m_mainFlow.InputCount == 0)
            {
                //and there are no more shutdown tasks, complete.
                if (m_definition.Shutdown == null || m_definition.Shutdown.Count == 0)
                {
                    m_logger.LogDebug("{functionName} Completed processing all tasks in the main flow. Completing.", nameof(ProcessSkraprTask));
                    m_mainFlow.Complete();
                }
                //add any shutdown tasks to the flow.
                else
                {
                    m_logger.LogDebug("{functionName} Adding shutdown tasks to the main flow.", nameof(ProcessSkraprTask));
                    foreach (var shutdownTask in m_definition.Shutdown)
                    {
                        m_mainFlow.Post(shutdownTask);
                    }
                    m_definition.Shutdown.Clear();
                }
            }
        }
예제 #4
0
 DataflowMessageStatus ITargetBlock <ISkraprTask> .OfferMessage(DataflowMessageHeader messageHeader, ISkraprTask messageValue, ISourceBlock <ISkraprTask> source, bool consumeToAccept)
 {
     return(((ITargetBlock <ISkraprTask>)m_mainFlow).OfferMessage(messageHeader, messageValue, source, consumeToAccept));
 }