示例#1
0
 private void RemoveFromInfos(JobRunInfo info)
 {
     if (info != null && _infos != null)
     {
         lock (_infos)
         {
             if (_infos.Contains(info))
             {
                 _infos.Remove(info);
             }
         }
     }
 }
示例#2
0
        private void LaunchNextJob(CancellationToken ct, bool runNow)
        {
            if (Configuration.RunState == JobRunState.Automatic || runNow)
            {
                var info = new JobRunInfo(new Task <bool>(() => Execute(ct), ct));

                info.StartTime = runNow ? DateTime.UtcNow : CalculateNextStartTime();

                if (_infos != null)
                {
                    lock (_infos)
                    {
                        _infos.Add(info);
                    }
                }

                Task.Run(() => Run(ct, info)); //does not block here on purpose
                _logger.Log(string.Format("Job \"{0}\" has been setup to run.", Configuration.Name));
            }
        }
示例#3
0
        private async Task RunTask(JobRunInfo info)
        {
            if (info != null && info.Task != null)
            {
                var watch = new Stopwatch();

                watch.Start();

                bool rc = false;

                try
                {
                    info.Task.Start();
                    Status         = JobStatus.Running;
                    info.IsRunning = true;

                    rc = await info.Task;
                }
                catch (OperationCanceledException)
                {
                    _logger.Log(string.Format("Job \"{0}\" canceled.", Configuration.Name), LogMessageSeverity.Warning);
                }
                catch (Exception ex)
                {
                    _logger.Log(string.Format("Job \"{0}\" failed! Error - {1}.", Configuration.Name, ex.Message), LogMessageSeverity.Error);
                }

                watch.Stop();

                info.CompletedSuccessfully = rc;
                info.RunDuration           = watch.Elapsed;
                info.IsRunning             = false;

                Status = rc ? JobStatus.Success : JobStatus.Error;

                string message = rc ? "completed successfully" : "failed to complete successfully";

                _logger.Log(string.Format("Job \"{0}\" {1}, run time = {2:hh\\:mm\\:ss}", Configuration.Name, message, watch.Elapsed), rc ? LogMessageSeverity.Information : LogMessageSeverity.Error);
            }
        }
示例#4
0
        //a self relaunching scheduler
        private async Task Run(CancellationToken ct, JobRunInfo info)
        {
            if (info != null)
            {
                if (Status != JobStatus.Misconfigured)
                {
                    try
                    {
                        _logger.Log(string.Format(string.Format("Job \"{0}\" scheduled to start \"{1}\"", Configuration.Name, info.StartTime.ToLocalTime())));
                        WaitTillDoneOrThrow(ct, info.StartTime); //wait till it's time, while checking for cancel token

                        _logger.Log(string.Format(string.Format("Job \"{0}\" starting at \"{1}\"", Configuration.Name, DateTime.UtcNow.ToLocalTime())));

                        bool willRun = !HasRunningTask() || Configuration.AllowSimultaneousExecutions;

                        if (!willRun && Configuration.RunImmediatelyIfRunTimeMissed)
                        {
                            _logger.Log(string.Format("Job \"{0}\" missed scheduled execution window, will run immediately after currently executing job.", Configuration.Name), LogMessageSeverity.Warning);

                            Task <bool>[] tasks = null;

                            if (_infos != null)
                            {
                                lock (_infos)
                                {
                                    tasks = _infos.Where(j => j.IsRunning).Select(j => j.Task).ToArray();
                                }
                            }

                            if (tasks != null)
                            {
                                if (tasks.Count() > 0)
                                {
                                    Task.WaitAll(tasks); //blocks till all the tasks are done
                                }
                            }

                            willRun = true;
                        }

                        LaunchNextJob(ct, false); //launch the next job no matter what

                        if (willRun)
                        {
                            await RunTask(info); //actually run it!
                        }
                        else
                        {
                            _logger.Log(string.Format("Job \"{0}\" missed scheduled execution window.", Configuration.Name), LogMessageSeverity.Warning);
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        _logger.Log(string.Format("The scheduled job, \"{0}\", has been canceled prior to execution.", Configuration.Name), LogMessageSeverity.Warning);
                    }
                    catch (Exception ex)
                    {
                        _logger.Log(string.Format("The scheduled job, \"{0}\", has encountered an error prior to execution - {1}.", Configuration.Name, ex.Message), LogMessageSeverity.Error);
                    }
                }
                else
                {
                    _logger.Log(string.Format("Job \"{0}\" cannot run because it is misconfigured...", Configuration.Name), LogMessageSeverity.Error);
                }

                RemoveFromInfos(info); //need to remove here no matter what, success, failure, cancel, exception, missed window, etc
            }
        }