I use appengine (java) as a backend for a mobile app (android). The user of my app can create public events consisting of a title and a date/time. Those events are stored on my appengine backend. Any user can subscribe for events and will receive a push notification at that time the events starts.
So I want to schedule a job / task on appengine to run at the events date/time to send a push notification to all subscribers.
Example:
User A creates an event that will start on Saturday next week on 8 pm. User B and User B subscribe for this event.
On Saturday 8 pm a job/task should start to send the push notifications to User B and User C to inform that the event has started.
My question is:
How do I implement something like this in an efficient way on appengine? I want to say, start a Task for the Event on Saturday at 8 pm. There are Cronjobs and TaskQueues. Cronjobs can not be created programmatically. TaskQueue needs to be pulled and can not be scheduled to pull at a given date / time, right?
So the only solutions I see is to create a cronjob that will run every minute to check if there is a Event that starts right now.
An event can be created at any time and any day in the week. However the most events are created for the weekend and There are days when no event has been created for. So running a cronjob periodically ever minute is very inefficient. Im looking for a smarter solution, any ideas?
Indeed, based on your description, the solution is to create a cron job that checks for new events that start right now.
However, you should be careful not to exceed the 60 second window you have for each cron job. If you have a lot of events, you probably should move the actual processing from the cron job to background tasks using Push Task Queues.
You may take a look to this post for a combination of cron jobs and Task Queues.
Related
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
I have an server and a table my current timed Jobs are started in a class where I have different methodes annotated with the #Schedule annotation.
Now I have another form of timed jobs where different requests should be sent to a service in definable time interval. So the user is able to choose something like every 5 minutes or every hour or daily. I will make a list of valid intervals so that there won't be values like every 38 minutes.
So this new timer has to look into the table in whitch interval a job has to be done and then call the function to get the data from the service.
Is this possible without making a new column for something like "Next run"? and what about timers that run at the same time like a 5 Minute a hourly and a dayly timer run all at once once in a day.
Rather than adding a "Next Run" column, I would add a new table that logs when each job was run. That way when your service worker runs it can check the configured run-interval to the last run-time.
I have a TimerTask that updates a few tables everyday at specific times(not one task per day, different tasks at different times in a day). I get a few time periods from a database and check if the current time is equal to one of the times in the database when the run() of TimerTask is called and perform the respective task for respective time(time from database which is equal to current time)
I think it's not working for the next day because I set the time(which I obtain from database) for the timer when the service starts. The next day when the timer is supposed to do the task and checks with the current time it checks with the previous day's time(the day service is started and time is set for TimerTask) and does not do the task. I should start the Service everyday to set the time(which is obtained from database to check with current time).
How do I start the service everyday at specific time so that the time to be checked with current time is set everyday.
I can try to schedule to do the tasks everyday 24 hours from the day service is started, but sometimes I have to change the start date and for that the service should be started again and I dont know if a service will run for 24 hours.
You should use Alarmanager for this. The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running.
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.
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.