trigger some event with message on specific time - events

How can I trigger some event at a specific time with some message?
Example: Someone scheduled a "Happy birthday" message on his friend's birthday at 12:00 am. So this birthday event should be triggered with a "Happy birthday" message on his birthday at 12:00 am.
The only solution I can come up with about how this work is a cron job that runs every min and checks the expired time and triggers that event.
But if we have a lot of events then querying every minute is not a good idea and it gives 1 minute error also.
So can we use any services like apache Kafka (but it does not schedule events at some specific time) to trigger events?

It seems like you want to create a distributed and fault tolerant job scheduler. Below are a few interesting reads over the web
https://leetcode.com/discuss/general-discussion/1082786/System-Design%3A-Designing-a-distributed-Job-Scheduler-or-Many-interesting-concepts-to-learn
https://towardsdatascience.com/ace-the-system-design-interview-job-scheduling-system-b25693817950

Related

Use gocron scheduler to schedule job on specific day at specific time

I want to schedule a job on a specific day at a specific time with some interval. I am using gocron scheduler for this. But I can't find a way to start a job on specific day. e.g. I want to execute a job on 7 Sept 2019 at 330pm. From 7 Sept, I want that job to be executed daily or weekly. How can I do that using gocron. or Any other packages available?
I tried passing UTC time to gocron.At() but its panics as it's expecting only "03:30" time formats and doesn't expect date.
When looking at the documentation for gocron, it does not seem to be designed to support scheduling things for specific days. It seems to be designed as a way to schedule things to run at various intervals, very similar to what the original cron utility was designed to do. So you would specify "I want this function to get called every 2 hours" or "I want this function to get called every Sunday at 3PM". There does not seem to be any documentation about starting jobs from a specific day.
The mentioned At(string) method is documented as allowing you to specify a time of day to run something. So you would use that to set that your job runs at 3:30PM.
If you wish to specify a start time, you would likely need to find another scheduling library or implement it yourself by creating a goroutine that sleeps until a specific time. The StackOverflow post mentioned by domcyrus looks like an excellent resource for implementing it yourself as well as listing some other scheduling libraries.

Cron vs queued task

My application has an Order model with an execution_datetime attribute. I'd like to send some distinct notifications. For example
execution_datetime minus 12 hours: email to carrier
execution_datetime minus 3 hours: sms to customer
execution_datetime plus 1 hour: email to customer
The above timings are not strict and can be approximated; slight deviations are acceptable. Also, the execution_datetime can change in the meantime...
I'm unsure whether to use cron or queued tasks for this. Some thoughts of my own:
Cron:
Business logic will need to be written to fetch applicable orders and execute accordingly
Is execution guaranteed? Should some sort of database flag be implemented to indicate a notification has been sent, and then perhaps fetch all due orders that are unflagged as some sort of failsafe?
Queued tasks:
Task is scheduled on creation of the order? If so, suppose the execution time is changed. How to modify the scheduled task? You'd need to somewhere keep track of the task ID?
Or perhaps a cron job that mass schedules applicable tasks every day?
I look forward to your suggestions.
Great question! I am interested in this discussion.Let me chip in with a scenario from my personal experience.
In my application, I have a Listing model and they have a promotion_ends_at column. Obviously, the listing promotion ends sometimes in the future.
So, like you also mentioned, there are two ways to do this.
When the listing is created, I could queue a job that will end the promotion on the listing in the future). The delay of that job would be the time the promotion has to end (and that could me months away).
I could also have a cron job that runs regularly that manages listings that their promotions should end on a specific date.
We were using SQS as our queue service and since the maximum delay on SQS is 15 mins, option 1 was not feasible. We, then, moved to Redis where we could queue delayed jobs with a long delay easily.
However, like you also said, the promotion_ends_at column could be updated during that time. So, either, you would have to keep track of the job to de-queue it or you could re-check whether the job should still run when it is about to execute.
For example, you could fresh() the model and check whether your condition is still valid. In my case, I would fresh my Listing and check if the promotion_ends_at is in the past. However, this means that we would have a lot of stale jobs that would probably be discarded anyway.
We finally went with a simple cron job that mass schedules the job on the day that they need to be run. I also think that running delayed jobs is a business logic and maybe the queue shouldn't be held responsible for running jobs delayed far too much in the future.

jBPM 6.2.0 send recurring Task reminder after 1 day time interval if the task is not complete

I am new to jBPM. I am working on jBPM version 6.2.0. I want to perform following tasks.
Send reminder email to user / group.
Remind the user again after 1 business day if the task is not yet complete. Continue to send reminder everyday untill the task is done.
Also what happens if jboss / tomcat server restarts after sending one reminder email. Will the later emails still schedule ?
I am able to add Deadlines (Escalation- Notification) But it runs once and sends only 1 email. I need to keep reminding the user on a daily basis (or hourly) to complete the task.
I tried looking in jBPM 6 user guide but it does not have clarity about Boundary timer events and intermediate catch time events. And when i use any of them then it runs once.
Any help is much appreciated.
Here is an example of something that I did recently for sending periodic emails.
This should loop until a user finally completes the task. You might have trouble with the one business day rule since I do not know if the ISO 8601 spec is flexible enough to know about weekends/holidays/business days. You could add that logic into your service task for sending the email.
Be aware that this loop will continue forever until the task is complete. You might want to consider adding some additional timeout. You could add a loop count so after X amount of times the process will be cancelled. Some of my processes have a rule that if the process is not complete in Y days, the process should be cancelled. I accomplished that by have a process variable CancelDate and set a Timer Event definition to Date/Time and the value #{CancelDate}.

Recurring Toasts with Windows 8.1 Store Apps build with JS

I've been trying to create notifications that happen on a weekly basis - for example, every monday at 8am.
I've tried to use a recurring toast for this - http://msdn.microsoft.com/en-us/library/windows/apps/hh465417.aspx - but realized that the recurrence parameters are more designed for a snooze functionality, with a maximum delay of 60 minutes, and a maximum repeat for 3 times.
Is there a suggested workaround for this?
Is there a best practice for such a use case?
Thanks!
You're right that the recurrence on scheduled toasts is designed for snooze. Unfortunately, the API doesn't provide a way to show the same toast multiple times on a fixed schedule.
You'll need to manually create a ScheduledToastNotification each time you want it to be shown. In your example, you might create and schedule out a toast a week for each Monday at 8 AM.

Testing Quartz JDBC Job Store

I am using Quartz JDBC Job store (org.quartz.impl.jdbcjobstore.JobStoreTX) and MySQL for scheduling jobs.
I have the following setup:
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource=foo
org.quartz.dataSource.foo.driver=com.mysql.jdbc.Driver
org.quartz.dataSource.foo.URL=jdbc:mysql://localhost:3306/myDB
org.quartz.dataSource.foo.user=user
org.quartz.dataSource.foo.password=*****
org.quartz.dataSource.foo.maxConnections=5
org.quartz.dataSource.foo.validateOnCheckout=true
org.quartz.dataSource.foo.validationQuery=SELECT 1
I am able to schedule a job with Quartz picking up the job from the database when the time is due.
There are some jobs that can be scheduled up to 3 or 4 weeks in the future. How do I test this?
Right now I go manually change the system time. For example, if I schedule a job to run on 2/5/2013 12:45 PM, then I go change the system clock time to 2/5/2013 12:43 PM, then wait for a couple of minutes to see if Quartz picks up the job from the DB. This works fine for me.
I don't want to change the system clock time every time I need to test. Is there a better way to do this?
I noticed that changing the system time frequently sometimes messes up with Quartz with some jobs not picked up.
You could use the Quartz TriggerUtils methods to find out whether the future executions are the expected.
More specifically the computeFireTimes(org.quartz.spi.OperableTrigger trigg, Calendar cal, int numTimes) method returns a list of Dates that are the next fire times of a Trigger.
I hope this helps.

Resources