Check out Queue::later in the docs, I think that would get you on your way.
Oh wow, I never even knew about that option?! Very pleased in your guidance shansma, I appreciate the help. Enjoy your day :)
Me again, so doing some research on this topic the queue system is perfect for the job. What is puzzling me though is the laravel API.
$date = Carbon::now()->addMinutes(15);
Queue::later($date, 'SendEmail@send', array('message' => $message));
this implies that there should only be a delay, not an exact date? Is it possible to do $date = (12:00 PM every week day)
I was wondering about this as well. I guess you'll have to calculate the exact delay.
It seems that within the fire method of the queue, we would have to calculate each delay depending on what the user specifies in the users settings.
Meaning that we would have to continually create a queue job from within a queue job, then delete the current queue job once the following days queue is pushed into the following line.
I don't like this system =\
It would be nice to specify a queue like :
// pseudo code
$date = (Week Day Only - Time);
Queue::on($date, 'SendEmail@send', array('message' => $message));
Maybe you can run a loop and create all the queues at once? if it's only once a week Carbon's addWeek method will be very useful.
Just thinking aloud here.. or maybe it can't be done, is there a time limit for placing a queue? Is the sendEmail@send method called on the creation or in the execution of the queue?
Good luck!
I don't think there is a time a limit? Says no where in the laravel docs or on beanstalkd FAQ. And to my understanding of how the queues work, the sendEmail@send method is called on the execution of the queue.
Can we get a definite word from some one who has used queues for notifications based off user settings? Or how they've implemented a user based notifications system?
I'm going to start working on this sometime tonight. Gonna try every single hacked up way I can think of to get this to work. I feel like this is a massive feature that a lot of applications could take advantage of.
I was looking for something very similar and found this:
https://github.com/liebig/cron
Basically you set one cron process which runs every minute, and it looks for registered jobs.
You could hook into an event on your user save/update that registers the process.
Check out Carbon's documentation on difference https://github.com/briannesbitt/Carbon#api-difference You can use this feature to calculate the difference in seconds (with diffInSeconds()). Pass that output to the Queue::later function.
In the past I have written a master application cron script which is executed by the system cron every minute, its job is to check the queue for jobs that meet a criteria for being ran now, it then marks those as locked (so that if another cron ticks during its work they dont both do the same job) for a set timeout period and begins forking threads to work through the given job queue until its complete. I ended up writing in a simple algorithm to identify how long certain tasks took on average and increase or decrease the set timeout period for those tasks.
After a while and because we needed something more accurate and instant we wrote a daemon process in PHP which watched for jobs and forked a process to execute each job (to a configured max threads). As a back up we had a cron script run every minute to check that the PHP daemon process hadn't crashed and to restart it if it had. Over 12 months we only had it crash once and it recovered almost immediately.
Thinking about it, it looks like what we ended up writing is similar to the Queue functionality baked into Laravel - although ours was designed around having to process 1000+ items a minute and utilized parallel processing to do so.
So I came up with a way to do it. Following this tutorial : http://fideloper.com/ubuntu-beanstalkd-and-laravel4
I'm going to simply put a users request into the queue for example like so:
Route::get('/queue', function()
{
Queue::push('InterfaceQueue@textMessage');
return 'Inputted into work queue';
});
Then what I do inside the queue is :
public function textMessage($job, $data = null)
{
$cell = \Usercellphone::find(1);
$carrier = \DB::table('cellCarriers')->select('smsAddress')->where('carrierId', '=', $cell->carrierId)->get();
$data['num'] = $cell->carrierId;
$callback = function($message) use ($cell, $carrier)
{
$message->to(\Crypt::decrypt($cell->cellPhoneNum) . '@' . $carrier[0]->smsAddress);
};
if (\Mail::send('OutGoingMessages.Queue.test', $data, $callback))
{
return $job->release('Until the next time the user has chosen');
}
}
The release function is very very useful since it allows for the same job to be redone every time, taking a seconds argument which in turn could be calculated for the next time the user should receive the text message.
I forewarn any one though, be careful with the job release method, I pretty much DOS'd my own cell phone due to receiving so many text messages. The amount was unreal. Other than that hopefully this helps others out there in my shoes.
By the way for test cases (after my self DOS attack on my cell phone) :
return $job->release(60)
received a automated text message every 60 seconds.
Any questions or any further improvements I can make that would be really cool.
Thanks to every one for the help!
awestrope said:
Check also Iron Workers https://www.iron.io/worker
Reinventing the wheel is sometimes a good thing... no?
Thanks for sharing! I'm going to stick with my current set up as everything is locally hosted. I'm building a dashboard for maintaining messages sent and what not. - Much like the Mailgun dashboard.
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community