I'm writing a PHP project in Laravel. The admin can queue email alerts to be sent at a specific date/time. The natural choice was to use Laravel's Queue class with Beanstalkd (Laravel uses Pheanstalk internally).
However, the admin can choose to reschedule or delete email alerts that have not yet been sent. I could not find a way yet to delete a specific task so that I can insert a new one with the new timing.
What is the usual technique to accomplish something like this? I'm open to other ideas as well. I don't want to use CRON since the volumes of these emails would be pretty high, and I'd rather reuse an already tested solution for managing a task queue.
I have scoured the internet for such an answer myself.
Here's what I've found:
I think the simplest way within Beantalkd is to use its ability to delay a job (giving it a number of seconds to delay as an argument).
You can then do date math to capture the difference in time between now()
and when the job ideally is run (in seconds) and delay the job that long.
Here's an example (see first answer to that SO question - it's in Python, but you can get the gist of what the person is saying/doing)
Note that this doesn't guarantee the task is run on time - the delay just make the job available after X seconds. How behind your queue is on processing tasks when the delayed job becomes available determines when the job is run in reality. (If you're queue is behind due to heavy number of jobs, then it won't necessarily run exactly on time!)
Laravel's Queue has a later method, which you can use instead of push
Where as with Push, you'd do:
Queue::push('Some\Processing\Class', array('data' => $data));
with later()
, you'd do:
$delay = 14400; // 4 hours in seconds
Queue::later($delay, 'Some\Processing\Class', array('data' => $data));