AddSchedulerPlugin() публичный Метод

Add the given ISchedulerPlugin for the QuartzScheduler to use. This method expects the plugin's "initialize" method to be invoked externally (either before or after this method is called).
public AddSchedulerPlugin ( ISchedulerPlugin plugin ) : void
plugin ISchedulerPlugin
Результат void
Пример #1
0
        /// <summary>
        /// Creates a scheduler using the specified thread pool and job store and
        /// binds it for remote access.
        /// </summary>
        /// <param name="schedulerName">The name for the scheduler.</param>
        /// <param name="schedulerInstanceId">The instance ID for the scheduler.</param>
        /// <param name="threadPool">The thread pool for executing jobs</param>
        /// <param name="threadExecutor">Thread executor.</param>
        /// <param name="jobStore">The type of job store</param>
        /// <param name="schedulerPluginMap"></param>
        /// <param name="idleWaitTime">The idle wait time. You can specify TimeSpan.Zero for
        /// the default value, which is currently 30000 ms.</param>
        /// <param name="dbFailureRetryInterval">The db failure retry interval.</param>
        /// <param name="maxBatchSize">The maximum batch size of triggers, when acquiring them</param>
        /// <param name="batchTimeWindow">The time window for which it is allowed to "pre-acquire" triggers to fire</param>
        public virtual void CreateScheduler(string schedulerName, string schedulerInstanceId, IThreadPool threadPool, IThreadExecutor threadExecutor,
                                            IJobStore jobStore, IDictionary<string, ISchedulerPlugin> schedulerPluginMap, TimeSpan idleWaitTime,
                                            TimeSpan dbFailureRetryInterval, int maxBatchSize, TimeSpan batchTimeWindow)
        {
            // Currently only one run-shell factory is available...
            IJobRunShellFactory jrsf = new StdJobRunShellFactory();

            // Fire everything u
            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            threadPool.Initialize();

            QuartzSchedulerResources qrs = new QuartzSchedulerResources();

            qrs.Name = schedulerName;
            qrs.InstanceId = schedulerInstanceId;

            SchedulerDetailsSetter.SetDetails(threadPool, schedulerName, schedulerInstanceId);

            qrs.JobRunShellFactory = jrsf;
            qrs.ThreadPool = threadPool;
            qrs.ThreadExecutor= threadExecutor;
            qrs.JobStore = jobStore;
            qrs.MaxBatchSize = maxBatchSize;
            qrs.BatchTimeWindow = batchTimeWindow;

            // add plugins
            if (schedulerPluginMap != null)
            {
                foreach (ISchedulerPlugin plugin in schedulerPluginMap.Values)
                {
                    qrs.AddSchedulerPlugin(plugin);
                }
            }

            QuartzScheduler qs = new QuartzScheduler(qrs, idleWaitTime, dbFailureRetryInterval);

            ITypeLoadHelper cch = new SimpleTypeLoadHelper();
            cch.Initialize();

            SchedulerDetailsSetter.SetDetails(jobStore, schedulerName, schedulerInstanceId);
            jobStore.Initialize(cch, qs.SchedulerSignaler);

            IScheduler scheduler = new StdScheduler(qs);

            jrsf.Initialize(scheduler);

            qs.Initialize();

            // Initialize plugins now that we have a Scheduler instance.
            if (schedulerPluginMap != null)
            {
                foreach (var pluginEntry in schedulerPluginMap)
                {
                    pluginEntry.Value.Initialize(pluginEntry.Key, scheduler);
                }
            }

            Log.Info(string.Format(CultureInfo.InvariantCulture, "Quartz scheduler '{0}", scheduler.SchedulerName));

            Log.Info(string.Format(CultureInfo.InvariantCulture, "Quartz scheduler version: {0}", qs.Version));

            SchedulerRepository schedRep = SchedulerRepository.Instance;

            qs.AddNoGCObject(schedRep); // prevents the repository from being
            // garbage collected

            schedRep.Bind(scheduler);

            initialized = true;
        }
        /// <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;
        }
Пример #3
0
        /// <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;
            }
        }
	    /// <summary>
		/// Creates a scheduler using the specified thread pool and job store and
		/// binds it to RMI.
		/// </summary>
		/// <param name="schedulerName">The name for the scheduler.</param>
		/// <param name="schedulerInstanceId">The instance ID for the scheduler.</param>
		/// <param name="threadPool">The thread pool for executing jobs</param>
		/// <param name="jobStore">The type of job store</param>
		/// <param name="schedulerPluginMap"></param>
		/// <param name="idleWaitTime">The idle wait time. You can specify TimeSpan.Zero for
		/// the default value, which is currently 30000 ms.</param>
		/// <param name="dbFailureRetryInterval">The db failure retry interval.</param>
		public virtual void CreateScheduler(string schedulerName, string schedulerInstanceId, IThreadPool threadPool,
                                            IJobStore jobStore, IDictionary schedulerPluginMap, TimeSpan idleWaitTime,
		                                    TimeSpan dbFailureRetryInterval)
		{
			// Currently only one run-shell factory is available...
			IJobRunShellFactory jrsf = new StdJobRunShellFactory();

			// Fire everything up
			// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			SchedulingContext schedCtxt = new SchedulingContext();
			schedCtxt.InstanceId = schedulerInstanceId;

			QuartzSchedulerResources qrs = new QuartzSchedulerResources();

			qrs.Name = schedulerName;
			qrs.InstanceId = schedulerInstanceId;
			qrs.JobRunShellFactory = jrsf;
			qrs.ThreadPool = threadPool;
			qrs.JobStore = jobStore;


            // add plugins
            if (schedulerPluginMap != null)
            {
                foreach (ISchedulerPlugin plugin in schedulerPluginMap.Values)
                {
                    qrs.AddSchedulerPlugin(plugin);
                }
            }

			QuartzScheduler qs = new QuartzScheduler(qrs, schedCtxt, idleWaitTime, dbFailureRetryInterval);

			ITypeLoadHelper cch = new CascadingClassLoadHelper();
			cch.Initialize();

			jobStore.Initialize(cch, qs.SchedulerSignaler);

			IScheduler scheduler = new StdScheduler(qs, schedCtxt);

            // Initialize plugins now that we have a Scheduler instance.
            if (schedulerPluginMap != null)
            {
                foreach (DictionaryEntry pluginEntry in schedulerPluginMap)
                {
                    ((ISchedulerPlugin)pluginEntry.Value).Initialize(
                            (string) pluginEntry.Key, scheduler);
                }
            }

			jrsf.Initialize(scheduler, schedCtxt);

			Log.Info(string.Format(CultureInfo.InvariantCulture, "Quartz scheduler '{0}", scheduler.SchedulerName));

			Log.Info(string.Format(CultureInfo.InvariantCulture, "Quartz scheduler version: {0}", qs.Version));

			SchedulerRepository schedRep = SchedulerRepository.Instance;

			qs.AddNoGCObject(schedRep); // prevents the repository from being
			// garbage collected

			schedRep.Bind(scheduler);
		}