public void AddJobListener(IJobListener jobListener, IList<IMatcher<JobKey>> matchers) { if (String.IsNullOrEmpty(jobListener.Name)) { throw new ArgumentException( "JobListener name cannot be empty."); } lock (globalJobListeners) { globalJobListeners[jobListener.Name] = jobListener; List<IMatcher<JobKey>> matchersL = new List<IMatcher<JobKey>>(); if (matchers != null && matchers.Count > 0) { matchersL.AddRange(matchers); } else { matchersL.Add(EverythingMatcher<JobKey>.AllJobs()); } globalJobListenersMatchers[jobListener.Name] = matchersL; } }
private void AddJobListener(IJobListener jobListener, string jobGroup) { if (Scheduler != null) { Scheduler.ListenerManager.AddJobListener(jobListener, GroupMatcher <JobKey> .GroupEquals(jobGroup)); } }
/// <summary> /// Initializes a new instance of the <see cref="QuartzServer" /> class. The given internal jobs will be executed once /// and /// then scheduled as normal jobs /// </summary> public QuartzServer(IJobFactory jobFactory, IJobListener jobListener, ISchedulerFactory factory, IInternalJob[] internalJobs) { _jobFactory = jobFactory; _jobListener = jobListener; _internalJobs = internalJobs; _schedulerFactory = factory; }
public void AddJobListener(IJobListener jobListener, IReadOnlyCollection <IMatcher <JobKey> > matchers) { if (string.IsNullOrEmpty(jobListener.Name)) { throw new ArgumentException( "JobListener name cannot be empty."); } lock (globalJobListeners) { globalJobListeners[jobListener.Name] = jobListener; List <IMatcher <JobKey> > matchersL = new List <IMatcher <JobKey> >(); if (matchers != null && matchers.Count > 0) { matchersL.AddRange(matchers); } else { matchersL.Add(EverythingMatcher <JobKey> .AllJobs()); } globalJobListenersMatchers[jobListener.Name] = matchersL; } }
public static bool Set(string schedulerName, string jobsConfigPath, bool isRun, ILogger logger, IJobListener globalJobListener, JobToBeExecuted globalBeforeExecuted, JobWasExecuted globalAfterExecuted) { schedulerName = schedulerName.Trim().ToLower(); jobsConfigPath = jobsConfigPath.Trim().ToLower(); if (Schedulers.ContainsKey(schedulerName)) { if (jobsConfigPath == Schedulers[schedulerName].JobsConfigPath) { throw new Exception("所设置的调度器已经存在,不做任何操作"); } Schedulers[schedulerName].Stop(); lock (sync) { Schedulers.Remove(schedulerName); } } lock (sync) { Schedulers.Add(schedulerName, new QuartzScheduler(schedulerName, jobsConfigPath, logger, globalJobListener, globalBeforeExecuted, globalAfterExecuted)); if (isRun) { Schedulers[schedulerName].Start(); } } return(true); }
public static bool SetAndRun(string schedulerName, string jobsConfigPath, ILogger logger, IJobListener globalJobListener, JobToBeExecuted globalBeforeExecuted, JobWasExecuted globalAfterExecuted) { return(Set(schedulerName, jobsConfigPath, true, logger, globalJobListener, globalBeforeExecuted, globalAfterExecuted)); }
public QuartzScheduler(string name, string jobsConfigPath, ILogger logger, IJobListener globalJobListener, JobToBeExecuted globalBeforeExecuted, JobWasExecuted globalAfterExecuted) { JobsConfigPath = jobsConfigPath; JobCfgFileWatch(); if (logger == null) { Log = LogCentral.Current; } else { Log = logger; } if (name == null) { Name = jobsConfigPath; } else { Name = name; } GlobalJobListener = globalJobListener; GlobalBeforeExecuted = globalBeforeExecuted; GlobalAfterExecuted = globalAfterExecuted; IsStop = true; }
public JobListener(IJobListener listener) { Listener = listener; Matchers = new IMatcher <JobKey>[] { EverythingMatcher <JobKey> .AllJobs() }; }
public QuartzHostedService(ILogger <QuartzHostedService> logger, ISchedulerFactory schedulerFactory, IJobFactory jobFactory, IEnumerable <JobSchedule> jobSchedules, IJobListener jobListener, ISchedulerListener schedulerListener) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _schedulerFactory = schedulerFactory ?? throw new ArgumentNullException(nameof(schedulerFactory)); _jobFactory = jobFactory ?? throw new ArgumentNullException(nameof(jobFactory)); _jobListener = jobListener ?? throw new ArgumentNullException(nameof(jobListener)); _schedulerListener = schedulerListener ?? throw new ArgumentNullException(nameof(schedulerListener)); _injectJobSchedules = jobSchedules ?? throw new ArgumentNullException(nameof(jobSchedules)); }
protected internal virtual void ProcessInternal(string xml) { ClearValidationExceptions(); scheduledJobs.Clear(); jobsToSchedule.Clear(); calsToSchedule.Clear(); ValidateXmlIfNeeded(xml); // deserialize as object model XmlSerializer xs = new XmlSerializer(typeof(quartz)); quartz data = (quartz)xs.Deserialize(new StringReader(xml)); // process data // add calendars if (data.calendar != null) { foreach (calendarType ct in data.calendar) { CalendarBundle c = CreateCalendarFromXmlObject(ct); AddCalendarToSchedule(c); } } // add job scheduling bundles ProcessJobs(data); if (data.joblistener != null) { // go through listeners foreach (joblistenerType jt in data.joblistener) { Type listenerType = Type.GetType(jt.type); if (listenerType == null) { throw new SchedulerConfigException("Unknown job listener type " + jt.type); } IJobListener listener = (IJobListener)ObjectUtils.InstantiateType(listenerType); // set name of trigger with reflection, this might throw errors NameValueCollection properties = new NameValueCollection(); properties.Add("Name", jt.name); try { ObjectUtils.SetObjectProperties(listener, properties); } catch (Exception) { throw new SchedulerConfigException(string.Format("Could not set name for job listener of type '{0}', do you have public set method defined for property 'Name'?", jt.type)); } AddListenerToSchedule(listener); } } MaybeThrowValidationException(); }
private static IScheduler GetScheduler(ITriggerListener triggerListener, IJobListener jobListener) { var quartzScheduler = StdSchedulerFactory.GetDefaultScheduler().Result; // registering listeners quartzScheduler.ListenerManager.AddTriggerListener(triggerListener, GroupMatcher <TriggerKey> .AnyGroup()); quartzScheduler.ListenerManager.AddJobListener(jobListener, GroupMatcher <JobKey> .AnyGroup()); return(quartzScheduler); }
public bool RemoveListener(string listenerName) { IJobListener listener = listeners.Find(x => x.Name == listenerName); if (listener != null) { listeners.Remove(listener); return(true); } return(false); }
public JobHostedService( ISchedulerFactory schedulerFactory, IJobFactory jobFactory, IJobListener jobListener, IEnumerable <JobSchedule> jobSchedules) { this.schedulerFactory = schedulerFactory; this.jobFactory = jobFactory; this.jobListener = jobListener; this.jobSchedules = jobSchedules; }
public bool RemoveListener(IJobListener listener) { if (listeners.Contains(listener)) { listeners.Remove(listener); return(true); } else { return(false); } }
public void AttachListener(IJobListener listener) { if (listener == null) { throw new ArgumentNullException("listener"); } if (this.listener != null) { throw new InvalidOperationException("Only one listener can be attached to a job at a time."); } this.listener = listener; }
/// <summary> /// Remove the specified name of a <see cref="IJobListener" /> from /// the <see cref="IJob" />'s list of listeners. /// </summary> /// <returns>true if the given name was found in the list, and removed</returns> public virtual bool RemoveJobListener(string listenerName) { for (int i = 0; i < jobListeners.Count; i++) { IJobListener listener = (IJobListener)jobListeners[i]; if (listener.Name == listenerName) { jobListeners.RemoveAt(i); return(true); } } return(false); }
/// <summary> /// Looks up the listener's <see cref="Type">Type</see> in the job's data map. You must set the value /// of the listener's type in a parameter called "type". /// </summary> /// <param name="context"></param> public void Execute(IJobExecutionContext context) { string type = context.MergedJobDataMap.GetString("type"); if (string.IsNullOrEmpty(type)) { throw new ArgumentNullException("type", "Could not find a parameter named type in the job's datamap."); } IJobListener listener = (IJobListener)Type.GetType(type).GetConstructor(new Type[] { }).Invoke(null); IMatcher <JobKey> matcher = Quartz.Impl.Matchers.EverythingMatcher <JobKey> .AllJobs(); context.Scheduler.ListenerManager.AddJobListener(listener, matcher); }
public bool RemoveListener(string listenerName) { for (int i = 0; i < listeners.Count; ++i) { IJobListener jl = (IJobListener)listeners[i]; if (jl.Name.Equals(listenerName)) { listeners.RemoveAt(i); return(true); } } return(false); }
/// <summary> /// 任务监视器 /// </summary> /// <returns></returns> public static IJobListener GetJobListener() { if (jobListener == null) { lock (lockObj2) { if (jobListener == null) { //获取监听 jobListener = new CustomJobListener(); } } } return(jobListener); }
/// <summary> /// 任务监视器 /// </summary> /// <returns></returns> public static IJobListener GetJobListener() { if (jobListener == null) { lock (lockObj2) { if (jobListener == null) { //获取监听 jobListener = new CustomJobListener(); } } } return jobListener; }
public void AddJobListener(IJobListener jobListener, IList <IMatcher <JobKey> > matchers) { if (String.IsNullOrEmpty(jobListener.Name)) { throw new ArgumentException( "JobListener name cannot be empty."); } lock (globalJobListeners) { globalJobListeners[jobListener.Name] = jobListener; if (matchers == null) { matchers = new List <IMatcher <JobKey> >(); } if (matchers.Count == 0) { matchers.Add(EverythingMatcher <JobKey> .AllJobs()); } globalJobListenersMatchers[jobListener.Name] = new List <IMatcher <JobKey> >(matchers); } }
public static bool Add(string schedulerName, string jobsConfigPath, bool isRun, ILogger logger, IJobListener globalJobListener, JobToBeExecuted globalBeforeExecuted, JobWasExecuted globalAfterExecuted) { schedulerName = schedulerName.Trim().ToLower(); jobsConfigPath = jobsConfigPath.Trim().ToLower(); if (Schedulers.ContainsKey(schedulerName)) { throw new Exception(string.Concat("已存在相同名称的调度器,参数:schedulerName='", schedulerName, "'")); } lock (sync) { Schedulers.Add(schedulerName, new QuartzScheduler(schedulerName, jobsConfigPath, logger, globalJobListener, globalBeforeExecuted, globalAfterExecuted)); if (isRun) { Schedulers[schedulerName].Start(); } } return(true); }
public void RemoveTask(ScheduledTask task) { IJobListener jobListener = m_QuartzScheduler.ListenerManager.GetJobListener(task.TaskName); if (jobListener != null) { //Following should always be true, but checking anyway in case the use of jobs is expanded if (jobListener is ExecuteSequenceJobListener) { ExecuteSequenceJobListener executeSequenceJobListener = (ExecuteSequenceJobListener)jobListener; executeSequenceJobListener.TaskStart -= jobListener_TaskStart; executeSequenceJobListener.TaskComplete -= jobListener_TaskComplete; } m_QuartzScheduler.ListenerManager.RemoveJobListener(task.TaskName); } JobKey jobKey = JobKey.Create(task.TaskName, JobKey.DefaultGroup); if (m_QuartzScheduler.CheckExists(jobKey)) { m_QuartzScheduler.DeleteJob(jobKey); } }
/// <summary> /// Add <paramref name="listner"/> for a given job <paramref name="key"/> /// </summary> /// <param name="scheduler"></param> /// <param name="listner"></param> /// <param name="key"></param> public static void AddListner(this IScheduler scheduler, IJobListener listner, JobKey key) { scheduler.ListenerManager.AddJobListener(listner, KeyMatcher <JobKey> .KeyEquals(key)); }
/// <summary> /// Calls the equivalent method on the 'proxied' <see cref="QuartzScheduler" />, /// passing the <see cref="SchedulingContext" /> associated with this /// instance. /// </summary> public virtual bool RemoveGlobalJobListener(IJobListener jobListener) { throw new SchedulerException("Operation not supported for remote schedulers.", SchedulerException.ErrorUnsupportedFunctionInThisConfiguration); }
public bool RemoveListener(IJobListener listener) { return(listeners.Remove(listener)); }
/// <summary> /// 为指定的作业添加监听器 /// </summary> /// <param name="jobListener"></param> /// <param name="JobName"></param> /// <param name="GroupName"></param> public void AddListener(IJobListener jobListener, string JobName, string GroupName) { sche.ListenerManager.AddJobListener(jobListener, KeyMatcher<JobKey>.KeyEquals(new JobKey(JobName, GroupName))); }
public void AddJobListener(IJobListener jobListener, params IMatcher<JobKey>[] matchers) { AddJobListener(jobListener, new List<IMatcher<JobKey>>(matchers)); }
public bool RemoveListener(IJobListener listener) { if (listeners.Contains(listener)) { listeners.Remove(listener); return true; } else { return false; } }
private static void ConfigureJob <T>(ServiceConfigurator <T> configurator, Action <QuartzConfigurator> jobConfigurator) where T : class { var log = HostLogger.Get(typeof(ScheduleJobServiceConfiguratorExtensions)); var jobConfig = new QuartzConfigurator(); jobConfigurator(jobConfig); if (jobConfig.JobEnabled == null || jobConfig.JobEnabled() || jobConfig.Job == null || jobConfig.Triggers == null) { var jobDetail = jobConfig.Job(); var jobTriggers = jobConfig.Triggers.Select(triggerFactory => triggerFactory()).Where(trigger => trigger != null); configurator.BeforeStartingService(() => { log.Debug("[Topshelf.Quartz] Scheduler starting up..."); if (Scheduler == null) { Scheduler = GetScheduler(); } if (Scheduler != null) { if (jobDetail != null && jobTriggers.Any()) { var triggersForJob = new HashSet <ITrigger>(jobTriggers); Scheduler.ScheduleJob(jobDetail, triggersForJob, false); log.Info($"[Topshelf.Quartz] Scheduled Job: {jobDetail.Key}"); foreach (var trigger in triggersForJob) { log.Info($"[Topshelf.Quartz] Job Schedule: {trigger} - Next Fire Time (local): {(trigger.GetNextFireTimeUtc().HasValue ? trigger.GetNextFireTimeUtc().Value.ToLocalTime().ToString() : "none")}"); } if (!Scheduler.IsStarted) { Scheduler.Start(); log.Info("[Topshelf.Quartz] Scheduler started..."); } } foreach (Tuple <Func <IJobListener>, IMatcher <JobKey>[]> jobListenerTuple in jobConfig.JobListeners) { IJobListener jobListener = jobListenerTuple.Item1(); IMatcher <JobKey>[] keyEquals = jobListenerTuple.Item2; if (jobListener != null) { Scheduler.ListenerManager.AddJobListener(jobListener, keyEquals); } } } }); configurator.BeforeStoppingService(() => { log.Debug("[Topshelf.Quartz] Scheduler shutting down..."); Scheduler.Shutdown(true); log.Info("[Topshelf.Quartz] Scheduler shut down..."); }); } }
public JsonJobListener(IJobListener listener) { name = listener.Name; }
public JobListener(IJobListener listener, IMatcher <JobKey>[] matchers) { Listener = listener; Matchers = matchers; }
public void AddJobListener(IJobListener jobListener) { scheduler.AddJobListener(jobListener); }
/// <summary> /// Add the given <see cref="IJobListener" /> to the /// <see cref="IScheduler" />'s <i>internal</i> list. /// </summary> /// <param name="jobListener"></param> public void AddInternalJobListener(IJobListener jobListener) { if (jobListener.Name.IsNullOrWhiteSpace()) { throw new ArgumentException("JobListener name cannot be empty.", "jobListener"); } lock (internalJobListeners) { internalJobListeners[jobListener.Name] = jobListener; } }
public bool RemoveGlobalJobListener(IJobListener jobListener) { return scheduler.RemoveGlobalJobListener(jobListener); }
/// <summary> </summary> private async Task <IScheduler> Instantiate() { if (cfg == null) { Initialize(); } if (initException != null) { throw initException; } ISchedulerExporter? exporter = null; IJobStore js; IThreadPool tp; QuartzScheduler? qs = null; IDbConnectionManager?dbMgr = null; Type?instanceIdGeneratorType = null; NameValueCollection tProps; bool autoId = false; TimeSpan idleWaitTime = TimeSpan.Zero; TimeSpan dbFailureRetry = TimeSpan.FromSeconds(15); SchedulerRepository schedRep = SchedulerRepository.Instance; // Get Scheduler Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string schedName = cfg !.GetStringProperty(PropertySchedulerInstanceName, "QuartzScheduler") !; string threadName = cfg.GetStringProperty(PropertySchedulerThreadName, "{0}_QuartzSchedulerThread".FormatInvariant(schedName)) !; var schedInstId = cfg.GetStringProperty(PropertySchedulerInstanceId, DefaultInstanceId) !; if (schedInstId.Equals(AutoGenerateInstanceId)) { autoId = true; instanceIdGeneratorType = LoadType(cfg.GetStringProperty(PropertySchedulerInstanceIdGeneratorType)) ?? typeof(SimpleInstanceIdGenerator); } else if (schedInstId.Equals(SystemPropertyAsInstanceId)) { autoId = true; instanceIdGeneratorType = typeof(SystemPropertyInstanceIdGenerator); } Type?typeLoadHelperType = LoadType(cfg.GetStringProperty(PropertySchedulerTypeLoadHelperType)); Type?jobFactoryType = LoadType(cfg.GetStringProperty(PropertySchedulerJobFactoryType, null)); idleWaitTime = cfg.GetTimeSpanProperty(PropertySchedulerIdleWaitTime, idleWaitTime); if (idleWaitTime > TimeSpan.Zero && idleWaitTime < TimeSpan.FromMilliseconds(1000)) { throw new SchedulerException("quartz.scheduler.idleWaitTime of less than 1000ms is not legal."); } dbFailureRetry = cfg.GetTimeSpanProperty(PropertySchedulerDbFailureRetryInterval, dbFailureRetry); if (dbFailureRetry < TimeSpan.Zero) { throw new SchedulerException(PropertySchedulerDbFailureRetryInterval + " of less than 0 ms is not legal."); } bool makeSchedulerThreadDaemon = cfg.GetBooleanProperty(PropertySchedulerMakeSchedulerThreadDaemon); long batchTimeWindow = cfg.GetLongProperty(PropertySchedulerBatchTimeWindow, 0L); int maxBatchSize = cfg.GetIntProperty(PropertySchedulerMaxBatchSize, 1); bool interruptJobsOnShutdown = cfg.GetBooleanProperty(PropertySchedulerInterruptJobsOnShutdown, false); bool interruptJobsOnShutdownWithWait = cfg.GetBooleanProperty(PropertySchedulerInterruptJobsOnShutdownWithWait, false); NameValueCollection schedCtxtProps = cfg.GetPropertyGroup(PropertySchedulerContextPrefix, true); bool proxyScheduler = cfg.GetBooleanProperty(PropertySchedulerProxy, false); // Create type load helper ITypeLoadHelper loadHelper; try { loadHelper = InstantiateType <ITypeLoadHelper>(typeLoadHelperType ?? typeof(SimpleTypeLoadHelper)); } catch (Exception e) { throw new SchedulerConfigException("Unable to instantiate type load helper: {0}".FormatInvariant(e.Message), e); } loadHelper.Initialize(); // If Proxying to remote scheduler, short-circuit here... // ~~~~~~~~~~~~~~~~~~ if (proxyScheduler) { if (autoId) { schedInstId = DefaultInstanceId; } var proxyType = loadHelper.LoadType(cfg.GetStringProperty(PropertySchedulerProxyType)) ?? typeof(RemotingSchedulerProxyFactory); IRemotableSchedulerProxyFactory factory; try { factory = InstantiateType <IRemotableSchedulerProxyFactory>(proxyType); ObjectUtils.SetObjectProperties(factory, cfg.GetPropertyGroup(PropertySchedulerProxy, true)); } catch (Exception e) { initException = new SchedulerException("Remotable proxy factory '{0}' could not be instantiated.".FormatInvariant(proxyType), e); throw initException; } string uid = QuartzSchedulerResources.GetUniqueIdentifier(schedName, schedInstId); RemoteScheduler remoteScheduler = new RemoteScheduler(uid, factory); schedRep.Bind(remoteScheduler); return(remoteScheduler); } IJobFactory?jobFactory = null; if (jobFactoryType != null) { try { jobFactory = InstantiateType <IJobFactory>(jobFactoryType); } catch (Exception e) { throw new SchedulerConfigException("Unable to Instantiate JobFactory: {0}".FormatInvariant(e.Message), e); } tProps = cfg.GetPropertyGroup(PropertySchedulerJobFactoryPrefix, true); try { ObjectUtils.SetObjectProperties(jobFactory, tProps); } catch (Exception e) { initException = new SchedulerException("JobFactory of type '{0}' props could not be configured.".FormatInvariant(jobFactoryType), e); throw initException; } } IInstanceIdGenerator?instanceIdGenerator = null; if (instanceIdGeneratorType != null) { try { instanceIdGenerator = InstantiateType <IInstanceIdGenerator>(instanceIdGeneratorType); } catch (Exception e) { throw new SchedulerConfigException("Unable to Instantiate InstanceIdGenerator: {0}".FormatInvariant(e.Message), e); } tProps = cfg.GetPropertyGroup(PropertySchedulerInstanceIdGeneratorPrefix, true); try { ObjectUtils.SetObjectProperties(instanceIdGenerator, tProps); } catch (Exception e) { initException = new SchedulerException("InstanceIdGenerator of type '{0}' props could not be configured.".FormatInvariant(instanceIdGeneratorType), e); throw initException; } } // Get ThreadPool Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var threadPoolTypeString = cfg.GetStringProperty(PropertyThreadPoolType).NullSafeTrim(); if (threadPoolTypeString != null && threadPoolTypeString.StartsWith("Quartz.Simpl.SimpleThreadPool", StringComparison.OrdinalIgnoreCase)) { // default to use as synonym for now threadPoolTypeString = typeof(DefaultThreadPool).AssemblyQualifiedNameWithoutVersion(); } Type tpType = loadHelper.LoadType(threadPoolTypeString) ?? typeof(DefaultThreadPool); try { tp = InstantiateType <IThreadPool>(tpType); } catch (Exception e) { initException = new SchedulerException("ThreadPool type '{0}' could not be instantiated.".FormatInvariant(tpType), e); throw initException; } tProps = cfg.GetPropertyGroup(PropertyThreadPoolPrefix, true); try { ObjectUtils.SetObjectProperties(tp, tProps); } catch (Exception e) { initException = new SchedulerException("ThreadPool type '{0}' props could not be configured.".FormatInvariant(tpType), e); throw initException; } // Set up any DataSources // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var dsNames = cfg.GetPropertyGroups(PropertyDataSourcePrefix); foreach (string dataSourceName in dsNames) { string datasourceKey = "{0}.{1}".FormatInvariant(PropertyDataSourcePrefix, dataSourceName); NameValueCollection propertyGroup = cfg.GetPropertyGroup(datasourceKey, true); PropertiesParser pp = new PropertiesParser(propertyGroup); Type?cpType = loadHelper.LoadType(pp.GetStringProperty(PropertyDbProviderType, null)); // custom connectionProvider... if (cpType != null) { IDbProvider cp; try { cp = InstantiateType <IDbProvider>(cpType); } catch (Exception e) { initException = new SchedulerException("ConnectionProvider of type '{0}' could not be instantiated.".FormatInvariant(cpType), e); throw initException; } try { // remove the type name, so it isn't attempted to be set pp.UnderlyingProperties.Remove(PropertyDbProviderType); ObjectUtils.SetObjectProperties(cp, pp.UnderlyingProperties); cp.Initialize(); } catch (Exception e) { initException = new SchedulerException("ConnectionProvider type '{0}' props could not be configured.".FormatInvariant(cpType), e); throw initException; } dbMgr = DBConnectionManager.Instance; dbMgr.AddConnectionProvider(dataSourceName, cp); } else { string?dsProvider = pp.GetStringProperty(PropertyDataSourceProvider, null); string?dsConnectionString = pp.GetStringProperty(PropertyDataSourceConnectionString, null); string?dsConnectionStringName = pp.GetStringProperty(PropertyDataSourceConnectionStringName, null); if (dsConnectionString == null && !string.IsNullOrEmpty(dsConnectionStringName)) { ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings[dsConnectionStringName]; if (connectionStringSettings == null) { initException = new SchedulerException("Named connection string '{0}' not found for DataSource: {1}".FormatInvariant(dsConnectionStringName, dataSourceName)); throw initException; } dsConnectionString = connectionStringSettings.ConnectionString; } if (dsProvider == null) { initException = new SchedulerException("Provider not specified for DataSource: {0}".FormatInvariant(dataSourceName)); throw initException; } if (dsConnectionString == null) { initException = new SchedulerException("Connection string not specified for DataSource: {0}".FormatInvariant(dataSourceName)); throw initException; } try { DbProvider dbp = new DbProvider(dsProvider, dsConnectionString); dbp.Initialize(); dbMgr = DBConnectionManager.Instance; dbMgr.AddConnectionProvider(dataSourceName, dbp); } catch (Exception exception) { initException = new SchedulerException("Could not Initialize DataSource: {0}".FormatInvariant(dataSourceName), exception); throw initException; } } } // Get JobStore Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Type?jsType = loadHelper.LoadType(cfg.GetStringProperty(PropertyJobStoreType)); try { js = InstantiateType <IJobStore>(jsType ?? typeof(RAMJobStore)); } catch (Exception e) { initException = new SchedulerException("JobStore of type '{0}' could not be instantiated.".FormatInvariant(jsType), e); throw initException; } // Get object serializer properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IObjectSerializer?objectSerializer = null; string serializerTypeKey = "quartz.serializer.type"; string? objectSerializerType = cfg.GetStringProperty(serializerTypeKey); if (objectSerializerType != null) { // some aliases if (objectSerializerType.Equals("json", StringComparison.OrdinalIgnoreCase)) { objectSerializerType = "Quartz.Simpl.JsonObjectSerializer, Quartz.Serialization.Json"; } if (objectSerializerType.Equals("binary", StringComparison.OrdinalIgnoreCase)) { objectSerializerType = typeof(BinaryObjectSerializer).AssemblyQualifiedNameWithoutVersion(); } tProps = cfg.GetPropertyGroup(PropertyObjectSerializer, true); try { objectSerializer = InstantiateType <IObjectSerializer>(loadHelper.LoadType(objectSerializerType)); log.Info("Using object serializer: " + objectSerializerType); ObjectUtils.SetObjectProperties(objectSerializer, tProps); objectSerializer.Initialize(); } catch (Exception e) { initException = new SchedulerException("Object serializer type '" + objectSerializerType + "' could not be instantiated.", e); throw initException; } } else if (js.GetType() != typeof(RAMJobStore)) { // when we know for sure that job store does not need serialization we can be a bit more relaxed // otherwise it's an error to not define the serialization strategy initException = new SchedulerException($"You must define object serializer using configuration key '{serializerTypeKey}' when using other than RAMJobStore. " + "Out of the box supported values are 'json' and 'binary'. JSON doesn't suffer from versioning as much as binary serialization but you cannot use it if you already have binary serialized data."); throw initException; } SchedulerDetailsSetter.SetDetails(js, schedName, schedInstId); tProps = cfg.GetPropertyGroup(PropertyJobStorePrefix, true, new[] { PropertyJobStoreLockHandlerPrefix }); try { ObjectUtils.SetObjectProperties(js, tProps); } catch (Exception e) { initException = new SchedulerException("JobStore type '{0}' props could not be configured.".FormatInvariant(jsType), e); throw initException; } if (js is JobStoreSupport jobStoreSupport) { // Install custom lock handler (Semaphore) Type?lockHandlerType = loadHelper.LoadType(cfg.GetStringProperty(PropertyJobStoreLockHandlerType)); if (lockHandlerType != null) { try { ISemaphore lockHandler; var cWithDbProvider = lockHandlerType.GetConstructor(new[] { typeof(DbProvider) }); if (cWithDbProvider != null) { // takes db provider IDbProvider dbProvider = DBConnectionManager.Instance.GetDbProvider(jobStoreSupport.DataSource); lockHandler = (ISemaphore)cWithDbProvider.Invoke(new object[] { dbProvider }); } else { lockHandler = InstantiateType <ISemaphore>(lockHandlerType); } tProps = cfg.GetPropertyGroup(PropertyJobStoreLockHandlerPrefix, true); // If this lock handler requires the table prefix, add it to its properties. if (lockHandler is ITablePrefixAware) { tProps[PropertyTablePrefix] = jobStoreSupport.TablePrefix; tProps[PropertySchedulerName] = schedName; } try { ObjectUtils.SetObjectProperties(lockHandler, tProps); } catch (Exception e) { initException = new SchedulerException("JobStore LockHandler type '{0}' props could not be configured.".FormatInvariant(lockHandlerType), e); throw initException; } jobStoreSupport.LockHandler = lockHandler; Log.Info("Using custom data access locking (synchronization): " + lockHandlerType); } catch (Exception e) { initException = new SchedulerException("JobStore LockHandler type '{0}' could not be instantiated.".FormatInvariant(lockHandlerType), e); throw initException; } } } // Set up any SchedulerPlugins // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var pluginNames = cfg.GetPropertyGroups(PropertyPluginPrefix); ISchedulerPlugin[] plugins = new ISchedulerPlugin[pluginNames.Count]; for (int i = 0; i < pluginNames.Count; i++) { NameValueCollection pp = cfg.GetPropertyGroup("{0}.{1}".FormatInvariant(PropertyPluginPrefix, pluginNames[i]), true); string plugInType = pp[PropertyPluginType]; if (plugInType == null) { initException = new SchedulerException("SchedulerPlugin type not specified for plugin '{0}'".FormatInvariant(pluginNames[i])); throw initException; } ISchedulerPlugin plugin; try { plugin = ObjectUtils.InstantiateType <ISchedulerPlugin>(LoadType(plugInType)); } catch (Exception e) { initException = new SchedulerException("SchedulerPlugin of type '{0}' could not be instantiated.".FormatInvariant(plugInType), e); throw initException; } try { ObjectUtils.SetObjectProperties(plugin, pp); } catch (Exception e) { initException = new SchedulerException("JobStore SchedulerPlugin '{0}' props could not be configured.".FormatInvariant(plugInType), e); throw initException; } plugins[i] = plugin; } // Set up any JobListeners // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var jobListenerNames = cfg.GetPropertyGroups(PropertyJobListenerPrefix); IJobListener[] jobListeners = new IJobListener[jobListenerNames.Count]; for (int i = 0; i < jobListenerNames.Count; i++) { NameValueCollection lp = cfg.GetPropertyGroup("{0}.{1}".FormatInvariant(PropertyJobListenerPrefix, jobListenerNames[i]), true); string listenerType = lp[PropertyListenerType]; if (listenerType == null) { initException = new SchedulerException("JobListener type not specified for listener '{0}'".FormatInvariant(jobListenerNames[i])); throw initException; } IJobListener listener; try { listener = ObjectUtils.InstantiateType <IJobListener>(loadHelper.LoadType(listenerType)); } catch (Exception e) { initException = new SchedulerException("JobListener of type '{0}' could not be instantiated.".FormatInvariant(listenerType), e); throw initException; } try { var nameProperty = listener.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance); if (nameProperty != null && nameProperty.CanWrite) { nameProperty.GetSetMethod() !.Invoke(listener, new object[] { jobListenerNames[i] }); } ObjectUtils.SetObjectProperties(listener, lp); } catch (Exception e) { initException = new SchedulerException("JobListener '{0}' props could not be configured.".FormatInvariant(listenerType), e); throw initException; } jobListeners[i] = listener; } // Set up any TriggerListeners // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var triggerListenerNames = cfg.GetPropertyGroups(PropertyTriggerListenerPrefix); ITriggerListener[] triggerListeners = new ITriggerListener[triggerListenerNames.Count]; for (int i = 0; i < triggerListenerNames.Count; i++) { NameValueCollection lp = cfg.GetPropertyGroup("{0}.{1}".FormatInvariant(PropertyTriggerListenerPrefix, triggerListenerNames[i]), true); string listenerType = lp[PropertyListenerType]; if (listenerType == null) { initException = new SchedulerException("TriggerListener type not specified for listener '{0}'".FormatInvariant(triggerListenerNames[i])); throw initException; } ITriggerListener listener; try { listener = ObjectUtils.InstantiateType <ITriggerListener>(loadHelper.LoadType(listenerType)); } catch (Exception e) { initException = new SchedulerException("TriggerListener of type '{0}' could not be instantiated.".FormatInvariant(listenerType), e); throw initException; } try { var nameProperty = listener.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance); if (nameProperty != null && nameProperty.CanWrite) { nameProperty.GetSetMethod() !.Invoke(listener, new object[] { triggerListenerNames[i] }); } ObjectUtils.SetObjectProperties(listener, lp); } catch (Exception e) { initException = new SchedulerException("TriggerListener '{0}' props could not be configured.".FormatInvariant(listenerType), e); throw initException; } triggerListeners[i] = listener; } // Get exporter // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var exporterType = cfg.GetStringProperty(PropertySchedulerExporterType, null); #if !REMOTING if (exporterType != null && exporterType.StartsWith("Quartz.Simpl.RemotingSchedulerExporter")) { log.Warn("RemotingSchedulerExporter configuration was ignored as Remoting is not supported"); exporterType = null; } #endif if (exporterType != null) { try { exporter = InstantiateType <ISchedulerExporter>(loadHelper.LoadType(exporterType)); } catch (Exception e) { initException = new SchedulerException("Scheduler exporter of type '{0}' could not be instantiated.".FormatInvariant(exporterType), e); throw initException; } tProps = cfg.GetPropertyGroup(PropertySchedulerExporterPrefix, true); try { ObjectUtils.SetObjectProperties(exporter, tProps); } catch (Exception e) { initException = new SchedulerException("Scheduler exporter type '{0}' props could not be configured.".FormatInvariant(exporterType), e); throw initException; } } bool tpInited = false; bool qsInited = false; // Fire everything up // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ try { IJobRunShellFactory jrsf = new StdJobRunShellFactory(); if (autoId) { try { schedInstId = DefaultInstanceId; if (js.Clustered) { schedInstId = (await instanceIdGenerator !.GenerateInstanceId().ConfigureAwait(false)) !; } } catch (Exception e) { Log.ErrorException("Couldn't generate instance Id!", e); throw new InvalidOperationException("Cannot run without an instance id."); } } if (js is JobStoreSupport js2) { js2.DbRetryInterval = dbFailureRetry; js2.ObjectSerializer = objectSerializer; } QuartzSchedulerResources rsrcs = new QuartzSchedulerResources(); rsrcs.Name = schedName; rsrcs.ThreadName = threadName; rsrcs.InstanceId = schedInstId !; rsrcs.JobRunShellFactory = jrsf; rsrcs.MakeSchedulerThreadDaemon = makeSchedulerThreadDaemon; rsrcs.BatchTimeWindow = TimeSpan.FromMilliseconds(batchTimeWindow); rsrcs.MaxBatchSize = maxBatchSize; rsrcs.InterruptJobsOnShutdown = interruptJobsOnShutdown; rsrcs.InterruptJobsOnShutdownWithWait = interruptJobsOnShutdownWithWait; rsrcs.SchedulerExporter = exporter; SchedulerDetailsSetter.SetDetails(tp, schedName, schedInstId !); rsrcs.ThreadPool = tp; tp.Initialize(); tpInited = true; rsrcs.JobStore = js; // add plugins foreach (ISchedulerPlugin plugin in plugins) { rsrcs.AddSchedulerPlugin(plugin); } qs = new QuartzScheduler(rsrcs, idleWaitTime); qsInited = true; // Create Scheduler ref... IScheduler sched = Instantiate(rsrcs, qs); // set job factory if specified if (jobFactory != null) { qs.JobFactory = jobFactory; } // Initialize plugins now that we have a Scheduler instance. for (int i = 0; i < plugins.Length; i++) { await plugins[i].Initialize(pluginNames[i], sched).ConfigureAwait(false); } // add listeners foreach (IJobListener listener in jobListeners) { qs.ListenerManager.AddJobListener(listener, EverythingMatcher <JobKey> .AllJobs()); } foreach (ITriggerListener listener in triggerListeners) { qs.ListenerManager.AddTriggerListener(listener, EverythingMatcher <TriggerKey> .AllTriggers()); } // set scheduler context data... foreach (var key in schedCtxtProps) { string val = schedCtxtProps.Get((string)key !); sched.Context.Put((string)key !, val); } // fire up job store, and runshell factory js.InstanceId = schedInstId !; js.InstanceName = schedName; js.ThreadPoolSize = tp.PoolSize; await js.Initialize(loadHelper, qs.SchedulerSignaler).ConfigureAwait(false); jrsf.Initialize(sched); qs.Initialize(); Log.Info("Quartz scheduler '{0}' initialized".FormatInvariant(sched.SchedulerName)); Log.Info("Quartz scheduler version: {0}".FormatInvariant(qs.Version)); // prevents the repository from being garbage collected qs.AddNoGCObject(schedRep); // prevents the db manager from being garbage collected if (dbMgr != null) { qs.AddNoGCObject(dbMgr); } schedRep.Bind(sched); return(sched); } catch (SchedulerException) { await ShutdownFromInstantiateException(tp, qs, tpInited, qsInited).ConfigureAwait(false); throw; } catch { await ShutdownFromInstantiateException(tp, qs, tpInited, qsInited).ConfigureAwait(false); throw; } }
public void AddJobListener(IJobListener jobListener, params IMatcher <JobKey>[] matchers) { AddJobListener(jobListener, new List <IMatcher <JobKey> >(matchers)); }
public bool RemoveListener(IJobListener listener) { return listeners.Remove(listener); }
/// <summary> </summary> private IScheduler Instantiate() { if (cfg == null) { Initialize(); } if (initException != null) { throw initException; } ISchedulerExporter exporter = null; IJobStore js; IThreadPool tp; QuartzScheduler qs = null; DBConnectionManager dbMgr = null; Type instanceIdGeneratorType = null; NameValueCollection tProps; bool autoId = false; TimeSpan idleWaitTime = TimeSpan.Zero; TimeSpan dbFailureRetry = TimeSpan.FromSeconds(15); IThreadExecutor threadExecutor; SchedulerRepository schedRep = SchedulerRepository.Instance; // Get Scheduler Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string schedName = cfg.GetStringProperty(PropertySchedulerInstanceName, "QuartzScheduler"); string threadName = cfg.GetStringProperty(PropertySchedulerThreadName, "{0}_QuartzSchedulerThread".FormatInvariant(schedName)); string schedInstId = cfg.GetStringProperty(PropertySchedulerInstanceId, DefaultInstanceId); if (schedInstId.Equals(AutoGenerateInstanceId)) { autoId = true; instanceIdGeneratorType = LoadType(cfg.GetStringProperty(PropertySchedulerInstanceIdGeneratorType)) ?? typeof(SimpleInstanceIdGenerator); } else if (schedInstId.Equals(SystemPropertyAsInstanceId)) { autoId = true; instanceIdGeneratorType = typeof(SystemPropertyInstanceIdGenerator); } Type typeLoadHelperType = LoadType(cfg.GetStringProperty(PropertySchedulerTypeLoadHelperType)); Type jobFactoryType = LoadType(cfg.GetStringProperty(PropertySchedulerJobFactoryType, null)); idleWaitTime = cfg.GetTimeSpanProperty(PropertySchedulerIdleWaitTime, idleWaitTime); if (idleWaitTime > TimeSpan.Zero && idleWaitTime < TimeSpan.FromMilliseconds(1000)) { throw new SchedulerException("quartz.scheduler.idleWaitTime of less than 1000ms is not legal."); } dbFailureRetry = cfg.GetTimeSpanProperty(PropertySchedulerDbFailureRetryInterval, dbFailureRetry); if (dbFailureRetry < TimeSpan.Zero) { throw new SchedulerException(PropertySchedulerDbFailureRetryInterval + " of less than 0 ms is not legal."); } bool makeSchedulerThreadDaemon = cfg.GetBooleanProperty(PropertySchedulerMakeSchedulerThreadDaemon); long batchTimeWindow = cfg.GetLongProperty(PropertySchedulerBatchTimeWindow, 0L); int maxBatchSize = cfg.GetIntProperty(PropertySchedulerMaxBatchSize, 1); bool interruptJobsOnShutdown = cfg.GetBooleanProperty(PropertySchedulerInterruptJobsOnShutdown, false); bool interruptJobsOnShutdownWithWait = cfg.GetBooleanProperty(PropertySchedulerInterruptJobsOnShutdownWithWait, false); NameValueCollection schedCtxtProps = cfg.GetPropertyGroup(PropertySchedulerContextPrefix, true); bool proxyScheduler = cfg.GetBooleanProperty(PropertySchedulerProxy, false); // Create type load helper ITypeLoadHelper loadHelper; try { loadHelper = ObjectUtils.InstantiateType<ITypeLoadHelper>(typeLoadHelperType ?? typeof(SimpleTypeLoadHelper)); } catch (Exception e) { throw new SchedulerConfigException("Unable to instantiate type load helper: {0}".FormatInvariant(e.Message), e); } loadHelper.Initialize(); // If Proxying to remote scheduler, short-circuit here... // ~~~~~~~~~~~~~~~~~~ if (proxyScheduler) { if (autoId) { schedInstId = DefaultInstanceId; } Type proxyType = loadHelper.LoadType(cfg.GetStringProperty(PropertySchedulerProxyType)) ?? typeof(RemotingSchedulerProxyFactory); IRemotableSchedulerProxyFactory factory; try { factory = ObjectUtils.InstantiateType<IRemotableSchedulerProxyFactory>(proxyType); ObjectUtils.SetObjectProperties(factory, cfg.GetPropertyGroup(PropertySchedulerProxy, true)); } catch (Exception e) { initException = new SchedulerException("Remotable proxy factory '{0}' could not be instantiated.".FormatInvariant(proxyType), e); throw initException; } string uid = QuartzSchedulerResources.GetUniqueIdentifier(schedName, schedInstId); RemoteScheduler remoteScheduler = new RemoteScheduler(uid, factory); schedRep.Bind(remoteScheduler); return remoteScheduler; } IJobFactory jobFactory = null; if (jobFactoryType != null) { try { jobFactory = ObjectUtils.InstantiateType<IJobFactory>(jobFactoryType); } catch (Exception e) { throw new SchedulerConfigException("Unable to Instantiate JobFactory: {0}".FormatInvariant(e.Message), e); } tProps = cfg.GetPropertyGroup(PropertySchedulerJobFactoryPrefix, true); try { ObjectUtils.SetObjectProperties(jobFactory, tProps); } catch (Exception e) { initException = new SchedulerException("JobFactory of type '{0}' props could not be configured.".FormatInvariant(jobFactoryType), e); throw initException; } } IInstanceIdGenerator instanceIdGenerator = null; if (instanceIdGeneratorType != null) { try { instanceIdGenerator = ObjectUtils.InstantiateType<IInstanceIdGenerator>(instanceIdGeneratorType); } catch (Exception e) { throw new SchedulerConfigException("Unable to Instantiate InstanceIdGenerator: {0}".FormatInvariant(e.Message), e); } tProps = cfg.GetPropertyGroup(PropertySchedulerInstanceIdGeneratorPrefix, true); try { ObjectUtils.SetObjectProperties(instanceIdGenerator, tProps); } catch (Exception e) { initException = new SchedulerException("InstanceIdGenerator of type '{0}' props could not be configured.".FormatInvariant(instanceIdGeneratorType), e); throw initException; } } // Get ThreadPool Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Type tpType = loadHelper.LoadType(cfg.GetStringProperty(PropertyThreadPoolType)) ?? typeof(SimpleThreadPool); try { tp = ObjectUtils.InstantiateType<IThreadPool>(tpType); } catch (Exception e) { initException = new SchedulerException("ThreadPool type '{0}' could not be instantiated.".FormatInvariant(tpType), e); throw initException; } tProps = cfg.GetPropertyGroup(PropertyThreadPoolPrefix, true); try { ObjectUtils.SetObjectProperties(tp, tProps); } catch (Exception e) { initException = new SchedulerException("ThreadPool type '{0}' props could not be configured.".FormatInvariant(tpType), e); throw initException; } // Set up any DataSources // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] dsNames = cfg.GetPropertyGroups(PropertyDataSourcePrefix); for (int i = 0; i < dsNames.Length; i++) { string datasourceKey = "{0}.{1}".FormatInvariant( PropertyDataSourcePrefix, dsNames[i]); NameValueCollection propertyGroup = cfg.GetPropertyGroup(datasourceKey, true); PropertiesParser pp = new PropertiesParser(propertyGroup); Type cpType = loadHelper.LoadType(pp.GetStringProperty(PropertyDbProviderType, null)); // custom connectionProvider... if (cpType != null) { IDbProvider cp; try { cp = ObjectUtils.InstantiateType<IDbProvider>(cpType); } catch (Exception e) { initException = new SchedulerException("ConnectionProvider of type '{0}' could not be instantiated.".FormatInvariant(cpType), e); throw initException; } try { // remove the type name, so it isn't attempted to be set pp.UnderlyingProperties.Remove(PropertyDbProviderType); ObjectUtils.SetObjectProperties(cp, pp.UnderlyingProperties); cp.Initialize(); } catch (Exception e) { initException = new SchedulerException("ConnectionProvider type '{0}' props could not be configured.".FormatInvariant(cpType), e); throw initException; } dbMgr = DBConnectionManager.Instance; dbMgr.AddConnectionProvider(dsNames[i], cp); } else { string dsProvider = pp.GetStringProperty(PropertyDataSourceProvider, null); string dsConnectionString = pp.GetStringProperty(PropertyDataSourceConnectionString, null); string dsConnectionStringName = pp.GetStringProperty(PropertyDataSourceConnectionStringName, null); if (dsConnectionString == null && !String.IsNullOrEmpty(dsConnectionStringName)) { ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings[dsConnectionStringName]; if (connectionStringSettings == null) { initException = new SchedulerException("Named connection string '{0}' not found for DataSource: {1}".FormatInvariant(dsConnectionStringName, dsNames[i])); throw initException; } dsConnectionString = connectionStringSettings.ConnectionString; } if (dsProvider == null) { initException = new SchedulerException("Provider not specified for DataSource: {0}".FormatInvariant(dsNames[i])); throw initException; } if (dsConnectionString == null) { initException = new SchedulerException("Connection string not specified for DataSource: {0}".FormatInvariant(dsNames[i])); throw initException; } try { DbProvider dbp = new DbProvider(dsProvider, dsConnectionString); dbp.Initialize(); dbMgr = DBConnectionManager.Instance; dbMgr.AddConnectionProvider(dsNames[i], dbp); } catch (Exception exception) { initException = new SchedulerException("Could not Initialize DataSource: {0}".FormatInvariant(dsNames[i]), exception); throw initException; } } } // Get object serializer properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IObjectSerializer objectSerializer; string objectSerializerType = cfg.GetStringProperty("quartz.serializer.type"); if (objectSerializerType != null) { tProps = cfg.GetPropertyGroup(PropertyObjectSerializer, true); try { objectSerializer = ObjectUtils.InstantiateType<IObjectSerializer>(loadHelper.LoadType(objectSerializerType)); log.Info("Using custom implementation for object serializer: " + objectSerializerType); ObjectUtils.SetObjectProperties(objectSerializer, tProps); } catch (Exception e) { initException = new SchedulerException("Object serializer type '" + objectSerializerType + "' could not be instantiated.", e); throw initException; } } else { log.Info("Using default implementation for object serializer"); objectSerializer = new DefaultObjectSerializer(); } // Get JobStore Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Type jsType = loadHelper.LoadType(cfg.GetStringProperty(PropertyJobStoreType)); try { js = ObjectUtils.InstantiateType<IJobStore>(jsType ?? typeof(RAMJobStore)); } catch (Exception e) { initException = new SchedulerException("JobStore of type '{0}' could not be instantiated.".FormatInvariant(jsType), e); throw initException; } SchedulerDetailsSetter.SetDetails(js, schedName, schedInstId); tProps = cfg.GetPropertyGroup(PropertyJobStorePrefix, true, new string[] {PropertyJobStoreLockHandlerPrefix}); try { ObjectUtils.SetObjectProperties(js, tProps); } catch (Exception e) { initException = new SchedulerException("JobStore type '{0}' props could not be configured.".FormatInvariant(jsType), e); throw initException; } if (js is JobStoreSupport) { // Install custom lock handler (Semaphore) Type lockHandlerType = loadHelper.LoadType(cfg.GetStringProperty(PropertyJobStoreLockHandlerType)); if (lockHandlerType != null) { try { ISemaphore lockHandler; ConstructorInfo cWithDbProvider = lockHandlerType.GetConstructor(new Type[] {typeof (DbProvider)}); if (cWithDbProvider != null) { // takes db provider IDbProvider dbProvider = DBConnectionManager.Instance.GetDbProvider(((JobStoreSupport) js).DataSource); lockHandler = (ISemaphore) cWithDbProvider.Invoke(new object[] { dbProvider }); } else { lockHandler = ObjectUtils.InstantiateType<ISemaphore>(lockHandlerType); } tProps = cfg.GetPropertyGroup(PropertyJobStoreLockHandlerPrefix, true); // If this lock handler requires the table prefix, add it to its properties. if (lockHandler is ITablePrefixAware) { tProps[PropertyTablePrefix] = ((JobStoreSupport) js).TablePrefix; tProps[PropertySchedulerName] = schedName; } try { ObjectUtils.SetObjectProperties(lockHandler, tProps); } catch (Exception e) { initException = new SchedulerException("JobStore LockHandler type '{0}' props could not be configured.".FormatInvariant(lockHandlerType), e); throw initException; } ((JobStoreSupport) js).LockHandler = lockHandler; Log.Info("Using custom data access locking (synchronization): " + lockHandlerType); } catch (Exception e) { initException = new SchedulerException("JobStore LockHandler type '{0}' could not be instantiated.".FormatInvariant(lockHandlerType), e); throw initException; } } } // Set up any SchedulerPlugins // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] pluginNames = cfg.GetPropertyGroups(PropertyPluginPrefix); ISchedulerPlugin[] plugins = new ISchedulerPlugin[pluginNames.Length]; for (int i = 0; i < pluginNames.Length; i++) { NameValueCollection pp = cfg.GetPropertyGroup("{0}.{1}".FormatInvariant(PropertyPluginPrefix, pluginNames[i]), true); string plugInType = pp[PropertyPluginType] ?? null; if (plugInType == null) { initException = new SchedulerException("SchedulerPlugin type not specified for plugin '{0}'".FormatInvariant(pluginNames[i])); throw initException; } ISchedulerPlugin plugin; try { plugin = ObjectUtils.InstantiateType<ISchedulerPlugin>(LoadType(plugInType)); } catch (Exception e) { initException = new SchedulerException("SchedulerPlugin of type '{0}' could not be instantiated.".FormatInvariant(plugInType), e); throw initException; } try { ObjectUtils.SetObjectProperties(plugin, pp); } catch (Exception e) { initException = new SchedulerException("JobStore SchedulerPlugin '{0}' props could not be configured.".FormatInvariant(plugInType), e); throw initException; } plugins[i] = plugin; } // Set up any JobListeners // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] jobListenerNames = cfg.GetPropertyGroups(PropertyJobListenerPrefix); IJobListener[] jobListeners = new IJobListener[jobListenerNames.Length]; for (int i = 0; i < jobListenerNames.Length; i++) { NameValueCollection lp = cfg.GetPropertyGroup("{0}.{1}".FormatInvariant(PropertyJobListenerPrefix, jobListenerNames[i]), true); string listenerType = lp[PropertyListenerType]; if (listenerType == null) { initException = new SchedulerException("JobListener type not specified for listener '{0}'".FormatInvariant(jobListenerNames[i])); throw initException; } IJobListener listener; try { listener = ObjectUtils.InstantiateType<IJobListener>(loadHelper.LoadType(listenerType)); } catch (Exception e) { initException = new SchedulerException("JobListener of type '{0}' could not be instantiated.".FormatInvariant(listenerType), e); throw initException; } try { PropertyInfo nameProperty = listener.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance); if (nameProperty != null && nameProperty.CanWrite) { nameProperty.GetSetMethod().Invoke(listener, new object[] {jobListenerNames[i]}); } ObjectUtils.SetObjectProperties(listener, lp); } catch (Exception e) { initException = new SchedulerException("JobListener '{0}' props could not be configured.".FormatInvariant(listenerType), e); throw initException; } jobListeners[i] = listener; } // Set up any TriggerListeners // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] triggerListenerNames = cfg.GetPropertyGroups(PropertyTriggerListenerPrefix); ITriggerListener[] triggerListeners = new ITriggerListener[triggerListenerNames.Length]; for (int i = 0; i < triggerListenerNames.Length; i++) { NameValueCollection lp = cfg.GetPropertyGroup("{0}.{1}".FormatInvariant(PropertyTriggerListenerPrefix, triggerListenerNames[i]), true); string listenerType = lp[PropertyListenerType]; if (listenerType == null) { initException = new SchedulerException("TriggerListener type not specified for listener '{0}'".FormatInvariant(triggerListenerNames[i])); throw initException; } ITriggerListener listener; try { listener = ObjectUtils.InstantiateType<ITriggerListener>(loadHelper.LoadType(listenerType)); } catch (Exception e) { initException = new SchedulerException("TriggerListener of type '{0}' could not be instantiated.".FormatInvariant(listenerType), e); throw initException; } try { PropertyInfo nameProperty = listener.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance); if (nameProperty != null && nameProperty.CanWrite) { nameProperty.GetSetMethod().Invoke(listener, new object[] {triggerListenerNames[i]}); } ObjectUtils.SetObjectProperties(listener, lp); } catch (Exception e) { initException = new SchedulerException("TriggerListener '{0}' props could not be configured.".FormatInvariant(listenerType), e); throw initException; } triggerListeners[i] = listener; } // Get exporter // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string exporterType = cfg.GetStringProperty(PropertySchedulerExporterType, null); if (exporterType != null) { try { exporter = ObjectUtils.InstantiateType<ISchedulerExporter>(loadHelper.LoadType(exporterType)); } catch (Exception e) { initException = new SchedulerException("Scheduler exporter of type '{0}' could not be instantiated.".FormatInvariant(exporterType), e); throw initException; } tProps = cfg.GetPropertyGroup(PropertySchedulerExporterPrefix, true); try { ObjectUtils.SetObjectProperties(exporter, tProps); } catch (Exception e) { initException = new SchedulerException("Scheduler exporter type '{0}' props could not be configured.".FormatInvariant(exporterType), e); throw initException; } } bool tpInited = false; bool qsInited = false; // Get ThreadExecutor Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string threadExecutorClass = cfg.GetStringProperty(PropertyThreadExecutorType); if (threadExecutorClass != null) { tProps = cfg.GetPropertyGroup(PropertyThreadExecutor, true); try { threadExecutor = ObjectUtils.InstantiateType<IThreadExecutor>(loadHelper.LoadType(threadExecutorClass)); log.Info("Using custom implementation for ThreadExecutor: " + threadExecutorClass); ObjectUtils.SetObjectProperties(threadExecutor, tProps); } catch (Exception e) { initException = new SchedulerException( "ThreadExecutor class '" + threadExecutorClass + "' could not be instantiated.", e); throw initException; } } else { log.Info("Using default implementation for ThreadExecutor"); threadExecutor = new DefaultThreadExecutor(); } // Fire everything up // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ try { IJobRunShellFactory jrsf = new StdJobRunShellFactory(); if (autoId) { try { schedInstId = DefaultInstanceId; if (js.Clustered) { schedInstId = instanceIdGenerator.GenerateInstanceId(); } } catch (Exception e) { Log.Error("Couldn't generate instance Id!", e); throw new SystemException("Cannot run without an instance id."); } } if (js is JobStoreSupport) { JobStoreSupport jjs = (JobStoreSupport) js; jjs.DbRetryInterval = dbFailureRetry; jjs.ThreadExecutor = threadExecutor; // object serializer jjs.ObjectSerializer = objectSerializer; } QuartzSchedulerResources rsrcs = new QuartzSchedulerResources(); rsrcs.Name = schedName; rsrcs.ThreadName = threadName; rsrcs.InstanceId = schedInstId; rsrcs.JobRunShellFactory = jrsf; rsrcs.MakeSchedulerThreadDaemon = makeSchedulerThreadDaemon; rsrcs.BatchTimeWindow = TimeSpan.FromMilliseconds(batchTimeWindow); rsrcs.MaxBatchSize = maxBatchSize; rsrcs.InterruptJobsOnShutdown = interruptJobsOnShutdown; rsrcs.InterruptJobsOnShutdownWithWait = interruptJobsOnShutdownWithWait; rsrcs.SchedulerExporter = exporter; SchedulerDetailsSetter.SetDetails(tp, schedName, schedInstId); rsrcs.ThreadExecutor = threadExecutor; threadExecutor.Initialize(); rsrcs.ThreadPool = tp; if (tp is SimpleThreadPool) { ((SimpleThreadPool) tp).ThreadNamePrefix = schedName + "_Worker"; } tp.Initialize(); tpInited = true; rsrcs.JobStore = js; // add plugins for (int i = 0; i < plugins.Length; i++) { rsrcs.AddSchedulerPlugin(plugins[i]); } qs = new QuartzScheduler(rsrcs, idleWaitTime, dbFailureRetry); qsInited = true; // Create Scheduler ref... IScheduler sched = Instantiate(rsrcs, qs); // set job factory if specified if (jobFactory != null) { qs.JobFactory = jobFactory; } // Initialize plugins now that we have a Scheduler instance. for (int i = 0; i < plugins.Length; i++) { plugins[i].Initialize(pluginNames[i], sched); } // add listeners for (int i = 0; i < jobListeners.Length; i++) { qs.ListenerManager.AddJobListener(jobListeners[i], EverythingMatcher<JobKey>.AllJobs()); } for (int i = 0; i < triggerListeners.Length; i++) { qs.ListenerManager.AddTriggerListener(triggerListeners[i], EverythingMatcher<TriggerKey>.AllTriggers()); } // set scheduler context data... foreach (string key in schedCtxtProps) { string val = schedCtxtProps.Get(key); sched.Context.Put(key, val); } // fire up job store, and runshell factory js.InstanceId = schedInstId; js.InstanceName = schedName; js.ThreadPoolSize = tp.PoolSize; js.Initialize(loadHelper, qs.SchedulerSignaler); jrsf.Initialize(sched); qs.Initialize(); Log.Info("Quartz scheduler '{0}' initialized".FormatInvariant(sched.SchedulerName)); Log.Info("Quartz scheduler version: {0}".FormatInvariant(qs.Version)); // prevents the repository from being garbage collected qs.AddNoGCObject(schedRep); // prevents the db manager from being garbage collected if (dbMgr != null) { qs.AddNoGCObject(dbMgr); } schedRep.Bind(sched); return sched; } catch (SchedulerException) { if (qsInited) { qs.Shutdown(false); } else if (tpInited) { tp.Shutdown(false); } throw; } catch { if (qsInited) { qs.Shutdown(false); } else if (tpInited) { tp.Shutdown(false); } throw; } }
public void AddListener(IJobListener listener) { listeners.Add(listener); }
/// <summary> /// Add the given <see cref="IJobListener" /> to the /// <see cref="IScheduler" />'s list, of registered <see cref="IJobListener" />s. /// </summary> public virtual void AddJobListener(IJobListener jobListener) { if (jobListener.Name == null || jobListener.Name.Length == 0) { throw new ArgumentException("JobListener name cannot be empty."); } lock (jobListener) { jobListeners.Add(jobListener.Name, jobListener); } }
/// <summary> /// Remove the given <see cref="IJobListener" /> from the /// <see cref="IScheduler" />'s list of <i>global</i> listeners. /// </summary> /// <returns> /// true if the identifed listener was found in the list, and removed. /// </returns> public virtual bool RemoveGlobalJobListener(IJobListener jobListener) { return RemoveGlobalJobListener((jobListener == null) ? null : jobListener.Name); }
public void AddListener(IJobListener listener) { listeners.Add(listener); }
public virtual void AddListenerToSchedule(IJobListener listener) { listenersToSchedule.Add(listener); }
public QuartzJobListenerConfig(IJobListener listener, params IMatcher<JobKey>[] matchers) { Listener = listener; Matchers = matchers; }
/// <summary> /// Calls the equivalent method on the 'proxied' <see cref="QuartzScheduler" />, /// passing the <see cref="SchedulingContext" /> associated with this /// instance. /// </summary> public virtual bool RemoveGlobalJobListener(IJobListener jobListener) { throw new SchedulerException("Operation not supported for remote schedulers.", SchedulerException.ErrorUnsupportedFunctionInThisConfiguration); }
private bool MatchJobListener(IJobListener listener, JobKey key) { IList<IMatcher<JobKey>> matchers = ListenerManager.GetJobListenerMatchers(listener.Name); if (matchers == null) { return true; } foreach (IMatcher<JobKey> matcher in matchers) { if (matcher.IsMatch(key)) { return true; } } return false; }
/// <summary> </summary> private IScheduler Instantiate() { if (cfg == null) { Initialize(); } if (initException != null) { throw initException; } ISchedulerExporter exporter = null; IJobStore js; IThreadPool tp; QuartzScheduler qs; SchedulingContext schedCtxt; DBConnectionManager dbMgr = null; string instanceIdGeneratorType = null; NameValueCollection tProps; bool autoId = false; TimeSpan idleWaitTime = TimeSpan.Zero; TimeSpan dbFailureRetry = TimeSpan.Zero; string typeLoadHelperType; string jobFactoryType; SchedulerRepository schedRep = SchedulerRepository.Instance; // Get Scheduler Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string schedName = cfg.GetStringProperty(PropertySchedulerInstanceName, "QuartzScheduler"); string threadName = cfg.GetStringProperty(PropertySchedulerThreadName, string.Format(CultureInfo.InvariantCulture, "{0}_QuartzSchedulerThread", schedName)); string schedInstId = cfg.GetStringProperty(PropertySchedulerInstanceId, DefaultInstanceId); if (schedInstId.Equals(AutoGenerateInstanceId)) { autoId = true; instanceIdGeneratorType = cfg.GetStringProperty(PropertySchedulerInstanceIdGeneratorType, "Quartz.Simpl.SimpleInstanceIdGenerator, Quartz"); } typeLoadHelperType = cfg.GetStringProperty(PropertySchedulerTypeLoadHelperType, "Quartz.Simpl.CascadingClassLoadHelper, Quartz"); jobFactoryType = cfg.GetStringProperty(PropertySchedulerJobFactoryType, null); idleWaitTime = cfg.GetTimeSpanProperty(PropertySchedulerIdleWaitTime, idleWaitTime); dbFailureRetry = cfg.GetTimeSpanProperty(PropertySchedulerDbFailureRetryInterval, dbFailureRetry); bool makeSchedulerThreadDaemon = cfg.GetBooleanProperty(PropertySchedulerMakeSchedulerThreadDaemon); NameValueCollection schedCtxtProps = cfg.GetPropertyGroup(PropertySchedulerContextPrefix, true); bool proxyScheduler = cfg.GetBooleanProperty(PropertySchedulerProxy, false); // If Proxying to remote scheduler, short-circuit here... // ~~~~~~~~~~~~~~~~~~ if (proxyScheduler) { if (autoId) { schedInstId = DefaultInstanceId; } schedCtxt = new SchedulingContext(); schedCtxt.InstanceId = schedInstId; string uid = QuartzSchedulerResources.GetUniqueIdentifier(schedName, schedInstId); RemoteScheduler remoteScheduler = new RemoteScheduler(schedCtxt, uid); string remoteSchedulerAddress = cfg.GetStringProperty(PropertySchedulerProxyAddress); remoteScheduler.RemoteSchedulerAddress = remoteSchedulerAddress; schedRep.Bind(remoteScheduler); return remoteScheduler; } // Create type load helper ITypeLoadHelper loadHelper; try { loadHelper = (ITypeLoadHelper)ObjectUtils.InstantiateType(LoadType(typeLoadHelperType)); } catch (Exception e) { throw new SchedulerConfigException( string.Format(CultureInfo.InvariantCulture, "Unable to instantiate type load helper: {0}", e.Message), e); } loadHelper.Initialize(); IJobFactory jobFactory = null; if (jobFactoryType != null) { try { jobFactory = (IJobFactory) ObjectUtils.InstantiateType(loadHelper.LoadType(jobFactoryType)); } catch (Exception e) { throw new SchedulerConfigException( string.Format(CultureInfo.InvariantCulture, "Unable to Instantiate JobFactory: {0}", e.Message), e); } tProps = cfg.GetPropertyGroup(PropertySchedulerJobFactoryPrefix, true); try { ObjectUtils.SetObjectProperties(jobFactory, tProps); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "JobFactory of type '{0}' props could not be configured.", jobFactoryType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } } IInstanceIdGenerator instanceIdGenerator = null; if (instanceIdGeneratorType != null) { try { instanceIdGenerator = (IInstanceIdGenerator) ObjectUtils.InstantiateType(loadHelper.LoadType(instanceIdGeneratorType)); } catch (Exception e) { throw new SchedulerConfigException( string.Format(CultureInfo.InvariantCulture, "Unable to Instantiate InstanceIdGenerator: {0}", e.Message), e); } tProps = cfg.GetPropertyGroup(PropertySchedulerInstanceIdGeneratorPrefix, true); try { ObjectUtils.SetObjectProperties(instanceIdGenerator, tProps); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "InstanceIdGenerator of type '{0}' props could not be configured.", instanceIdGeneratorType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } } // Get ThreadPool Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string tpType = cfg.GetStringProperty(PropertyThreadPoolType, typeof(SimpleThreadPool).AssemblyQualifiedName); if (tpType == null) { initException = new SchedulerException("ThreadPool type not specified. ", SchedulerException.ErrorBadConfiguration); throw initException; } try { tp = (IThreadPool) ObjectUtils.InstantiateType(loadHelper.LoadType(tpType)); } catch (Exception e) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "ThreadPool type '{0}' could not be instantiated.", tpType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } tProps = cfg.GetPropertyGroup(PropertyThreadPoolPrefix, true); try { ObjectUtils.SetObjectProperties(tp, tProps); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "ThreadPool type '{0}' props could not be configured.", tpType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } // Set up any DataSources // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] dsNames = cfg.GetPropertyGroups(PropertyDataSourcePrefix); for (int i = 0; i < dsNames.Length; i++) { PropertiesParser pp = new PropertiesParser( cfg.GetPropertyGroup(string.Format(CultureInfo.InvariantCulture, "{0}.{1}", PropertyDataSourcePrefix, dsNames[i]), true)); string cpType = pp.GetStringProperty(PropertyDbProviderType, null); // custom connectionProvider... if (cpType != null) { IDbProvider cp; try { cp = (IDbProvider) ObjectUtils.InstantiateType(loadHelper.LoadType(cpType)); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "ConnectionProvider of type '{0}' could not be instantiated.", cpType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } try { // remove the type name, so it isn't attempted to be set pp.UnderlyingProperties.Remove(PropertyDbProviderType); ObjectUtils.SetObjectProperties(cp, pp.UnderlyingProperties); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "ConnectionProvider type '{0}' props could not be configured.", cpType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } dbMgr = DBConnectionManager.Instance; dbMgr.AddConnectionProvider(dsNames[i], cp); } else { string dsProvider = pp.GetStringProperty(PropertyDataSourceProvider, null); string dsConnectionString = pp.GetStringProperty(PropertyDataSourceConnectionString, null); string dsConnectionStringName = pp.GetStringProperty(PropertyDataSourceConnectionStringName, null); if (dsConnectionString == null && dsConnectionStringName != null && dsConnectionStringName.Length > 0) { #if NET_20 ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings[dsConnectionStringName]; if (connectionStringSettings == null) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "Named connection string '{0}' not found for DataSource: {1}", dsConnectionStringName, dsNames[i])); throw initException; } dsConnectionString = connectionStringSettings.ConnectionString; #endif } if (dsProvider == null) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "Provider not specified for DataSource: {0}", dsNames[i])); throw initException; } if (dsConnectionString == null) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "Connection string not specified for DataSource: {0}", dsNames[i])); throw initException; } try { DbProvider dbp = new DbProvider(dsProvider, dsConnectionString); dbMgr = DBConnectionManager.Instance; dbMgr.AddConnectionProvider(dsNames[i], dbp); } catch (Exception exception) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "Could not Initialize DataSource: {0}", dsNames[i]), exception); throw initException; } } } // Get JobStore Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string jsType = cfg.GetStringProperty(PropertyJobStoreType, typeof (RAMJobStore).FullName); if (jsType == null) { initException = new SchedulerException("JobStore type not specified. ", SchedulerException.ErrorBadConfiguration); throw initException; } try { js = (IJobStore) ObjectUtils.InstantiateType(loadHelper.LoadType(jsType)); } catch (Exception e) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "JobStore of type '{0}' could not be instantiated.", jsType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } tProps = cfg.GetPropertyGroup(PropertyJobStorePrefix, true, new string[] {PropertyJobStoreLockHandlerPrefix}); try { ObjectUtils.SetObjectProperties(js, tProps); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "JobStore type '{0}' props could not be configured.", jsType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } if (js is JobStoreSupport) { ((JobStoreSupport) js).InstanceId = schedInstId; ((JobStoreSupport) js).InstanceName = schedName; // Install custom lock handler (Semaphore) string lockHandlerTypeName = cfg.GetStringProperty(PropertyJobStoreLockHandlerType); if (lockHandlerTypeName != null) { try { Type lockHandlerType = loadHelper.LoadType(lockHandlerTypeName); ISemaphore lockHandler; ConstructorInfo cWithDbProvider = lockHandlerType.GetConstructor(new Type[] {typeof (DbProvider)}); if (cWithDbProvider != null) { // takes db provider IDbProvider dbProvider = DBConnectionManager.Instance.GetDbProvider(((JobStoreSupport) js).DataSource); lockHandler = (ISemaphore) cWithDbProvider.Invoke(new object[] { dbProvider }); } else { lockHandler = (ISemaphore)ObjectUtils.InstantiateType(lockHandlerType); } tProps = cfg.GetPropertyGroup(PropertyJobStoreLockHandlerPrefix, true); // If this lock handler requires the table prefix, add it to its properties. if (lockHandler is ITablePrefixAware) { tProps[PropertyTablePrefix] = ((JobStoreSupport) js).TablePrefix; } try { ObjectUtils.SetObjectProperties(lockHandler, tProps); } catch (Exception e) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "JobStore LockHandler type '{0}' props could not be configured.", lockHandlerTypeName), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } ((JobStoreSupport) js).LockHandler = lockHandler; Log.Info("Using custom data access locking (synchronization): " + lockHandlerType); } catch (Exception e) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "JobStore LockHandler type '{0}' could not be instantiated.", lockHandlerTypeName), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } } } // Set up any SchedulerPlugins // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] pluginNames = cfg.GetPropertyGroups(PropertyPluginPrefix); ISchedulerPlugin[] plugins = new ISchedulerPlugin[pluginNames.Length]; for (int i = 0; i < pluginNames.Length; i++) { NameValueCollection pp = cfg.GetPropertyGroup(string.Format(CultureInfo.InvariantCulture, "{0}.{1}", PropertyPluginPrefix, pluginNames[i]), true); string plugInType = pp[PropertyPluginType] == null ? null : pp[PropertyPluginType]; if (plugInType == null) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "SchedulerPlugin type not specified for plugin '{0}'", pluginNames[i]), SchedulerException.ErrorBadConfiguration); throw initException; } ISchedulerPlugin plugin; try { plugin = (ISchedulerPlugin) ObjectUtils.InstantiateType(LoadType(plugInType)); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "SchedulerPlugin of type '{0}' could not be instantiated.", plugInType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } try { ObjectUtils.SetObjectProperties(plugin, pp); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "JobStore SchedulerPlugin '{0}' props could not be configured.", plugInType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } plugins[i] = plugin; } // Set up any JobListeners // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Type[] strArg = new Type[] {typeof (string)}; string[] jobListenerNames = cfg.GetPropertyGroups(PropertyJobListenerPrefix); IJobListener[] jobListeners = new IJobListener[jobListenerNames.Length]; for (int i = 0; i < jobListenerNames.Length; i++) { NameValueCollection lp = cfg.GetPropertyGroup(string.Format(CultureInfo.InvariantCulture, "{0}.{1}", PropertyJobListenerPrefix, jobListenerNames[i]), true); string listenerType = lp[PropertyListenerType] == null ? null : lp[PropertyListenerType]; if (listenerType == null) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "JobListener type not specified for listener '{0}'", jobListenerNames[i]), SchedulerException.ErrorBadConfiguration); throw initException; } IJobListener listener; try { listener = (IJobListener) ObjectUtils.InstantiateType(loadHelper.LoadType(listenerType)); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "JobListener of type '{0}' could not be instantiated.", listenerType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } try { MethodInfo nameSetter = listener.GetType().GetMethod("setName", (strArg == null) ? new Type[0] : strArg); if (nameSetter != null) { nameSetter.Invoke(listener, new object[] {jobListenerNames[i]}); } ObjectUtils.SetObjectProperties(listener, lp); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "JobListener '{0}' props could not be configured.", listenerType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } jobListeners[i] = listener; } // Set up any TriggerListeners // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] triggerListenerNames = cfg.GetPropertyGroups(PropertyTriggerListenerPrefix); ITriggerListener[] triggerListeners = new ITriggerListener[triggerListenerNames.Length]; for (int i = 0; i < triggerListenerNames.Length; i++) { NameValueCollection lp = cfg.GetPropertyGroup( string.Format(CultureInfo.InvariantCulture, "{0}.{1}", PropertyTriggerListenerPrefix, triggerListenerNames[i]), true); string listenerType = lp[PropertyListenerType] == null ? null : lp[PropertyListenerType]; if (listenerType == null) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "TriggerListener type not specified for listener '{0}'", triggerListenerNames[i]), SchedulerException.ErrorBadConfiguration); throw initException; } ITriggerListener listener; try { listener = (ITriggerListener) ObjectUtils.InstantiateType(loadHelper.LoadType(listenerType)); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "TriggerListener of type '{0}' could not be instantiated.", listenerType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } try { MethodInfo nameSetter = listener.GetType().GetMethod("setName", (strArg == null) ? new Type[0] : strArg); if (nameSetter != null) { nameSetter.Invoke(listener, (new object[] {triggerListenerNames[i]})); } ObjectUtils.SetObjectProperties(listener, lp); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "TriggerListener '{0}' props could not be configured.", listenerType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } triggerListeners[i] = listener; } // Get exporter // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string exporterType = cfg.GetStringProperty(PropertySchedulerExporterType, null); if (exporterType != null) { try { exporter = (ISchedulerExporter)ObjectUtils.InstantiateType(loadHelper.LoadType(exporterType)); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "Scheduler exporter of type '{0}' could not be instantiated.", exporterType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } tProps = cfg.GetPropertyGroup(PropertySchedulerExporterPrefix, true); try { ObjectUtils.SetObjectProperties(exporter, tProps); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "Scheduler exporter type '{0}' props could not be configured.", exporterType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } } // Fire everything up // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IJobRunShellFactory jrsf = new StdJobRunShellFactory(); if (autoId) { try { schedInstId = DefaultInstanceId; if (js is JobStoreSupport) { if (((JobStoreSupport) js).Clustered) { schedInstId = instanceIdGenerator.GenerateInstanceId(); } } } catch (Exception e) { Log.Error("Couldn't generate instance Id!", e); throw new SystemException("Cannot run without an instance id."); } } if (js is JobStoreSupport) { JobStoreSupport jjs = (JobStoreSupport) js; jjs.InstanceId = schedInstId; jjs.DbRetryInterval = dbFailureRetry; } QuartzSchedulerResources rsrcs = new QuartzSchedulerResources(); rsrcs.Name = schedName; rsrcs.ThreadName = threadName; rsrcs.InstanceId = schedInstId; rsrcs.JobRunShellFactory = jrsf; rsrcs.MakeSchedulerThreadDaemon = makeSchedulerThreadDaemon; rsrcs.ThreadPool = tp; rsrcs.SchedulerExporter = exporter; if (tp is SimpleThreadPool) { ((SimpleThreadPool) tp).ThreadNamePrefix = schedName + "_Worker"; } tp.Initialize(); rsrcs.JobStore = js; // add plugins for (int i = 0; i < plugins.Length; i++) { rsrcs.AddSchedulerPlugin(plugins[i]); } schedCtxt = new SchedulingContext(); schedCtxt.InstanceId = rsrcs.InstanceId; qs = new QuartzScheduler(rsrcs, schedCtxt, idleWaitTime, dbFailureRetry); // Create Scheduler ref... IScheduler sched = Instantiate(rsrcs, qs); // set job factory if specified if (jobFactory != null) { qs.JobFactory = jobFactory; } // Initialize plugins now that we have a Scheduler instance. for (int i = 0; i < plugins.Length; i++) { plugins[i].Initialize(pluginNames[i], sched); } // add listeners for (int i = 0; i < jobListeners.Length; i++) { qs.AddGlobalJobListener(jobListeners[i]); } for (int i = 0; i < triggerListeners.Length; i++) { qs.AddGlobalTriggerListener(triggerListeners[i]); } // set scheduler context data... IEnumerator itr = new HashSet(schedCtxtProps).GetEnumerator(); while (itr.MoveNext()) { string key = (String) itr.Current; string val = schedCtxtProps.Get(key); sched.Context.Put(key, val); } // fire up job store, and runshell factory js.Initialize(loadHelper, qs.SchedulerSignaler); jrsf.Initialize(sched, schedCtxt); Log.Info(string.Format(CultureInfo.InvariantCulture, "Quartz scheduler '{0}' initialized", sched.SchedulerName)); Log.Info(string.Format(CultureInfo.InvariantCulture, "Quartz scheduler version: {0}", qs.Version)); // prevents the repository from being garbage collected qs.AddNoGCObject(schedRep); // prevents the db manager from being garbage collected if (dbMgr != null) { qs.AddNoGCObject(dbMgr); } schedRep.Bind(sched); return sched; }
/// <summary> </summary> private IScheduler Instantiate() { if (cfg == null) { Initialize(); } if (initException != null) { throw initException; } ISchedulerExporter exporter = null; IJobStore js; IThreadPool tp; QuartzScheduler qs = null; IDbConnectionManager dbMgr = null; Type instanceIdGeneratorType = null; NameValueCollection tProps; bool autoId = false; TimeSpan idleWaitTime = TimeSpan.Zero; TimeSpan dbFailureRetry = TimeSpan.FromSeconds(15); IThreadExecutor threadExecutor; SchedulerRepository schedRep = SchedulerRepository.Instance; // Get Scheduler Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string schedName = cfg.GetStringProperty(PropertySchedulerInstanceName, "QuartzScheduler"); string threadName = cfg.GetStringProperty(PropertySchedulerThreadName, "{0}_QuartzSchedulerThread".FormatInvariant(schedName)); string schedInstId = cfg.GetStringProperty(PropertySchedulerInstanceId, DefaultInstanceId); if (schedInstId.Equals(AutoGenerateInstanceId)) { autoId = true; instanceIdGeneratorType = LoadType(cfg.GetStringProperty(PropertySchedulerInstanceIdGeneratorType)) ?? typeof(SimpleInstanceIdGenerator); } else if (schedInstId.Equals(SystemPropertyAsInstanceId)) { autoId = true; instanceIdGeneratorType = typeof(SystemPropertyInstanceIdGenerator); } Type typeLoadHelperType = LoadType(cfg.GetStringProperty(PropertySchedulerTypeLoadHelperType)); Type jobFactoryType = LoadType(cfg.GetStringProperty(PropertySchedulerJobFactoryType, null)); idleWaitTime = cfg.GetTimeSpanProperty(PropertySchedulerIdleWaitTime, idleWaitTime); if (idleWaitTime > TimeSpan.Zero && idleWaitTime < TimeSpan.FromMilliseconds(1000)) { throw new SchedulerException("quartz.scheduler.idleWaitTime of less than 1000ms is not legal."); } dbFailureRetry = cfg.GetTimeSpanProperty(PropertySchedulerDbFailureRetryInterval, dbFailureRetry); if (dbFailureRetry < TimeSpan.Zero) { throw new SchedulerException(PropertySchedulerDbFailureRetryInterval + " of less than 0 ms is not legal."); } bool makeSchedulerThreadDaemon = cfg.GetBooleanProperty(PropertySchedulerMakeSchedulerThreadDaemon); long batchTimeWindow = cfg.GetLongProperty(PropertySchedulerBatchTimeWindow, 0L); int maxBatchSize = cfg.GetIntProperty(PropertySchedulerMaxBatchSize, 1); bool interruptJobsOnShutdown = cfg.GetBooleanProperty(PropertySchedulerInterruptJobsOnShutdown, false); bool interruptJobsOnShutdownWithWait = cfg.GetBooleanProperty(PropertySchedulerInterruptJobsOnShutdownWithWait, false); NameValueCollection schedCtxtProps = cfg.GetPropertyGroup(PropertySchedulerContextPrefix, true); bool proxyScheduler = cfg.GetBooleanProperty(PropertySchedulerProxy, false); // Create type load helper ITypeLoadHelper loadHelper; try { loadHelper = ObjectUtils.InstantiateType <ITypeLoadHelper>(typeLoadHelperType ?? typeof(SimpleTypeLoadHelper)); } catch (Exception e) { throw new SchedulerConfigException("Unable to instantiate type load helper: {0}".FormatInvariant(e.Message), e); } loadHelper.Initialize(); // If Proxying to remote scheduler, short-circuit here... // ~~~~~~~~~~~~~~~~~~ if (proxyScheduler) { if (autoId) { schedInstId = DefaultInstanceId; } Type proxyType = loadHelper.LoadType(cfg.GetStringProperty(PropertySchedulerProxyType)) ?? typeof(RemotingSchedulerProxyFactory); IRemotableSchedulerProxyFactory factory; try { factory = ObjectUtils.InstantiateType <IRemotableSchedulerProxyFactory>(proxyType); ObjectUtils.SetObjectProperties(factory, cfg.GetPropertyGroup(PropertySchedulerProxy, true)); } catch (Exception e) { initException = new SchedulerException("Remotable proxy factory '{0}' could not be instantiated.".FormatInvariant(proxyType), e); throw initException; } string uid = QuartzSchedulerResources.GetUniqueIdentifier(schedName, schedInstId); RemoteScheduler remoteScheduler = new RemoteScheduler(uid, factory); schedRep.Bind(remoteScheduler); return(remoteScheduler); } IJobFactory jobFactory = null; if (jobFactoryType != null) { try { jobFactory = ObjectUtils.InstantiateType <IJobFactory>(jobFactoryType); } catch (Exception e) { throw new SchedulerConfigException("Unable to Instantiate JobFactory: {0}".FormatInvariant(e.Message), e); } tProps = cfg.GetPropertyGroup(PropertySchedulerJobFactoryPrefix, true); try { ObjectUtils.SetObjectProperties(jobFactory, tProps); } catch (Exception e) { initException = new SchedulerException("JobFactory of type '{0}' props could not be configured.".FormatInvariant(jobFactoryType), e); throw initException; } } IInstanceIdGenerator instanceIdGenerator = null; if (instanceIdGeneratorType != null) { try { instanceIdGenerator = ObjectUtils.InstantiateType <IInstanceIdGenerator>(instanceIdGeneratorType); } catch (Exception e) { throw new SchedulerConfigException("Unable to Instantiate InstanceIdGenerator: {0}".FormatInvariant(e.Message), e); } tProps = cfg.GetPropertyGroup(PropertySchedulerInstanceIdGeneratorPrefix, true); try { ObjectUtils.SetObjectProperties(instanceIdGenerator, tProps); } catch (Exception e) { initException = new SchedulerException("InstanceIdGenerator of type '{0}' props could not be configured.".FormatInvariant(instanceIdGeneratorType), e); throw initException; } } // Get ThreadPool Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Type tpType = loadHelper.LoadType(cfg.GetStringProperty(PropertyThreadPoolType)) ?? typeof(SimpleThreadPool); try { tp = ObjectUtils.InstantiateType <IThreadPool>(tpType); } catch (Exception e) { initException = new SchedulerException("ThreadPool type '{0}' could not be instantiated.".FormatInvariant(tpType), e); throw initException; } tProps = cfg.GetPropertyGroup(PropertyThreadPoolPrefix, true); try { ObjectUtils.SetObjectProperties(tp, tProps); } catch (Exception e) { initException = new SchedulerException("ThreadPool type '{0}' props could not be configured.".FormatInvariant(tpType), e); throw initException; } // Set up any DataSources // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IList <string> dsNames = cfg.GetPropertyGroups(PropertyDataSourcePrefix); foreach (string dataSourceName in dsNames) { string datasourceKey = "{0}.{1}".FormatInvariant(PropertyDataSourcePrefix, dataSourceName); NameValueCollection propertyGroup = cfg.GetPropertyGroup(datasourceKey, true); PropertiesParser pp = new PropertiesParser(propertyGroup); Type cpType = loadHelper.LoadType(pp.GetStringProperty(PropertyDbProviderType, null)); // custom connectionProvider... if (cpType != null) { IDbProvider cp; try { cp = ObjectUtils.InstantiateType <IDbProvider>(cpType); } catch (Exception e) { initException = new SchedulerException("ConnectionProvider of type '{0}' could not be instantiated.".FormatInvariant(cpType), e); throw initException; } try { // remove the type name, so it isn't attempted to be set pp.UnderlyingProperties.Remove(PropertyDbProviderType); ObjectUtils.SetObjectProperties(cp, pp.UnderlyingProperties); cp.Initialize(); } catch (Exception e) { initException = new SchedulerException("ConnectionProvider type '{0}' props could not be configured.".FormatInvariant(cpType), e); throw initException; } dbMgr = DBConnectionManager.Instance; dbMgr.AddConnectionProvider(dataSourceName, cp); } else { string dsProvider = pp.GetStringProperty(PropertyDataSourceProvider, null); string dsConnectionString = pp.GetStringProperty(PropertyDataSourceConnectionString, null); string dsConnectionStringName = pp.GetStringProperty(PropertyDataSourceConnectionStringName, null); if (dsConnectionString == null && !String.IsNullOrEmpty(dsConnectionStringName)) { ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings[dsConnectionStringName]; if (connectionStringSettings == null) { initException = new SchedulerException("Named connection string '{0}' not found for DataSource: {1}".FormatInvariant(dsConnectionStringName, dataSourceName)); throw initException; } dsConnectionString = connectionStringSettings.ConnectionString; } if (dsProvider == null) { initException = new SchedulerException("Provider not specified for DataSource: {0}".FormatInvariant(dataSourceName)); throw initException; } if (dsConnectionString == null) { initException = new SchedulerException("Connection string not specified for DataSource: {0}".FormatInvariant(dataSourceName)); throw initException; } try { DbProvider dbp = new DbProvider(dsProvider, dsConnectionString); dbp.Initialize(); dbMgr = DBConnectionManager.Instance; dbMgr.AddConnectionProvider(dataSourceName, dbp); } catch (Exception exception) { initException = new SchedulerException("Could not Initialize DataSource: {0}".FormatInvariant(dataSourceName), exception); throw initException; } } } // Get object serializer properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IObjectSerializer objectSerializer; string objectSerializerType = cfg.GetStringProperty("quartz.serializer.type"); if (objectSerializerType != null) { tProps = cfg.GetPropertyGroup(PropertyObjectSerializer, true); try { objectSerializer = ObjectUtils.InstantiateType <IObjectSerializer>(loadHelper.LoadType(objectSerializerType)); log.Info("Using custom implementation for object serializer: " + objectSerializerType); ObjectUtils.SetObjectProperties(objectSerializer, tProps); } catch (Exception e) { initException = new SchedulerException("Object serializer type '" + objectSerializerType + "' could not be instantiated.", e); throw initException; } } else { log.Info("Using default implementation for object serializer"); objectSerializer = new DefaultObjectSerializer(); } // Get JobStore Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Type jsType = loadHelper.LoadType(cfg.GetStringProperty(PropertyJobStoreType)); try { js = ObjectUtils.InstantiateType <IJobStore>(jsType ?? typeof(RAMJobStore)); } catch (Exception e) { initException = new SchedulerException("JobStore of type '{0}' could not be instantiated.".FormatInvariant(jsType), e); throw initException; } SchedulerDetailsSetter.SetDetails(js, schedName, schedInstId); tProps = cfg.GetPropertyGroup(PropertyJobStorePrefix, true, new string[] { PropertyJobStoreLockHandlerPrefix }); try { ObjectUtils.SetObjectProperties(js, tProps); } catch (Exception e) { initException = new SchedulerException("JobStore type '{0}' props could not be configured.".FormatInvariant(jsType), e); throw initException; } JobStoreSupport jobStoreSupport = js as JobStoreSupport; if (jobStoreSupport != null) { // Install custom lock handler (Semaphore) Type lockHandlerType = loadHelper.LoadType(cfg.GetStringProperty(PropertyJobStoreLockHandlerType)); if (lockHandlerType != null) { try { ISemaphore lockHandler; ConstructorInfo cWithDbProvider = lockHandlerType.GetConstructor(new Type[] { typeof(DbProvider) }); if (cWithDbProvider != null) { // takes db provider IDbProvider dbProvider = DBConnectionManager.Instance.GetDbProvider(jobStoreSupport.DataSource); lockHandler = (ISemaphore)cWithDbProvider.Invoke(new object[] { dbProvider }); } else { lockHandler = ObjectUtils.InstantiateType <ISemaphore>(lockHandlerType); } tProps = cfg.GetPropertyGroup(PropertyJobStoreLockHandlerPrefix, true); // If this lock handler requires the table prefix, add it to its properties. if (lockHandler is ITablePrefixAware) { tProps[PropertyTablePrefix] = jobStoreSupport.TablePrefix; tProps[PropertySchedulerName] = schedName; } try { ObjectUtils.SetObjectProperties(lockHandler, tProps); } catch (Exception e) { initException = new SchedulerException("JobStore LockHandler type '{0}' props could not be configured.".FormatInvariant(lockHandlerType), e); throw initException; } jobStoreSupport.LockHandler = lockHandler; Log.Info("Using custom data access locking (synchronization): " + lockHandlerType); } catch (Exception e) { initException = new SchedulerException("JobStore LockHandler type '{0}' could not be instantiated.".FormatInvariant(lockHandlerType), e); throw initException; } } } // Set up any SchedulerPlugins // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IList <string> pluginNames = cfg.GetPropertyGroups(PropertyPluginPrefix); ISchedulerPlugin[] plugins = new ISchedulerPlugin[pluginNames.Count]; for (int i = 0; i < pluginNames.Count; i++) { NameValueCollection pp = cfg.GetPropertyGroup("{0}.{1}".FormatInvariant(PropertyPluginPrefix, pluginNames[i]), true); string plugInType = pp[PropertyPluginType]; if (plugInType == null) { initException = new SchedulerException("SchedulerPlugin type not specified for plugin '{0}'".FormatInvariant(pluginNames[i])); throw initException; } ISchedulerPlugin plugin; try { plugin = ObjectUtils.InstantiateType <ISchedulerPlugin>(LoadType(plugInType)); } catch (Exception e) { initException = new SchedulerException("SchedulerPlugin of type '{0}' could not be instantiated.".FormatInvariant(plugInType), e); throw initException; } try { ObjectUtils.SetObjectProperties(plugin, pp); } catch (Exception e) { initException = new SchedulerException("JobStore SchedulerPlugin '{0}' props could not be configured.".FormatInvariant(plugInType), e); throw initException; } plugins[i] = plugin; } // Set up any JobListeners // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IList <string> jobListenerNames = cfg.GetPropertyGroups(PropertyJobListenerPrefix); IJobListener[] jobListeners = new IJobListener[jobListenerNames.Count]; for (int i = 0; i < jobListenerNames.Count; i++) { NameValueCollection lp = cfg.GetPropertyGroup("{0}.{1}".FormatInvariant(PropertyJobListenerPrefix, jobListenerNames[i]), true); string listenerType = lp[PropertyListenerType]; if (listenerType == null) { initException = new SchedulerException("JobListener type not specified for listener '{0}'".FormatInvariant(jobListenerNames[i])); throw initException; } IJobListener listener; try { listener = ObjectUtils.InstantiateType <IJobListener>(loadHelper.LoadType(listenerType)); } catch (Exception e) { initException = new SchedulerException("JobListener of type '{0}' could not be instantiated.".FormatInvariant(listenerType), e); throw initException; } try { PropertyInfo nameProperty = listener.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance); if (nameProperty != null && nameProperty.CanWrite) { nameProperty.GetSetMethod().Invoke(listener, new object[] { jobListenerNames[i] }); } ObjectUtils.SetObjectProperties(listener, lp); } catch (Exception e) { initException = new SchedulerException("JobListener '{0}' props could not be configured.".FormatInvariant(listenerType), e); throw initException; } jobListeners[i] = listener; } // Set up any TriggerListeners // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IList <string> triggerListenerNames = cfg.GetPropertyGroups(PropertyTriggerListenerPrefix); ITriggerListener[] triggerListeners = new ITriggerListener[triggerListenerNames.Count]; for (int i = 0; i < triggerListenerNames.Count; i++) { NameValueCollection lp = cfg.GetPropertyGroup("{0}.{1}".FormatInvariant(PropertyTriggerListenerPrefix, triggerListenerNames[i]), true); string listenerType = lp[PropertyListenerType]; if (listenerType == null) { initException = new SchedulerException("TriggerListener type not specified for listener '{0}'".FormatInvariant(triggerListenerNames[i])); throw initException; } ITriggerListener listener; try { listener = ObjectUtils.InstantiateType <ITriggerListener>(loadHelper.LoadType(listenerType)); } catch (Exception e) { initException = new SchedulerException("TriggerListener of type '{0}' could not be instantiated.".FormatInvariant(listenerType), e); throw initException; } try { PropertyInfo nameProperty = listener.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance); if (nameProperty != null && nameProperty.CanWrite) { nameProperty.GetSetMethod().Invoke(listener, new object[] { triggerListenerNames[i] }); } ObjectUtils.SetObjectProperties(listener, lp); } catch (Exception e) { initException = new SchedulerException("TriggerListener '{0}' props could not be configured.".FormatInvariant(listenerType), e); throw initException; } triggerListeners[i] = listener; } // Get exporter // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string exporterType = cfg.GetStringProperty(PropertySchedulerExporterType, null); if (exporterType != null) { try { exporter = ObjectUtils.InstantiateType <ISchedulerExporter>(loadHelper.LoadType(exporterType)); } catch (Exception e) { initException = new SchedulerException("Scheduler exporter of type '{0}' could not be instantiated.".FormatInvariant(exporterType), e); throw initException; } tProps = cfg.GetPropertyGroup(PropertySchedulerExporterPrefix, true); try { ObjectUtils.SetObjectProperties(exporter, tProps); } catch (Exception e) { initException = new SchedulerException("Scheduler exporter type '{0}' props could not be configured.".FormatInvariant(exporterType), e); throw initException; } } bool tpInited = false; bool qsInited = false; // Get ThreadExecutor Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string threadExecutorClass = cfg.GetStringProperty(PropertyThreadExecutorType); if (threadExecutorClass != null) { tProps = cfg.GetPropertyGroup(PropertyThreadExecutor, true); try { threadExecutor = ObjectUtils.InstantiateType <IThreadExecutor>(loadHelper.LoadType(threadExecutorClass)); log.Info("Using custom implementation for ThreadExecutor: " + threadExecutorClass); ObjectUtils.SetObjectProperties(threadExecutor, tProps); } catch (Exception e) { initException = new SchedulerException( "ThreadExecutor class '" + threadExecutorClass + "' could not be instantiated.", e); throw initException; } } else { log.Info("Using default implementation for ThreadExecutor"); threadExecutor = new DefaultThreadExecutor(); } // Fire everything up // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ try { IJobRunShellFactory jrsf = new StdJobRunShellFactory(); if (autoId) { try { schedInstId = DefaultInstanceId; if (js.Clustered) { schedInstId = instanceIdGenerator.GenerateInstanceId(); } } catch (Exception e) { Log.Error("Couldn't generate instance Id!", e); throw new SystemException("Cannot run without an instance id."); } } jobStoreSupport = js as JobStoreSupport; if (jobStoreSupport != null) { jobStoreSupport.DbRetryInterval = dbFailureRetry; jobStoreSupport.ThreadExecutor = threadExecutor; // object serializer jobStoreSupport.ObjectSerializer = objectSerializer; } QuartzSchedulerResources rsrcs = new QuartzSchedulerResources(); rsrcs.Name = schedName; rsrcs.ThreadName = threadName; rsrcs.InstanceId = schedInstId; rsrcs.JobRunShellFactory = jrsf; rsrcs.MakeSchedulerThreadDaemon = makeSchedulerThreadDaemon; rsrcs.BatchTimeWindow = TimeSpan.FromMilliseconds(batchTimeWindow); rsrcs.MaxBatchSize = maxBatchSize; rsrcs.InterruptJobsOnShutdown = interruptJobsOnShutdown; rsrcs.InterruptJobsOnShutdownWithWait = interruptJobsOnShutdownWithWait; rsrcs.SchedulerExporter = exporter; SchedulerDetailsSetter.SetDetails(tp, schedName, schedInstId); rsrcs.ThreadExecutor = threadExecutor; threadExecutor.Initialize(); rsrcs.ThreadPool = tp; tp.Initialize(); tpInited = true; rsrcs.JobStore = js; // add plugins foreach (ISchedulerPlugin plugin in plugins) { rsrcs.AddSchedulerPlugin(plugin); } qs = new QuartzScheduler(rsrcs, idleWaitTime); qsInited = true; // Create Scheduler ref... IScheduler sched = Instantiate(rsrcs, qs); // set job factory if specified if (jobFactory != null) { qs.JobFactory = jobFactory; } // Initialize plugins now that we have a Scheduler instance. for (int i = 0; i < plugins.Length; i++) { plugins[i].Initialize(pluginNames[i], sched); } // add listeners foreach (IJobListener listener in jobListeners) { qs.ListenerManager.AddJobListener(listener, EverythingMatcher <JobKey> .AllJobs()); } foreach (ITriggerListener listener in triggerListeners) { qs.ListenerManager.AddTriggerListener(listener, EverythingMatcher <TriggerKey> .AllTriggers()); } // set scheduler context data... foreach (string key in schedCtxtProps) { string val = schedCtxtProps.Get(key); sched.Context.Put(key, val); } // fire up job store, and runshell factory js.InstanceId = schedInstId; js.InstanceName = schedName; js.ThreadPoolSize = tp.PoolSize; js.Initialize(loadHelper, qs.SchedulerSignaler); jrsf.Initialize(sched); qs.Initialize(); Log.Info("Quartz scheduler '{0}' initialized".FormatInvariant(sched.SchedulerName)); Log.Info("Quartz scheduler version: {0}".FormatInvariant(qs.Version)); // prevents the repository from being garbage collected qs.AddNoGCObject(schedRep); // prevents the db manager from being garbage collected if (dbMgr != null) { qs.AddNoGCObject(dbMgr); } schedRep.Bind(sched); return(sched); } catch (SchedulerException) { ShutdownFromInstantiateException(tp, qs, tpInited, qsInited); throw; } catch { ShutdownFromInstantiateException(tp, qs, tpInited, qsInited); throw; } }
/// <summary> /// Calls the equivalent method on the 'proxied' <see cref="QuartzScheduler" />. /// </summary> public virtual void AddJobListener(IJobListener jobListener) { sched.AddJobListener(jobListener); }