2

I need to retrieve a list of all triggers in a Quartz.NET database so I can list information about them in a table. I want all triggers, regardless of whether they're running, waiting, acquired, or whatever. I'm only using a single scheduler name and a single group, so in my case this is basically a simple matter of doing SELECT * FROM QRTZ_TRIGGERS (not entirely true because I also need information from the QRTZ_CRON_TRIGGERS table), but I'd rather go through the API.

Currently I'm going through all known job types and calling GetTriggersOfJob for each one, as I've seen recommended in a couple of places on the internet. My real code is more complex than this, but this is the gist of it:

var allJobKeys = *a list of all known jobs*
var scheduler = *a new scheduler object*
var allTriggers = allJobKeys
    .Select(scheduler.GetTriggersOfJob)
    .ToList();

Is this really the only way to do it? It's really inefficient! I have about 30 different job types (and counting), most of which are likely to have zero triggers associated with them at any given time. But this will require 30 database queries every time, instead of a single query that retrieves all of them.

Note that the scheduler I'm retrieving the triggers in is used solely for that purpose as well as for creating/updating/deleting triggers, and will never be used to execute jobs. I ensure that by never calling scheduler.Start() on it.

From what I can tell there's no getAllTriggers() in the original Quartz API in Java either, so I'm assuming there's a reason why this doesn't exist, even though it seems like such a no-brainer. Is it do with concurrency handling when there are multiple scheduler hosts running in clustered mode or something like that? It seems like something people would want to do fairly often.

Magnus Grindal Bakken
  • 2,083
  • 1
  • 16
  • 22
  • Isn't this answer available at http://stackoverflow.com/questions/12489450/get-all-jobs-in-quartz-net-2-0 – labilbe Mar 03 '14 at 10:07
  • @labilbe The accepted answer there uses the same technique that I'm currently using, with `GetTriggersOfJob`. – Magnus Grindal Bakken Mar 03 '14 at 10:09
  • this is one of the small drawbacks to using an object model...with an existing API....."set operations" are sometimes an afterthought. you're stuck with the "looping"........you could ~contribute to the open source project......after you write code to do what you want. – granadaCoder Mar 03 '14 at 13:59
  • @granadaCoder Yes, I might put in a pull request if I can find the time to implement the function. I was mostly wondering if there was 1) something I'd missed; or 2) some technical/philosophical reason why it doesn't already exist. – Magnus Grindal Bakken Mar 03 '14 at 14:03
  • I hit a similar type of issue myself : http://stackoverflow.com/questions/21537460/testing-for-iinterruptablejob – granadaCoder Mar 03 '14 at 14:05

1 Answers1

8

A little more straightforward way could be

var allTriggerKeys = sched.GetTriggerKeys(GroupMatcher<TriggerKey>.AnyGroup());
foreach (var triggerKey in allTriggerKeys)
{
    ITrigger trigger = sched.GetTrigger(triggerKey);
}

Why so complicated and slow? The thing here is that there is trigger polymorphism and the type (and thus the associated data via linked table) is not known beforehand. After base record is loaded the rest of data can be loaded. And yes, the API was not originally meant for set operations.

If you are just reporting, I'd say bite the bullet and create the custom SQL query with (outer) joins etc. Just don't update Quartz's tables without Quartz knowing about it. Also don't issue DB locks. Prepare to fix the the query if schema changes.

Marko Lahma
  • 6,586
  • 25
  • 29
  • Thanks for the reply. Your solution does seem better than mine, and it should actually be faster in many cases, since I'm likely to have fewer actual triggers than job types. If I do go with the manual SQL route, I'll definitely make sure I avoid updating anything or creating locks. – Magnus Grindal Bakken Mar 14 '14 at 08:11