Scheduler Programs in Java and NodeJs
Scheduler architecture and programs are very useful features when it comes to the business needs of an organization. There will be some scenarios need to execute tasks at some point of time or periodically without any manual triggering or interaction. This is where these schedulers come into action.
Some practical scenarios
- When you need to archive local log files and move them to a separate location.
- When you need to extract data from 3rd party API and save that in your on-premise database by validating them on a special date or periodically.
- When you need to read sales records and do some analysis of the progress of the business once a month.
- When you need to remove user details who were inactive for 60 days from your e-commerce database due to storage capacity constraints.
- When you need to retry the process again of the failed data in your database, and that cannot be done manually everytime.
- You are the Agent 47 and you need to send your current location to the government agency at the rate of every 2 minutes from your mobile phone.
What is happening in a scheduler program
Actually, in a scheduler program, we write the piece of code as a function that we need to run in a scheduling way. then we set the time or rate or delay for this function that needs to be executed.
If it is java, then the main thread will keep track of that time and duration and when the right time comes, the relevant function will be executed in a different thread. Then after the execution that thread will be closed.
If it is NodeJs, timers will be used to achieve that because NodeJs is single-threaded. So the timer will create an event, and when the time expires, then that event will be put into the event loop. After that, function will be executed by the call stack.
There are three types of schedulers.
Fixed Rate
In this case, the scheduler function will be executed at every ‘n’ milliseconds that we define. next execution will be executed regardless of whether the previous execution is finished or not.
Fixed Delay
In this case, the scheduler function will be executed ‘n’ milliseconds after the previous scheduler finishes the execution.
Cron Expression
In this case, the cron expression will determine the exact time and date that the next execution should happen of a scheduler function. as an example when we need to execute a function every two seconds we need to use */2 * * * * *
cron expression. to learn more please look at this doc
https://www.baeldung.com/cron-expressions
Scheduling in Springboot
There are several methods to run schedulers in java, but here I will be discussing the schedulers using Sprinboot, because it is a robust, organized, and widely used java framework, and also it supports cron expressions.
- First, add Sprinboot web dependency to the application
- Then annotate the main class with
@EnableScheduling
annotation and if schedulers needed to be run asynchronously add@EnableAsync
annotation as well
@SpringBootApplication
@EnableScheduling
@EnableAsync
@Slf4j
public class Test1 {
public static void main(String[] args) {
SpringApplication.run(Test1.class, args);
log.info("this is main thread with threadId: {}", Thread.currentThread().getId());
}
}
- Then create a separate class with the schedule function and annotate that function with
@Scheduled()
with@Async
@Component
@Slf4j
public class ScheduledTask {
@Scheduled(fixedRate = 2000)
@Async
public void runScheduled(){
log.info("scheduled task invoked with threadId: {}", Thread.currentThread().getId());
}
}
@Component
@Slf4j
public class ScheduledTask {
@Scheduled(fixedDelay = 2000)
@Async
public void runScheduled(){
log.info("scheduled task invoked with threadId: {}", Thread.currentThread().getId());
}
}
@Component
@Slf4j
public class ScheduledTask {
@Scheduled(cron = "*/2 * * * * *")
@Async
public void runScheduled(){
log.info("scheduled task invoked with threadId: {}", Thread.currentThread().getId());
}
}
- For
fixedDelay
andfixedRate
schedulers extra param calledtimeUnit
can be used to specify the time unit that needs to consider for delay and rate values
@Component
@Slf4j
public class ScheduledTask {
@Scheduled(fixedRate = 2, timeUnit = TimeUnit.SECONDS)
@Async
public void runScheduled(){
log.info("scheduled task invoked with threadId: {}", Thread.currentThread().getId());
}
}
- We can configure and define the Threadpool that will be used for schedulers using the following bean. As I told earlier java will create another thread to run the shceduler, so we can define the pool of threads that should be used to run the schedulers as we need and also give them prefix.
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(5);
threadPoolTaskScheduler.setThreadNamePrefix("Schedule Task");
return threadPoolTaskScheduler;
}
Scheduling in NodeJs
In NodeJs it is super easy to create schedulers. Here I will be using the node-cron npm package and it will support cron expressions only.
- First, node-cron needs to be installed.
npm i node-schedule
- Then create a Nodejs project and in the index.js file following code needs to be added
const schedule = require("node-schedule")
const job = schedule.scheduleJob('*/2 * * * * *', () => {
console.log("Running in scheduler")
})
That is all you need to do in Nodejs. super easy than java.
When to use Java scheduling
- If the schedulers need to be executed by
fixedRate
orfixedDelay
and ok to be executed by cron expression. - If scheduled tasks are computation-heavy tasks and need to be run on a multithreaded environment asynchronously without blocking the scheduling. (Keep in mind creating system threads is expensive compared to a single-threaded environment)
- If you are more experienced and comfortable with Java.
When to use NodeJs scheduling
- If schedulers do not necessarily need to be executed by
fixedRate
orfixedDelay
and ok to be executed by cron expression. - If scheduled tasks have more I/O operations than computation-heavy tasks. Because NodeJs is single-threaded and if it encounters a computation-heavy task it will block the Eventloop.
- If you are more experienced and comfortable with NodeJs.
Schedulers with AWS Cloud
Instead of creating scheduler programs, AWS has provided us a good environment to run schedulers using AWS lambda and AWS eventbridge. We can create a lambda function and that can be triggered by AWS eventbridge with the scheduled events. In here I am not going to discuss about that architecture but will explain on another article. Instead of that we must know when to use schedulers over AWS eventbridge events.
It is good to use Schedulers over AWS Eventbridge…
- If the execution time of scheduler function is more than 15 mins (Because lambda function won’t run more than 15mins)
- If the shceduler will invoke 3rd party apis or database queries that take more than 15 mins to complete.
- If you don’t have any dynamic data to be passed to the scheduler function like current time etc. (If you have a scheduler that will depend on dynamic data, you have to use AWS eventbridge to send that data with the event)
- Apart from time, if your scheduler doesn’t need to be triggered by external events, like AWS RDS database events, AWS SQS events, AWS Api gateway events, etc.