So a while back I built an app for a company and now they'd like it revised a bit. The basis of the app is an RSVP system for health care Seminars and Consultations. They would now like to send email and text reminders once daily for to all clients whose seminar/consultation is within 24 hours. So I've created the code to pull all the seminars/consultations that occur within 24 hours. I know I will need to set up a CRON job on their server, which is not a big deal, but how would you go about the scheduling? Am I better off creating 2 new commands (one for seminars, one for consultations) and using the $schedule->command('some:newCommand --force)->dailyAt(2:00); in the Kernel.php file, or would you just $schedule->command('queue:work --force)->dailyAt(2:00); . I'm just trying to understand best/most efficient practice.
Just my 2 cents...
use $schedule->job(...) instead
put que:work in a supervised process
The schedule->job will figure out all the messages that need sending and make 1 job per message transmission. So, a job that makes more jobs.
Use the failed_jobs table to track if anyone didn't get the message.
Related
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.
I am using Laravel 5.1, and I have a task that takes around 2 minutes to process, and this task particularly is generating a report...
Now, it is obvious that I can't make the user wait for 2 minutes on the same page where I took user's input, instead I should process this task in the background and notify the user later about task completion...
So, to achieve this, Laravel provides Queues that runs the tasks in background (If I didn't understand wrong), Now for multi-user environment, i.e. if more than one user demands report generation (say there are 4 users), so being the feature named Queues, does it mean that tasks will be performed one after the other (i.e. when 4 users demand for report generation one after other, then 4th user's report will only be generated when report of 3rd user is generated) ??
If Queues completes their tasks one after other, then is there anyway with which tasks are instantly processed in background, on request of user, and user can get notified later when its task is completed??
Queue based architecture is little complicated than that. See the Queue provides you an interface to different messaging implementations like rabbitMQ, beanstalkd.
Now at any point in code you send send message to Queue which in this context is termed as a JOB. Now your queue will have multiple jobs which are ready to get out as in FIFO sequence.
As per your questions, there are worker which listens to queue, they get a job and execute them. It's up to you how many workers you want. If you have one worker your tasks will be executed one after another, more the workers more the parallel processes.
Worker process are started with command line interface of laravel called Artisan. Each process means one worker. You can start multiple workers with supervisor.
Since you know for sure that u r going to send notification to user after around 2 mins, i suggest to use cron job to check whether any report to generate every 2 mins and if there are, you can send notification to user. That check will be a simple one query so don't need to worry about performance that much.
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}.
So I have a mobile app that wants to use parse for login, user data, content, etc... but I also need to run an hourly k-means clustering job on my entire user data set. I was looking at Parse jobs as a possible solution. My question is since the clustering algorithms will probably take up a lot of memory - since they will need to load all the users into memory - will it be possible or useful to use parse for this, or to run map reduce jobs with the the background jobs.... or is this really beyond the means of parse and I should look at setting up my own backend instead of using a backend-as-a-service.
Parse offers background jobs https://parse.com/docs/cloud_code_guide#jobs
As long as the job completes within 15 minutes, it is fine.
However, there is an open bug on Parse that hasn't been fixed over the last 1.5 months. We believe that this is actually a memory issue (and if that's the case you might run into it, as well). Here's the bug ID: https://developers.facebook.com/bugs/1586656868273252/
In a Sinatra app I need to run on a daily basis a job in the background (I will probably use sidekiq for this) for each User of the app.
I'd like to distribute them evenly during the day according to the number of users. So, for instance if there are 12 users the job has to be executed once every two hour and if there are 240 users the job has to be executed every 6 minutes.
I understand there are some gems that allow you to schedule background jobs (Rufus scheduler, Whenever ...), however I'm not sure they allow to change the internal a job must be executed according to dynamic values such as the number of objects in a collection.
Any idea how I can achieve that?
Using whenever, you could get started like this:
In your user model, after a user is added successfully:
every (1440/User.all.count).to_i.minutes do
add your background command task
end
Also don't forget to update the whenever store which actually updates the cron.
system 'bundle exec whenever --update-crontab store'