Quartz trigger creation in large numbers - java

Our project is in airline domain and our system is managing the flights for an airline. The system get the flight details from external source as messages and we will always have flights up to 90 days in future in our DB.
We have a requirement to send a message to external system, X minutes before the departure time of a flight. For example 90 minutes before the departure of a flight, a message need to sent to external system. This need to happen for all the flight for a day.
We are planning to implement the solution like when a flight message comes into our system , we will create a quartz trigger for that flight to send the message 90 minutes before its departure time.
But the problem we are facing is there will be more than 300 flights in a day. That means at least 300 triggers are created in system for a single day and we think it will lead to any performance bottlenecks in the scheduler system.
Please suggest if there is any better alternate for this solution. Whether we can achieve it by just one trigger which will query database in frequent intervals and do the complex logic of sending flight message for all flights which satisfy the condition.

I found a way to solve the issue and posting it here so that somebody else can benefit from it.
Creating large number of quartz triggers is not at all a good idea and we resolved the issue just with two jobs.
The first job will run daily once at midnight and it will find all the flights for that day and calculate its message sending time. This information is written to a table.
Another job is created that runs every five minutes and read the table and see if any message need sent for for the current time and also any failed ones in previous attempt. Then it will send the message and update the status accordingly.

Related

How Can I Trigger An Action 30 Days After A Date?

I have a requirement to update a field if a payment date is 30 days late.
Is it possible to trigger an action to occur 30 days after the payment date?
The process is likely to restart in-between those times so it can't be in-memory and it can't be a relative date.
I can create an endpoint like /api/paymentdates so that it could be called from something else like cron.
However, there are likely to be a over a million items at some point in the future, each with its own date.
Is there an effective way to trigger a task like this or is the only option to run a task every morning and query the database?
You can make use of a Queue Triggered Function (Storage Queue or Service Bus Queue). Basically what you will do is put a message in a queue and keep it invisible for 30 days (it is called initial visibility timeout in storage queue and scheduled message in service bus queue).
The message will only appear in the queue after its invisibility expires and the Function will be triggered at that time. Once the Function is triggered, you can do whatever processing you want to do on that message.
You may find following links useful:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-queue
https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus

Creating Amazon SNS messages to be processed in the future

For the last few years we have used our own RM Application to process events related to our applications. This works by polling a database table every few minutes, looking for any rows that have a due date before now, and have not been processed yet.
We are currently making the transition to SNS, with SQS Worker tiers processing them. The problem with this approach is that we can't future date our messages. Our applications sometimes have events that we don't want to process until a week later.
Are there any design approaches, alternative services, clever tricks we could employ that would allow us to do achieve this?
One solution would be to keep our existing application running, at a simplified level, so all it does is send the SNS notifications when they are due, but the aim of this project is to try and do away with our existing app.
The database approach would be the wisest, being careful that each row is only processed once.
Amazon Simple Notification Service (SNS) is designed to send notifications immediately. There is no functionality for a delayed send (although some notification types are retried if they fail).
Amazon Simple Queue Service (SQS) does have a delay feature, but only up to 15 minutes -- this is useful if you need to do some work before the message is processed, such as copying related data to Amazon S3.
Given that your requirement is to wait until some future arbitrary time (effectively like a scheduling system), you could either start a process and tell it to sleep for a certain amount of time (a bad idea in case systems are restarted), or continue your approach of polling from a database.
If all jobs are scheduled for a distant future (eg at least one hour away), you theoretically only need to poll the database once an hour to retrieve the earliest scheduled time.
A week might be too long as SQS message retention itself is only 15 days. If you are okay with maximum retention of 15days, one idea is to keep the changing the visibility of a message every time you receive until it is ready for processing. The maximum allowed visibility timeout is 12 hours. More on visibility timeout and APIs for changing them,
http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ChangeMessageVisibility.html
http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/AboutVT.html
I found this approach: https://github.com/alestic/aws-sns-delayed. Basically, you can use a step function with a wait step in there

Generate reports in background and by schedule using Spring

There are 2 ways user can generate a report.
User click a button on the front end and job will run to generate the report.
User can schedule the report to generate weekly, monthly, etc.
On scenario 1, I decided to first save the request to a table, say "REQUEST_TBL". Right after that, I will run ThreadPoolTaskExecutor which picks up the specific request from "REQUEST_TBL". There could be a lot of users that can request to generate a report. But each user is given only up to 30 reports to generate for life (if user wants to generate a new report, he needs to delete any old reports).
On scenario 2, user can schedule a certain report to generate weekly, or monthly. Then a weekly (or monthly or etc) job will run and generate this report that the user scheduled.
Now, I am not sure on how to implement the report generator job. Whether I use ThreadPoolTaskExecutor or not. Or use the same program to handle user request and user scheduled request for report.
I am planning to let one job to run every minute to read "REQUEST_TBL" and for each record I will run ThreadPoolTaskExecutor.execute(). But if there are 1000 users all the same time they requested report, then how should I implement the creation of thread. Also for the scheduled job, I am planning to run it endofday only. The scheduled job will read from the same "REQUEST_TBL" and look for request that is scheduled. For scenario 1, if I want to run a job for every, say, 2 minutes, until what time should I run it? Cause it may be that at the end of that day, a scheduled report will need to run. Also, I thought of running a job for every, say 2 minutes, because if the server went down, there's no way to regenerate the report once the server is started.
I would appreciate your suggestion
You are asking many question at once. So few thoughts here:
definitely don't create thread yoursels. Use rather one of the Executors and limit the number of threads in this way.
for the rest I'll do it in the most consistent way: every record in REQUEST_TBL will also have time when it needs to be generated. So in scenario 1 you will save current time together with the request. With the scenario 2 you'll create a record(s) with timestamp which is week (months) ahead.
then you can run a job every minute or two to query requests with request time before or equal now. And schedule a job to the executor for each returned record.

A way to have a task run according to a given schedule

I'm about to create a small application which will be responsible for sending out various reports to various users at various intevals. We might be talking about 50 or 100 different reports going to different people. Some reports needs to be generated every day, some every week, and some every month.
I've been using the Quartz library earlier to run tasks at regular intervals. However, in order to keep things simple I like the thought of having a single Quartz thread taking care of all reports. That is, the thread should loop through all reports, say every 15 minutes, and determine wether it is time for one or more to be generated and sent. It does not matter if a report is generated at 12:00 or 12:15.
I'm thinking about wether it would be possible, somehow, for each report to set up specific times such as "mon#12:00,wed#12:00" or "fri#09:30". Then, based on that, the thread would determine if it was time to send a report or not.
My question is; has anyone else done something like this and does any libraries exist which can make it easy to implement this task?
why not simply register a separate quartz task instance for each report and let Quartz handle all the scheduling for you? That is after all the point behind it.
you can create just single thread and it would ping a "job schedule data structure" at some time interval to see if it needs to run a report. If yes, it would run the report, otherwise, it would go for a short nap and ping again after specified sleep time.
It will cause problem if one job takes too much time to complete and you start accumulating jobs.
The job schedule data structure would keep its record sorted by time stamp.

Implementing notification in webapp

We are developing and web application which allows users to register for certain events. What application is supposed to do, is to send them few notifications to remind them that they have registered. There will be more than 1k user which can register for many events in very wide time range. We have to send notofications like 3 months, 1 month, 1 week and one day before event.
The first thing is that I have to determine if I need to send notification to a specific user.
I'm thinking about thread which will iterate over registrations and determine whether sending notification is required or not. If notification is required, should I do it right away or maybe put all of the objects that need it in some kind of cache and then send them (by another thread)?
Second thing is: if I made that thread - is better to put it and run next to application or embed that thread into application and, for example, start it in the context listener?
How You would solve this? Maybe there are better approaches?
I would not spawn my own threads for that, I would use a scheduler like Quartz and run daily or hourly jobs (I don't know what granularity you need) that would:
find upcoming events in 1 day, 1 week, 1 month, 3 months and users that should get notified about them.
create the notifications and send them
I would probably implement that using separate jobs (sending notifications is a different concern) and thus queue the results of the first part, this will give you more flexibility. And the first part could be done by a unique job scheduled with different time frame parameters (1 day, 1 week, 1 month, 3 months).
Tabling the question about how to schedule the notifications once they're identified, I'd recommend looping over upcoming events, instead of over all users. It seems very likely that you'll have many more users than events (especially if you limit your scan to events that happen exactly 1 week, 1 month and 3 months in the future).
As far as the notifications, I think marking notifications to be sent first, then processing all the marked notifications will allow for more optimization than sending out notifications as part of your scan. If you have a queue of notifications to be sent out, you could then send each affected user one email including multiple events in the same time.

Categories

Resources