/// <summary> /// Returns an AppDomainHost to run the job. /// </summary> /// <remarks> /// Either an existing AppDomainHost is returned that has the /// required assembly, or a new AppDomainHost is created. /// </remarks> /// <param name="job"></param> /// <returns></returns> private AppDomainHost GetOrCreateAppDomainHost(Job job) { AppDomain ad; Components.AppDomainManager.Instance.GetAppDomainForType(job.WorkflowTypeName, true, out ad); if (!appDomains.ContainsKey(ad.Id)) { // New app domain, create host var adh = new AppDomainHost(ad, contextGuid); adh.WorkflowEvent += new EventHandler <HostEventArgs>(adh_WorkflowEvent); appDomains.Add(ad.Id, adh); adh.Start(Scheduler, interactive); return(adh); } else { // Old app domain, return existing host return(appDomains[ad.Id]); } }
/// <summary> /// Returns an AppDomainHost to run the job. /// </summary> /// <remarks> /// Either an existing AppDomainHost is returned that has the /// required assembly, or a new AppDomainHost is created. /// </remarks> /// <param name="job"></param> /// <returns></returns> private AppDomainHost GetOrCreateAppDomainHost(Job job) { AppDomain ad; Components.AppDomainManager.Instance.GetAppDomainForType(job.WorkflowTypeName, true, out ad); if (!appDomains.ContainsKey(ad.Id)) { // New app domain, create host var adh = new AppDomainHost(ad, contextGuid); adh.WorkflowEvent += new EventHandler<HostEventArgs>(adh_WorkflowEvent); appDomains.Add(ad.Id, adh); adh.Start(Scheduler, interactive); return adh; } else { // Old app domain, return existing host return appDomains[ad.Id]; } }
/// <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); }