public static List <JobInstance> QueueJob(Integration integration, IEnumerable <DataSource> sourceSideDataSourcesToRun, Job jobToRun, DateTime scheduledStartTime, string invocationSource, JobInvocationSourceType invocationSourceType, List <JobFilter> filters = null) { if (integration == null) { throw new Exception("Integration is missing or empty."); } if (sourceSideDataSourcesToRun == null || sourceSideDataSourcesToRun.Where(d => d != null).Count() == 0) { throw new Exception(string.Format("At least one source-side data source is required to queue job '{0}'.", jobToRun.Name)); } foreach (var dataSource in sourceSideDataSourcesToRun) { if (!jobToRun.SourceDataSources.ContainsKey(dataSource.Name)) { throw new Exception(string.Format("Source-side data source '{0}' does not exist for job '{1}'. This job will not be queued for execution.", dataSource.Name, jobToRun.Name)); } } if (String.IsNullOrWhiteSpace(invocationSource)) { throw new Exception("Invocation source is missing or empty."); } if (!integration.IsEnabled) { throw new Exception(string.Format("Job '{0}' could not be queued for execution because integration '{1}' is disabled.", jobToRun.Name, integration.Name)); } if (!jobToRun.IsEnabled) { throw new Exception(string.Format("Job '{0}' could not be queued for execution because it is disabled.", jobToRun.Name)); } if (jobToRun.Steps.Where(d => d.IsEnabled).Count() == 0) { throw new Exception(string.Format("Job '{0}' could not be queued for execution because no job steps exist or all are disabled.", jobToRun.Name)); } SetMaxConcurrentThreadsForIntegration(integration); List <JobInstance> queuedJobs = new List <JobInstance>(); JobInstance jobInstance; JobStepInstance jobStepInstance; List <JobStepInstance> jobStepInstances; var queueRequest = new JobQueueRequest(integration, jobToRun, invocationSourceType); queueRequest.StatusChanged += new EventHandler <JobQueueRequestStatusChangedArgs>(HandleChangedQueueRequestStatus); queueRequest.Status = JobQueueRequestStatus.Waiting; foreach (var sourceSideDataSource in sourceSideDataSourcesToRun) { byte jobStepIdx = 0; jobStepInstances = new List <JobStepInstance>(); foreach (var jobStep in jobToRun.Steps) { if (jobStep.IsEnabled) { jobStepInstance = new JobStepInstance(jobStep, jobStepIdx); jobStepInstance.StatusChanged += new EventHandler <JobStepQueueStatusChangedArgs>(HandleChangedJobStepStatus); jobStepInstances.Add(jobStepInstance); //jobStepInstance.Status = JobStepQueueStatus.Waiting; jobStepIdx++; } } jobInstance = new JobInstance(queueRequest, integration, jobToRun, sourceSideDataSource, jobToRun.TargetDataSource, jobStepInstances, scheduledStartTime, invocationSource, invocationSourceType, filters); queueRequest.JobInstances.Add(jobInstance); // change the status here to avoid the job step not having an association with the job instance when status changes are logged foreach (var jobStepInstanceToFireStatusChangeFor in jobStepInstances) { jobStepInstanceToFireStatusChangeFor.Status = JobStepQueueStatus.Waiting; } jobInstance.StatusChanged += new EventHandler <JobQueueStatusChangedArgs>(HandleChangedJobStatus); if (waitingJobsByIntegrationId.ContainsKey(jobInstance.Integration.Id)) { waitingJobsByIntegrationId[jobInstance.Integration.Id].Add(jobInstance); } else { waitingJobsByIntegrationId.Add(jobInstance.Integration.Id, new List <JobInstance>() { jobInstance }); } // cache the job instance in memory if on-demand (temporary to get around OutOfMemoryException) if (jobInstance.InvocationSourceType == JobInvocationSourceType.OnDemand) { jobInstancesById.Add(jobInstance.Id, jobInstance); queueRequestsById.Add(queueRequest.Id, queueRequest); } jobInstance.Status = JobQueueStatus.Scheduled; queuedJobs.Add(jobInstance); if (JobQueued != null) { JobQueued(null, new JobQueuedArgs(jobInstance)); } } return(queuedJobs); }