Search code examples
c#quartz.net

Unable to save anything to the Quartz.net ado store


Just starting out with Quartz.Net. So please dont mind the rookie question.

I have searched SO but apparently, I couldn't find someone facing the same problem. I am using MySQL for my Quartz.Net ADO store. I am able to run the service successfully and also fire jobs using the scheduler. But nothing gets logs into the Database. I checked if the DB is getting picked up by using a false password and the Scheduler service fails to start. So the Store is being picked by the service but the jobs which are fired are not being logged. I am not sure why.

These are the properties of my Scheduler Service.

  <quartz >
    <add key="quartz.scheduler.instanceName" value="AbACScheduler"/>
    <add key="quartz.scheduler.instanceId" value="instance_one"/>
    <add key="quartz.threadPool.threadCount" value="10"/>
    <add key="quartz.threadPool.threadPriority" value="Normal"/>

    <add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.MySQLDelegate, Quartz"/>
    <add key="quartz.jobStore.dataSource" value="default"/>
    <add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"/>
    <add key="quartz.dataSource.default.connectionString" value="Server=localhost;Database=quartz;Uid=xxx;Pwd=xxx;"/>
    <add key="quartz.jobStore.tablePrefix" value="qrtz_"/>
    <add key="quartz.dataSource.default.provider" value="MySql-50"/>
    <add key="quartz.jobStore.useProperties" value="true"/>
  </quartz>

The table prefix is also correct and I am using the 5.0 MySQL connector.

This is my Small test Console code for testing the service.

 private static void Main(string[] args)
    {
        try
        {
            Common.Logging.LogManager.Adapter = new Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter { Level = Common.Logging.LogLevel.Info };

            // Grab the Scheduler instance from the Factory 
            IScheduler scheduler = GetScheduler();

            // and start it off
            scheduler.Start();

            // define the job and tie it to our HelloJob class
            IJobDetail job = JobBuilder.Create<HelloJob>()
                .WithIdentity("job1", "group1")
                .Build();

            // Trigger the job to run now, and then repeat every 10 seconds
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity("trigger1", "group1")
                .StartNow()
                .WithSimpleSchedule(x => x
                    .WithIntervalInSeconds(10)
                    .RepeatForever())
                .Build();

            // Tell quartz to schedule the job using our trigger
            scheduler.ScheduleJob(job, trigger);

            // some sleep to show what's happening
            Thread.Sleep(TimeSpan.FromSeconds(60));

            // and last shut down the scheduler when you are ready to close your program
            scheduler.Shutdown();
        }
        catch (SchedulerException se)
        {
            Console.WriteLine(se);
        }

        Console.WriteLine("Press any key to close the application");
        Console.ReadKey();
    }
    private static IScheduler GetScheduler()
    {
        try
        {
            var properties = new NameValueCollection();
            properties["quartz.scheduler.instanceName"] = "AbACScheduler";
            properties["quartz.dataSource.default.provider"] ="MySql-50";
            properties["quartz.scheduler.proxy.address"] = string.Format(@"tcp://{0}:{1}/{2}", "localhost", "555",
                                                                         "AbACScheduler");

            // Get a reference to the scheduler
            var sf = new StdSchedulerFactory(properties);

            return sf.GetScheduler();

        }
        catch (Exception ex)
        {
            Console.WriteLine("Scheduler not available: '{0}'", ex.Message);
            throw;
        }
    }

This is my HelloJob (taken from quartz.Net)

public class HelloJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            Console.WriteLine("Greetings from HelloJob!");
        }
    }

I took the DB script for creating ADOStore for MySQL, which came along with the Quartz.Net Source files.

IS there anything which I am doing wrong? Please guide me.

Thanks!


Solution

  • Comparing my working AdoJobStore (but with sql server)........to yours, I see the following items missing.

    <add key="quartz.scheduler.instanceName" value="ExampleDefaultQuartzSchedulerInstanceName"/>
    <add key="quartz.scheduler.instanceId" value="instance_one"/>
    <add key="quartz.threadPool.threadCount" value="10"/>
    <add key="quartz.threadPool.threadPriority" value="Normal"/>
    

    Now I have this:

    <add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"/>
    

    and you have:

    Is there a MySql specific one?

    Here is my full setup, with sql server, but maybe you can start with this and plug in the mysql values.

    <add key="quartz.scheduler.instanceName" value="ExampleDefaultQuartzSchedulerFromConfigFileSqlServer"/>
    <add key="quartz.scheduler.instanceId" value="instance_one"/>
    <add key="quartz.threadPool.threadCount" value="10"/>
    <add key="quartz.threadPool.threadPriority" value="Normal"/>
    
    <!-- 
    org.quartz.scheduler.idleWaitTime
    Is the amount of time in milliseconds that the scheduler will wait before re-queries for available triggers when the scheduler is otherwise idle. Normally you should not have to 'tune' this parameter, unless you're using XA transactions, and are having problems with delayed firings of triggers that should fire immediately.
    It defaults to every 30 seconds until it finds a trigger. Once it finds any triggers, it gets the time of the next trigger to fire and stops checking until then, unless a trigger changes.   -->
    <add key="quartz.scheduler.idleWaitTime" value ="5000"/>
    
    <!-- Misfire : see http://nurkiewicz.blogspot.com/2012/04/quartz-scheduler-misfire-instructions.html  -->
    <add key="quartz.jobStore.misfireThreshold" value="60000"/>
    <add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"/>
    <add key="quartz.jobStore.tablePrefix" value="QRTZ_"/>
    <add key="quartz.jobStore.clustered" value="false"/>
    <add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"/>
    
    
    <add key="quartz.jobStore.dataSource" value="MySqlServerFullVersion"/>
    <add key="quartz.jobStore.useProperties" value="false"/>
    
    <add key="quartz.dataSource.MySqlServerFullVersion.connectionString" value="SuperSecret!!"/>
    <add key="quartz.dataSource.MySqlServerFullVersion.provider" value="SqlServer-20"/>
    

    EDIT

    Here is my full code......as an FYI.

                NameValueCollection config = (NameValueCollection)ConfigurationManager.GetSection("quartz");
                ISchedulerFactory factory = new StdSchedulerFactory(config);
                IScheduler sched = factory.GetScheduler();
    
                try
                {
    
                    sched.Clear();
    
                    /* schedule some jobs through code */
    
                    sched.Start();
    
                    Thread.Sleep(TimeSpan.FromSeconds(1));
    
                    Console.WriteLine(string.Empty);
                    Console.WriteLine("Press ENTER to Continue to Shut Down");
                    Console.WriteLine(string.Empty);
                    Console.ReadLine();
    
                }
                finally
                {
                    sched.Shutdown(false);
                }
    
    
                Console.Write("");
    
            }
            catch (Exception ex)
            {
    
                Exception exc = ex;
                while (null != exc)
                {
                    Console.WriteLine(exc.Message);
                    exc = exc.InnerException;
                }
            }
            finally
            {
                Console.WriteLine(string.Empty);
                Console.WriteLine(string.Empty);
                Console.WriteLine("Press ENTER to Exit");
                Console.ReadLine();
            }
    

    I just checked. The [QRTZ_FIRED_TRIGGERS] "cleans up after itself". It does NOT keep a full history.

    I've run thousands of jobs on my dev environment, but that table has one row in it.

    Note the below code in StdAdoConstants.cs

            public static readonly string SqlDeleteFiredTrigger =
                string.Format(CultureInfo.InvariantCulture, "DELETE FROM {0}{1} WHERE {2} = {3} AND {4} = @triggerEntryId", 
                TablePrefixSubst, TableFiredTriggers,ColumnSchedulerName, SchedulerNameSubst, ColumnEntryId);
    
            public static readonly string SqlDeleteFiredTriggers =
                string.Format(CultureInfo.InvariantCulture, "DELETE FROM {0}{1} WHERE {2} = {3}", TablePrefixSubst, TableFiredTriggers, ColumnSchedulerName, SchedulerNameSubst);
    
            public static readonly string SqlDeleteInstancesFiredTriggers =
                string.Format(CultureInfo.InvariantCulture, "DELETE FROM {0}{1} WHERE {2} = {3} AND {4} = @instanceName", TablePrefixSubst, TableFiredTriggers, ColumnSchedulerName, SchedulerNameSubst,
                              ColumnInstanceName);