Esempio n. 1
0
 protected virtual Task OnTaskIsDueAsync(HTaskSchedulerEventArgs e)
 {
     if (e == null)
     {
         return(Task.CompletedTask);
     }
     return(Cancellable.CancellableRunAsync(
                () => TaskIsDue?.Invoke(e.Sender, e)
                , this.Cts.Token));
 }
Esempio n. 2
0
        private void Process(IHTaskItem task)
        {
            HTaskSchedulerEventArgs evArgs = null;

            try
            {
                // check if task is eligible to run including retry on error status (if failed to run in an earlier attempt and the schedule
                // for when to retry and retry max attempts).


                if (!this.IsDue(task))
                {
                    return;
                }


                void RunTask()
                {
                    if (this.Cts.IsCancellationRequested)
                    {
                        return;
                    }

                    // todo: threaded having continuewith to check
                    // run status

                    evArgs = new HTaskSchedulerEventArgs(
                        this,
                        task,
                        this.Cts.Token
                        );

                    // if eligible to run (and has no previous error logged), trigger synchronous event
                    this.OnTaskIsDueAsync(evArgs)
                    .GetAwaiter().GetResult();
                }

                if (task.Schedule?.Repeat != null)
                {
                    AtomicGate delaySwitch = new AtomicGate();

                    foreach (var repeatDataModel in task.Schedule?.Repeat.EnsureEnumerable())
                    {
                        if (task.Schedule?.RepeatDelayInterval > 0 &&
                            !delaySwitch.TryOpen())
                        {
                            if (this.Cts?.Token != null)
                            {
                                Task.Delay((int)task.Schedule.RepeatDelayInterval, (CancellationToken)this.Cts.Token)
                                .GetAwaiter().GetResult();
                            }
                            else
                            {
                                Task.Delay((int)task.Schedule.RepeatDelayInterval)
                                .GetAwaiter().GetResult();
                            }
                        }
                        if (this.Cts.IsCancellationRequested)
                        {
                            return;
                        }
                        IEnumerable <IHTaskItem> AllChildren(IHTaskItem item)
                        {
                            return((item.Children?.SelectMany(x => AllChildren(x)) ??
                                    Enumerable.Empty <IHTaskItem>()).Append(item));
                        }
                        foreach (var child in AllChildren(task)
                                 //.Where(x => x.Vars?.Custom == null)
                                 )
                        {
                            child.Vars.Custom = repeatDataModel;
                        }
                        RunTask();
                    }
                }
                else
                {
                    RunTask();
                }

                // log successful run, and reset retry on error logic in case it was previously set.
                this.TimeLog[task.UniqueKey].LastExecuted = DateTime.Now;
                this.TimeLog[task.UniqueKey].ErrorCount   = 0;
                this.TimeLog[task.UniqueKey].LastError    = null;
                this.TimeLog.Save();
            }
            catch (Exception ex)
            {
                // catch errors within the thread, and check if retry on error is enabled
                // if enabled, don't throw exception, trigger OnErrorEvent async, then log error retry attempts and last error
                this.OnErrorAsync(new HTaskSchedularErrorEventArgs(this, ex, evArgs));
                if (task.Schedule.RetryAttemptsAfterError == null)
                {
                    throw;
                }
                this.TimeLog[task.UniqueKey].ErrorCount++;
                this.TimeLog[task.UniqueKey].LastError = DateTime.Now;
                this.TimeLog.Save();
            }
        }