I hope you guys are doing good, and had a fresh breath. Put your mask again if you find the previous topic smelly, as we are going to finish up the dissection for Akka Quartz Scheduler. I am going to refer the every Quartz-Scheduler things prefixed with java. So when I say Java-Quartz-Scheduler, I mean the the quartz library which is made through java, and which is wrapped by the Akka Quartz Scheduler. And one more thing to noticed is that
QuartzSchedule are different.
Alright, so let’s start then. First let’s revisit some of the parts of Akka-quartz which will help us to do the dissection part easily. If you check the repo, you will find that the class that we interact with is the QuartzSchedulerExtension. First we initialize it and then schedule it. When we initializes it, we have some states(immutable) for itself, then the schedule function is called. So let’s revisit this two parts. It initializes like this –
config – gets the config from the configuration file for the key “akka.quartz”
defaultConfig – hard coded strings parsed for configuration
threadCount – reads from the config(point 1) as Int for the key “threadPool.threadCount”
threadPriority – reads from the config(point 1) as Int for the key “threadPool.daemonThreads”
daemonThreads_? – reads from the config(point 1) as boolean for the key “threadPool.daemonThreads”
defaultTimeZone – reads from the config(point 1) as Timezone for the key “defaultTimeZone”
schedules – builds through the
QuartzSchedules by passing
config(point 1) and
defaultTimezone(point 6) which returns a immutable map of string and
runningJobs – just a declaration of mutable map with String and
threadPool – a
new SimpleThreadPool with the help of
threadPriority(point 4) and
jobStore – a
scheduler – here a lot of stuffs happen. It loads the java-Quartz-Scheduler using scheduler name, system name(from the Akka system passed to the
threadPool(Point 9) and
jobStore(point 10). Then it creates a scheduler from the java-Quartz’s
DirectSchedulerFactory. Using this scheduler object, the schedule jobs are being shutted down by calling shutdown function, which is hooked into
registerOnTermination of Akka system. Then finally the scheduler is being returned.
After this declarations comes the schedule function of
QuartzScheduleExtension, where it receives the schedule name, actor reference, the message which will be needed to send to the actor and the
QuartzSchedule object fetches from the schedules(point 7). In this function for the right case it sends the parameters to
scheduleJob function. In the scheduleJob function it does the following tasks.
F1. creates a
jobDataMap having key value types as String and
logBus, receiver which is the
ActoRef passed to it and the message which is again passed to it.
F2. creates a java-Quartz
JobDataMap object through java-Quartz
JobDataMapSupport object by converting scala
jobDataMap to java
jobDataMap and stored it in val called
F3. creates a java-Quartz Job through the
SimpleActorMessageJob and description from schedule(
QuartzSchedule) and stored it in a val called job
F4. add a key value pair in the
runningJobs(point 8) of key name(from the parameter) and key from the
F5. creates a trigger from the
schedule(QuartzSchedule object passed to the function) by calling
F6. schedule the the job using the job(point F3) and trigger(point F5) using the scheduler(point 11)
You must have noticed by now that we have these terms which we need to dissect
And of course the java terms which needs that came up like
Trigger. Well let’s first see how java quartz scheduler works and don’t worry we’re not going deep down into java quartz library. We need this stuffs to understand java Quartz scheduler – The
Scheduler, Job, jobDataMap and trigger.
In short a Scheduler schedules a job with the help of
jobMapData and run when it’s being triggered. Job has a method called execute which takes the
JobExecutionContext from where we can fetch the
jobDataMap. So now the question is how Akka-Quartz-Scheduler wraps them? Well if you go through the points F1 to F6 you would have already know, how it works. At point F2 it creates the
SimpleActorMessageJob is the job, at F5 it creates the Trigger through the scheduler and at F6 . So the answer is Job is wrapped by
SimpleActorMessageJob, Trigger is wrapped by
jobDataMap is created by java-
JobDataMapSupport from the values
jobData at (point F2). By now I hope you have fair idea how the scheduler(point 11) and
jobDataMap (point F2) are being created. So what we have dissect now is the Job that is
SimpleActorMessageJob and the Trigger i.e.
Let’s first go through
SimpleActorMessageJob as it is shorter than
QuartzSchdule to explain :P.
SimpleActionMessageJob extends java-Quartz’s Job, and when you extends a Job you have to override the execute function. The execute function takes
JobExecutionContext as parameter and through this
JobExecutionContext we can fetch the
jobDataMap which in our case is sent from the
QuartzSchedulerExtentsion (point F2). So basically this class has three functions
getAs is not being used anywhere :\. However as function is used inside the execute function to convert the objects get from
jobDataMap. So the only question is what happens inside the execute method. And the answer is simple it gets the actorRef from the jobDataMap through the key receiver, the message through the key message the
logBus to logs the stuffs through the key
logBus(point F1). and then it just use the Akka’s tell function to send the message to the actor
receiver ! msg.
Okay, so next thing left is
QuartzSchedule. Well when we find the
QuartzSchedule we find two more things
QuartzSchedules(which we have named earlier) and
QuartzSchedule is sealed trait in the QuartzSchedules.scala file.
QuartzCronSchedule implements it and
QuartzSchedules creates the instances of
Well it goes like this. If you see point 7 in the declaration, you will find that it sends
QuartzSchedules to get a map of
QuartzSchedule. Below are the tasks done through the
QS1. In the apply function get the ConfigObject for “schedules”, and pass it to
parseSchedule with name. Here the name is the key.
parseSchedule fetch the
timeZone using the key
description and sends it to
QS3. In the
parseCronSchedule it fetch the cron expression for the key
QuartzCronSchedule and returns.
QuartzCronSchedule extends the
QuartzSchedule and takes parameters
name, description, expression timezone and calendar(points QS1 to QS3). it declares an object called schedule which creates a
CronScheduleBuilder using expression and timezone. Where in
QuartzSchedule there are declaration for
name, description, schedule, calendar and an implemented function
buildTrigger, which creates a java-Quartz’s
TriggerBuilder using name, description and schedule. And here schedule is override in
CronScheduleBuilder.So if you revisit points F1 to F6 you will find that all these
QuartzCronSchedule are being called there. It would be wrong to say that Akka-Quartz-Scheduler works like the below diagram, but just to make similarity with java-Quartz it looks like this.
Now you may unmask and tell me if you like it ;).