Exemplo n.º 1
0
        /// <summary>
        /// Reschedules the job instance if it's a recurring job.
        /// </summary>
        /// <returns>The new job instance that is in the queue now.</returns>
        /// <remarks>
        /// The completed job is marked as completed and is stored for reference, so a new
        /// job instance is created with updated properties.
        /// </remarks>
        public JobInstance RescheduleIfRecurring()
        {
            if ((jobExecutionStatus == Registry.JobExecutionState.Completed ||
                 jobExecutionStatus == Registry.JobExecutionState.Failed ||
                 jobExecutionStatus == Registry.JobExecutionState.Cancelled) &&
                scheduleType == ScheduleType.Recurring)
            {
                // Create a copy first
                JobInstance newjob = new JobInstance(this);

                // Reset properties
                newjob.Guid               = Guid.Empty;
                newjob.Name               = GenerateRecurringJobID();
                newjob.dateStarted        = DateTime.MinValue;
                newjob.dateFinished       = DateTime.MinValue;
                newjob.JobExecutionStatus = JobExecutionState.Scheduled;
                newjob.ScheduleTime       = GetNextScheduleTime();
                newjob.workflowInstanceId = Guid.Empty;
                newjob.adminRequestTime   = DateTime.MinValue;
                newjob.adminRequestData   = null;
                newjob.adminRequestResult = -1;
                newjob.exceptionMessage   = null;

                // Save new job
                newjob.Save();

                return(newjob);
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Starts a single job
        /// </summary>
        /// <param name="job"></param>
        private void StartOrResumeJob(Job job)
        {
            AppDomainHost adh = null;

            using (Context context = ContextManager.Instance.CreateContext(ConnectionMode.AutoOpen, TransactionMode.AutoCommit))
            {
                context.JobGuid = job.Guid;
                context.ContextGuid = contextGuid;

                JobInstance ji = new JobInstance(context);
                ji.Guid = job.Guid;
                ji.Load();

                // Lock the job, so noone else can pick it up
                ji.DateStarted = DateTime.Now;
                ji.ObtainLock();

                ji.Save();
            }

            // Schedule job in the appropriate app domain
            adh = GetOrCreateAppDomainHost(job);

            // Check if job is a new instance or previously persisted and
            // has to be resumed
            switch (job.Status)
            {
                case JobStatus.Starting:
                    if (interactive)
                    {
                        Console.WriteLine("Starting job: {0}", job.Guid);
                    }

                    job.WorkflowInstanceId = adh.PrepareStartJob(job);
                    break;
                case JobStatus.Resuming:
                    if (interactive)
                    {
                        Console.WriteLine("Resuming job: {0}", job.Guid);
                    }

                    job.WorkflowInstanceId = adh.PrepareResumeJob(job);
                    break;
                default:
                    throw new NotImplementedException();
            }

            // Update job status
            job.TimeStarted = DateTime.Now;
            job.Status = JobStatus.Executing;
            job.AppDomainID = adh.ID;

            // TODO: this has to happen before starting the job
            lock (runningJobs)
            {
                runningJobs.Add(job.WorkflowInstanceId, job);
            }

            adh.RunJob(job);
        }
Exemplo n.º 3
0
        private void PersistJob(Job job)
        {
            using (Context context = ContextManager.Instance.CreateContext(ConnectionMode.AutoOpen, TransactionMode.AutoCommit))
            {
                context.JobGuid = job.Guid;
                context.ContextGuid = contextGuid;

                var ji = new JobInstance(context);
                ji.Guid = job.Guid;
                ji.Load();

                // Update registry
                ji.JobExecutionStatus = JobExecutionState.Persisting;

                ji.Save();
            }

            // Update job status
            job.Status = JobStatus.Persisted;

            appDomains[job.AppDomainID].PersistJob(job);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Finished the execution of a job and records the results in the registry.
        /// </summary>
        /// <param name="workflowInstanceId"></param>
        /// <param name="eventType"></param>
        private void FinishJob(Job job, HostEventArgs e)
        {
            using (Context context = ContextManager.Instance.CreateContext(ConnectionMode.AutoOpen, TransactionMode.AutoCommit))
            {
                context.JobGuid = job.Guid;
                context.ContextGuid = contextGuid;

                JobInstance ji = new JobInstance(context);
                ji.Guid = job.Guid;
                ji.Load();

                // Update execution status, error message and finish time
                switch (e.EventType)
                {
                    case WorkflowEventType.Completed:
                        ji.JobExecutionStatus = JobExecutionState.Completed;
                        break;
                    case WorkflowEventType.Cancelled:
                        ji.JobExecutionStatus = JobExecutionState.Cancelled;
                        break;
                    case WorkflowEventType.TimedOut:
                        ji.JobExecutionStatus = JobExecutionState.TimedOut;
                        break;
                    case WorkflowEventType.Persisted:
                        ji.JobExecutionStatus = JobExecutionState.Persisted;
                        break;
                    case WorkflowEventType.Failed:
                        ji.JobExecutionStatus = JobExecutionState.Failed;
                        ji.ExceptionMessage = e.ExceptionMessage;
                        break;
                }

                // Update registry
                ji.DateFinished = DateTime.Now;
                ji.Save();

                ji.ReleaseLock(false);
                ji.RescheduleIfRecurring();

                // Do local bookkeeping
                lock (runningJobs)
                {
                    lock (Cluster.Queues[job.QueueGuid].Jobs)
                    {
                        Cluster.Queues[job.QueueGuid].Jobs.Remove(job.Guid);
                    }

                    runningJobs.Remove(job.WorkflowInstanceId);
                }

                if (interactive)
                {
                    Console.WriteLine("Finishing job: {0}", ji.Guid);
                }
            }
        }
Exemplo n.º 5
0
        private void CancelOrTimeOutJob(Job job, bool timeout)
        {
            using (Context context = ContextManager.Instance.CreateContext(ConnectionMode.AutoOpen, TransactionMode.AutoCommit))
            {
                context.JobGuid = job.Guid;
                context.ContextGuid = contextGuid;

                var ji = new JobInstance(context);
                ji.Guid = job.Guid;
                ji.Load();

                // Update registry
                ji.JobExecutionStatus = JobExecutionState.Cancelling;

                ji.Save();
            }

            // Update job status
            if (timeout)
            {
                job.Status = JobStatus.TimedOut;
                appDomains[job.AppDomainID].TimeOutJob(job);
            }
            else
            {
                job.Status = JobStatus.Cancelled;
                appDomains[job.AppDomainID].CancelJob(job);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Reschedules the job instance if it's a recurring job.
        /// </summary>
        /// <returns>The new job instance that is in the queue now.</returns>
        /// <remarks>
        /// The completed job is marked as completed and is stored for reference, so a new
        /// job instance is created with updated properties.
        /// </remarks>
        public JobInstance RescheduleIfRecurring()
        {
            if ((jobExecutionStatus == Registry.JobExecutionState.Completed ||
                jobExecutionStatus == Registry.JobExecutionState.Failed ||
                jobExecutionStatus == Registry.JobExecutionState.Cancelled)
                && scheduleType == ScheduleType.Recurring)
            {
                // Create a copy first
                JobInstance newjob = new JobInstance(this);

                // Reset properties
                newjob.Guid = Guid.Empty;
                newjob.Name = GenerateRecurringJobID();
                newjob.dateStarted = DateTime.MinValue;
                newjob.dateFinished = DateTime.MinValue;
                newjob.JobExecutionStatus = JobExecutionState.Scheduled;
                newjob.ScheduleTime = GetNextScheduleTime();
                newjob.workflowInstanceId = Guid.Empty;
                newjob.adminRequestTime = DateTime.MinValue;
                newjob.adminRequestData = null;
                newjob.adminRequestResult = -1;
                newjob.exceptionMessage = null;

                // Save new job
                newjob.Save();

                return newjob;
            }
            else
            {
                return null;
            }
        }