Reputation: 79
I'm looking for frameworks to schedule a set of tasks populated in the Database
JPA entities look like this
@Entity
class Task extends Model {
@NotNull
@Min(1L)
@Column(name = "interval_ms", nullable = false)
Integer interval
@NotNull
String payload
@NotNull
Boolean enabled
}
@Entity
class TaskResult extends Model {
@ManyToOne(optional = false)
Task task
@Column(nullable = false)
Boolean result
@Column(nullable = false)
String message
}
tasks should be executed every interval defined in the "interval" field, result should be written into TaskResult table
The purpose of task is to make a GET or POST request, so requests have to be pooled to avoid the situation when a lot of tasks start to execute in parallel.
I'm using spring boot.
what are best practices here?
Upvotes: 3
Views: 13518
Reputation: 71
If you are using Spring Boot, you can use TaskExecutor bean and configure pool size http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-task-executor-usage Then use TaskScheduler to define, when the task should run. Event values for this parameter comes from database (ie. Object).
Once I created scheduler but I used Quartz. I created newJob's, which was triggered every 1 minute (but you can use also miliseconds) and searched EmailQueue in database, if email was found, it tries to send it, when error occured with sending, he do not delete email in the queue and writes into the LOG table details about an error. The scheduler (1 minute) was set up from database. In your case you should use: newJob(QuartzJob.class).withIntervalInMilliseconds
@Service
public class MyQuartz implements InitializingBean, DisposableBean {
@Autowired
StdSchedulerFactory stdSchedulerFactory;
@Autowired
TableConfiguration tableConfiguration;
Scheduler sched = null;
JobDetail job, job2;
JobDetail[] jobs = new JobDetail[2];
public void initIt() throws Exception {
try {
System.out.println("Shedulling a job...");
sched = stdSchedulerFactory.getScheduler();
} catch (SchedulerException e) {
System.err.println("Could not create scheduler.");
e.printStackTrace();
}
try {
System.out.println("Starting scheduler");
sched.start();
} catch (SchedulerException e) {
System.err.println("Could not start scheduler.");
e.printStackTrace();
}
// define the job and tie it to our QuartzJob class
job = newJob(QuartzJob.class).withIdentity("myJob", "group1").build();
job2 = newJob(QuartzCronJob.class).withIdentity("myCronJob", "group2")
.build();
jobs[0] = job;
// .. here I have more jobs ...
// Trigger the job to run now, and then every 5 minutes
Trigger trigger = newTrigger()
.withIdentity("myTrigger", "group1")
.startNow()
.withSchedule(
simpleSchedule().withIntervalInMinutes(
tableConfiguration.getTimeInterval())
.repeatForever()).build();
// ... more triggers also here
// Tell quartz to schedule the job using our trigger
try {
sched.scheduleJob(job, trigger);
System.out.println("..job schedulled.");
} catch (SchedulerException e) {
System.err.println("Could not schedulle a job.");
e.printStackTrace();
}
}
@Override
public void destroy() throws Exception {
try {
System.out.println("Stopping scheduler...");
for (int i = 0; i < jobs.length; i++) { // Destroying all jobs
sched.deleteJob(jobs[i].getKey());
}
sched.shutdown(true); // Waiting for jobs to complete.
System.out.println("...scheduler Terminated. Good Bye.");
} catch (SchedulerException e) {
System.err.println("ERROR, scheduler cannot be stopped.");
e.printStackTrace();
}
}
@Override
public void afterPropertiesSet() throws Exception {
}
}
and
@Service
@Transactional
public class QuartzCronJob implements Job {
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar = new GregorianCalendar();
String schedulled = sdf.format(calendar.getTime());
System.out.println("LIST now " + schedulled);
List<EmailQueue> emails = emailQueueDao.findAllForToday(schedulled);
if (emails != null) {
for (EmailQueue email : emails) {
// Send email:
try {
sendmail.sendNotification(email.getFrom(), email.getTo(),
email.getSubject(), email.getMessage(), "Sched.");
// Delete email from queue:
emailQueueDao.delete(email.getId());
System.out.println("Email sucessfully sent and deleted.");
} catch (Exception e) {
sendmail.logEmail(LoggerSeverity.ERROR,
"Could not send schedulled email", "Sched.");
System.err.println("Could not send schedulled email");
}
}
}
// ... more code here, this is just a working sample...
}
}
My code is not using pooling, but I did not retrieved more than 3 emails from database as it run once per minute :)
Upvotes: 5