示例#1
0
        /// <summary>
        /// Execute scenario in other thread
        /// </summary>
        /// <param name="param"></param>
        /// <param name="cancelToken"></param>
        public virtual void ExecuteAsyncParallel(ScenarioActionSource source, string param, ExecutionContext parentContext)
        {
            CheckRights(source, parentContext);

            TaskUtils.StartLongRunning(() =>
            {
                CheckValue(param, parentContext);
                var output = new OutputChangedDelegates();
                ExecutionContext context;
                var oldVal = GetPreviousValue();
                if (parentContext != null)
                {
                    var cancellationTokenSource = new SafeCancellationToken();
                    parentContext.CancellationTokenSource.RegisterCallback(cancellationTokenSource.Cancel);
                    context = new ExecutionContext(this, param, oldVal, output, parentContext, cancellationTokenSource);
                }
                else
                {
                    context = new ExecutionContext(this, param, oldVal, output, new SafeCancellationToken());
                }
                CheckContext(context);
                HandleExecution(() => ExecuteInternal(context));
            },
                                       HandleSet);
        }
示例#2
0
        public void SetValue(Lazurite.ActionsDomain.ExecutionContext context, string value)
        {
            float val = 0;

            float.TryParse(value, out val);
            Thread.Sleep(TimeSpan.FromMinutes(val));
        }
示例#3
0
 protected void CheckValue(string param, ExecutionContext parentContext)
 {
     try
     {
         if (!ValueType.Interprete(param).Success)
         {
             throw new ScenarioExecutionException(ScenarioExecutionError.InvalidValue, param);
         }
     }
     catch (Exception e)
     {
         parentContext?.CancelAll(); //stop execution
         throw e;
     }
 }
示例#4
0
 protected void CheckRights(ScenarioActionSource source, ExecutionContext context)
 {
     try
     {
         if (!IsAccessAvailable(source))
         {
             throw new ScenarioExecutionException(ScenarioExecutionError.AccessDenied);
         }
     }
     catch (Exception e)
     {
         context?.CancelAll(); //stop execution
         throw e;
     }
 }
示例#5
0
 /// <summary>
 /// Current value of scenario execution
 /// </summary>
 public virtual string CalculateCurrentValue(ScenarioActionSource source, ExecutionContext parentContext)
 {
     CheckRights(source, parentContext);
     try
     {
         if (parentContext != null)
         {
             //empty context, just for stack overflow and circular reference check
             var context = new ExecutionContext(this, string.Empty, string.Empty, null, parentContext, parentContext.CancellationTokenSource);
             CheckContext(context);
         }
         return(CalculateCurrentValueInternal());
     }
     catch (Exception e)
     {
         HandleGet(e);
         throw e;
     }
 }
示例#6
0
        protected void CheckContext(ExecutionContext context)
        {
            try
            {
                if (context.Find((x) => x.AlgorithmContext is ScenarioBase scenarioBase && scenarioBase.Id == Id) != null) //if true - then it is circular reference
                {
                    throw new ScenarioExecutionException(ScenarioExecutionError.CircularReference);
                }

                if (context.ExecutionNesting >= MaxStackValue)
                {
                    throw new ScenarioExecutionException(ScenarioExecutionError.StackOverflow);
                }
            }
            catch (Exception e)
            {
                context?.CancelAll(); //stop execution
                throw e;
            }
        }
示例#7
0
        protected ExecutionContext PrepareExecutionContext(string param, ExecutionContext parentContext)
        {
            var output = new OutputChangedDelegates();

            output.Add(val => SetCurrentValue(val, SystemActionSource));
            var tokenSource = PrepareCancellationTokenSource();
            ExecutionContext context;
            var prevValue = GetCurrentValue();

            if (parentContext == null)
            {
                context = new ExecutionContext(this, param, prevValue, output, tokenSource);
            }
            else
            {
                context = new ExecutionContext(this, param, prevValue, output, parentContext, tokenSource);
                parentContext.CancellationTokenSource.RegisterCallback(tokenSource.Cancel);
                CheckContext(context);
            }
            return(context);
        }
示例#8
0
 public ExecutionContext(IAlgorithmContext algorithmContext, string input, string previousValue, OutputChangedDelegates output, ExecutionContext parentContext, CancellationTokenSource cancellationTokenSource)
 {
     OutputChanged           = output;
     AlgorithmContext        = algorithmContext;
     Input                   = input;
     PreviousValue           = previousValue;
     CancellationTokenSource = cancellationTokenSource;
     ParentContext           = parentContext;
     ExecutionNesting        = ParentContext.ExecutionNesting + 1;
 }
示例#9
0
 public string GetValue(Lazurite.ActionsDomain.ExecutionContext context)
 {
     return("0");
 }
示例#10
0
 /// <summary>
 /// Execute scenario in current thread
 /// </summary>
 /// <param name="param"></param>
 /// <param name="cancelToken"></param>
 protected abstract void ExecuteInternal(ExecutionContext context);
示例#11
0
 /// <summary>
 /// Execute in current thread
 /// </summary>
 /// <param name="param"></param>
 /// <param name="cancelToken"></param>
 public virtual void Execute(ScenarioActionSource source, string param, out string executionId, ExecutionContext parentContext = null)
 {
     executionId = PrepareExecutionId();
     CheckRights(source, parentContext);
     try
     {
         CheckValue(param, parentContext);
         TryCancelAll();
         var context = PrepareExecutionContext(param, parentContext);
         HandleExecution(() =>
         {
             SetPreviousValue(GetCurrentValue());
             SetCurrentValue(param, source);
             ExecuteInternal(context);
         });
     }
     catch (Exception e)
     {
         HandleSet(e);
     }
 }
示例#12
0
 /// <summary>
 /// Execute scenario in main execution context
 /// </summary>
 /// <param name="param"></param>
 public virtual void ExecuteAsync(ScenarioActionSource source, string param, out string executionId, ExecutionContext parentContext = null)
 {
     executionId = PrepareExecutionId();
     CheckRights(source, parentContext);
     TaskUtils.StartLongRunning(() =>
     {
         CheckValue(param, parentContext);
         TryCancelAll();
         var context = PrepareExecutionContext(param, parentContext);
         HandleExecution(() =>
         {
             SetPreviousValue(GetCurrentValue());
             SetCurrentValue(param, source);
             ExecuteInternal(context);
         });
     },
                                HandleSet);
 }
示例#13
0
        protected override void RunInternal()
        {
            if (GetScenario() == null)
            {
                return;
            }

            //удаляем старую подписку, если имеется
            if (_lastSubscribe != null)
            {
                GetScenario().RemoveOnStateChanged(_lastSubscribe);
            }

            //выполнение по подписке на изменение значения
            var executeBySubscription = true;

            //если сценарий это одиночное действие и нельзя подписаться на изменение целевого действия
            //то не выполняем по подписке, а выполняем просто через цикл
            if (GetScenario() is SingleActionScenario singleActionScen && !singleActionScen.ActionHolder.Action.IsSupportsEvent)
            {
                executeBySubscription = false;
            }

            var contextCancellationToken = new SafeCancellationToken();

            CancellationToken.RegisterCallback(contextCancellationToken.Cancel);
            if (executeBySubscription)
            {
                _lastSubscribe = (sender, args) =>
                {
                    if (CancellationToken.IsCancellationRequested)
                    {
                        //crutch; scenario can be changed before initializing, then we need to remove
                        //current subscribe from previous scenario. CancellationToken.IsCancellationRequested
                        //can be setted in true only when trigger stopped;
                        args.Value.Scenario.RemoveOnStateChanged(_lastSubscribe);
                    }
                    else
                    {
                        if (!args.Value.OnlyIntent)
                        {
                            var action        = TargetAction;
                            var outputChanged = new OutputChangedDelegates();
                            outputChanged.Add((value) => GetScenario().SetCurrentValue(value, ExecuteActionSource));
                            contextCancellationToken.Cancel();
                            contextCancellationToken = new SafeCancellationToken();
                            var executionContext = new ExecutionContext(this, args.Value.Value, args.Value.PreviousValue, outputChanged, contextCancellationToken);
                            TaskUtils.StartLongRunning(
                                () => action.SetValue(executionContext, string.Empty),
                                (exception) => Log.ErrorFormat(exception, "Ошибка выполнения триггера [{0}][{1}]", Name, Id));
                        }
                    }
                };
                GetScenario().SetOnStateChanged(_lastSubscribe);
            }
            else
            {
                var lastVal = string.Empty;
                var timerCancellationToken = SystemUtils.StartTimer(
                    (token) =>
                {
                    try
                    {
                        var curVal = GetScenario().CalculateCurrentValue(ViewActionSource, null);
                        if (!lastVal.Equals(curVal))
                        {
                            var prevVal = GetScenario().GetPreviousValue();
                            lastVal     = curVal;
                            contextCancellationToken.Cancel();
                            contextCancellationToken = new SafeCancellationToken();
                            var executionContext     = new ExecutionContext(this, curVal, prevVal, new OutputChangedDelegates(), contextCancellationToken);
                            try
                            {
                                TargetAction.SetValue(executionContext, string.Empty);
                            }
                            catch (Exception exception)
                            {
                                Log.ErrorFormat(exception, "Ошибка выполнения триггера [{0}][{1}]", Name, Id);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Log.ErrorFormat(e, "Ошибка выполнения триггера [{0}][{1}]", Name, Id);
                    }
                },
                    () => TriggerChangesListenInterval,
                    true,
                    ticksSuperposition: true /*наложение тиков*/);
                CancellationToken.RegisterCallback(timerCancellationToken.Cancel);
            }
        }
 public override string CalculateCurrentValue(ScenarioActionSource source, ExecutionContext parentContext)
 {
     CheckRights(source, parentContext);
     return(CalculateCurrentValueInternal());
 }
示例#15
0
 /// <summary>
 /// Current value of scenario execution
 /// </summary>
 public virtual void CalculateCurrentValueAsync(ScenarioActionSource source, Action <string> callback, ExecutionContext parentContext)
 {
     CheckRights(source, parentContext);
     TaskUtils.Start(
         () =>
     {
         var result = CalculateCurrentValue(source, parentContext);
         callback(result);
     },
         HandleGet);
 }
 protected override void ExecuteInternal(ExecutionContext context)
 {
     TargetAction.SetValue(context, string.Empty);
 }
 public override void CalculateCurrentValueAsync(ScenarioActionSource source, Action <string> callback, ExecutionContext parentContext)
 {
     CheckRights(source, parentContext);
     callback(CalculateCurrentValueInternal());
 }