Decoupling Quartz from a web-app
If you’re a Java Developer and you’ve had to deal with scheduling there’s no doubt you have heard of or used Quartz. I’ve used and seen Quartz used for scheduling in many environments. One thing I noticed was that Quartz was usually deployed in a web-app, I’m not a big fan of that approach. One company had these huge long running intensive jobs bogging down the performance of the app affecting end-users. I like being able to update jobs and triggers in a Web UI but I don’t want the actual Scheduler running there.
I recently have been working on a project and I just got to the point where I needed a scheduler. I tried my hardest to avoid running the Quartz Scheduler directly in my web-app, and these are the 2 solutions I came up with. They’re still not 100% decoupled from my app, but they both provide a way to have the Scheduler running jobs outside of the web-ui.
RESTful Quartz
I really like the idea of a RESTful Scheduler on the Scheduler side, but from the schedulee (or whoever is making the jobs/triggers/etc) side I wasn’t too happy with it. I could sandbox the instance running the RESTful api or I could build an authorization/authentication layer on it as well. For this API I would use the RDBMS Store for jobs/triggers. I created a simple GET/PUT/POST/DELETE api for Jobs and Triggers and in the web UI where I could schedule these I made calls to this API.
Pros
- Robust. You can do a lot within the API or you can do the bare minimum
- Use the RDBMS store. Not as “hacky” as the stand-alone.
Cons
- Felt like more client side code. My App then depended on this scheduler micro-service and I didn’t need the added complexity of API calls in my business layer code.
- Another security layer needed.
Stand-alone scheduling app
The stand-alone app is just a scheduling package I made running a QuartzScheduler. It uses the in-memory job store so the jobs are not resilient. I’m saving these jobs and the details in my DB regardless and my scheduler just sends messages to a queue for later processing. I don’t need to chain jobs right now, I just needed something quick and dirty.
To get this to actually work I setup a @PostConstruct where I create a job which runs every minute to check the database for new jobs and to remove any jobs no longer in the DB. Not as robust as the RESTful API because I’m not relying on all of the Quartz package code for scheduling. It takes some validation to get things right, which you now have to implement yourself.
Pros
- Quick and faster to setup
- Utilizes security layer in the web UI where I schedule and create jobs
Cons
- Less robust. Jobs and triggers get created every time I start and stop the app.
- Need to build (some of) my own validation
Which I chose and why
I had a hard time deciding between the two ways. I went with the stand-alone app only because it was quick and easy to setup. I just now have to plan to work around its limitations or add to the complexity of the stand-alone app by building more on top of it. I will eventually build that RESTful API out but for now I just need to do some very simple scheduling and jobs. I built out the stand-alone app in an afternoon or two, the RESTful API will take a good deal more time not just in building the API but in then making API calls from within my other apps.
UPDATE
I later found out you can just turn off the setAutoStartup method on the SchedulerFactory and only use the JDBC Job Store.
Some Snippets
Here are some code snippets I think would be helpful. Cron validation I spent a good deal of time on, this validator works pretty well for CronTriggers.