Laravel has Task Scheduling where events, job and commands can be scheduled. I just can't figure out where does it store them? It doesn't look like it stores it in database
Your batch jobs can be stored in a database table, then use the scheduler to execute it.
The function below can be put in app/console/Kernel.php
$schedule->call(function () {
//put your logic here e.g. send verification code to newly
//registered users at 10 pm
})->dailyAt('22:00');
To execute the scheduler, you must specify the name of the command:
protected $commands = [
send:email
];
Then you would call it in terminal as php artisan send:email and keep the terminal process running.
Or you can setup a cron job
Related
I've built a Laravel system that schedules an artisan command to run daily at a specific time based off of a variable which is set in the .env file. This is because we need to set differing times for each installation of this syten.
.env
DEBTOR_EMAIL_TIME="12:30"
Kernel.php
protected function schedule(Schedule $schedule)
{
$schedule->command('commandt:make --email=test#test.com')->dailyAt(env('DEBTOR_EMAIL_TIME'));
}
If I hard-code a time into the dailyAt() method, the scheduler will either tell me there a no jobs queued to run or the job runs at the specified time.
When I use a variable, I get no output.
What could I be doing wrong?
In my app/Console/Kernel.php, I have set my code as
protected function schedule(Schedule $schedule)
{
$schedule->job(new Refresher);
}
When I run the php artisan schedule:run command, I get the No scheduled commands are ready to run. message. I'm not sure if I am missing out on anything, I have tried adding the ->everyMinute(), but it still does not work.
Your code is creating a queued job. The queue should run on its own. However if you want to start the queue on your own use the command:
php artisan queue:work --stop-when-empty
Queued job, like scheduled tasks, should have a frequency option chained after the job method. Add it to your code:
protected function schedule(Schedule $schedule)
{
$schedule->job(new Refresher)->everyMinute();
}
Note: the Refresher class must respect a specific class structure.You can find it in the Laravel docs https://laravel.com/docs/5.8/queues#class-structure ( I don't know the Laravel version you're working on so i posted the 5.8 docs. Just change the version to the one you're using in the URL)
If you need to create a simple task you can simply change the code to:
$schedule->call(new Refresher)->everyMinute();
I'm looking for a sustainable solution to fetch data every x seconds (let's say 20) and store it in a relational database using PHP. After doing some research I found a few options:
1) Cronjobs (with shell scripts)
See https://askubuntu.com/questions/800/how-to-run-scripts-every-5-seconds for more information. This basically comes down to run a shell script (looping/sleeping)
This doesn't feel right as I could not catch exceptions and/or race conditions might occur. Also, cronjobs itself are not made for this kind of tasks.
2) Web-worker (with queued jobs)
Laravel provides a queue worker that can process new jobs (asynchronously) as they are pushed onto the queue. I could push multiple (say a lot) of jobs to the queue at once which should processed every x seconds consecutively.
This sounds like a more robust solution as I could catch exceptions and make sure the worker is running (using observers). The downside; it's slower and it might be overengineered.
3) Web socket
I could use node.js to run a websocket client like socket.io and implement some kind of timing mechanism to store the data every x seconds.
This solution feels odd as I was taught that sockets are used to push data to clients (realtime), but I have never seen that they were used to insert data.
All help is appreciated.
What you are looking for are artisan commands.
You would start by creating a command:
php artisan make:command FetchData
This creates a FetchData class. In this class you can edit the handle function.
public function handle()
{
//fetch your data here
}
You also need to edit the $signature variable.
protected $signature = 'fetch:data';
The next step is to register the command in the Kernel.php in the Console namespace.
You need to add your newly created FetchData class to the $commands array.
protected $commands = [
Commands\FetchData::class
];
You could now call this command from the console like php artisan fetch:data
After you registered your command in the Kernel.php you can schedule this command.
You start by adding following line to your crontab on your server (type crontab -e)
* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
You can now add following command to the schedule function in the Kernel.php:
$schedule->command('fetch:data')->everyThirtyMinutes();
There is no option for a job to run every twenty minutes so in this example I chose thirty minutes. You can check the available options here.
my project in laravel 5.5 and mysql have a start and end date for users to register in my web site
When the time ends on a date determined by the administrator, the following function must be executed in laravel:
public function select()
{
seleccion::create([
'emp_id' => Carbon\Carbon::now()->format('Y-m-d'),
'dst_id' => 'Success',
]);
}
I read the laravel documentation but I do not know what to use
Task Scheduling
commands
event / listeners
Scheduling Queued Jobs
???
those methods do not tell me how to execute a function once on a certain date.
Assuming that there's a single date upon which this function needs to execute, I would simply schedule an Artisan Command
You'd first have to create a command, which you can do by running:
php artisan make:command ExpireRegistrations
Then you'd add your code to the handle() method of the command
Then you would schedule the command to be executed on the date you require, by adding it to App/Console/Kernel.php
See the laravel docs for the scheduling syntax: https://laravel.com/docs/5.5/scheduling#schedule-frequency-options
Lastly, you'll want to ensure that the Laravel
Cron job is set to run on your server by adding this to your Cron Tab:
* * * * * php /path-to-your-project/artisan schedule:
I have an event that is fired when I receive certain notifications. I want to Queue the event so that they aren't all fired at the same time but are Queued up as I receive them and then fired after the previous event completes. I want to know the best way to do this.
Edit: Just for anyone in the future, setting up the database Queue driver is very straightforward and simple. You run the php artisan queue:table and change the driver to 'database'. My problem was that my app wasn't recognizing my QUEUE_DRIVER setting in my .env file for some reason.
Laravel 5 has it's own way of dealing with queued jobs, but you can still use the options that were available in Laravel 4. I've personally been curious as to how it all works and just threw together a blank project and ran a couple of queued jobs with a little help from the docs so this may not be a full answer but I hope this helps you on your way.
First you will want to set your config to use the database queue driver, this can be done in config/queue.php or for me it was a matter of going to the .env file and doing this: QUEUE_DRIVER=database.
Then you want to set up the database table to hold the queued jobs, you can do this by running an artisan command: php artisan queue:table this will create the migration so then you need to create the table by running php artisan migrate and then you'll have your jobs table in your DB.
Following that, you'll want to set up a queued job which come in the form of Commands. For example I'll set up a job that writes some text to the log file. You can create jobs or commands using an artisan command, here's what I did to create a command: php artisan make:command WriteToLog --queued. And here's what my command class looks like after adding a little code to get it to write to the log file...
app/Commands/WriteToLog.php
use App\Commands\Command;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldBeQueued;
class WriteToLog extends Command implements SelfHandling, ShouldBeQueued {
use InteractsWithQueue, SerializesModels;
protected $secs;
/**
* Create a new command instance.
*
* #return void
*/
public function __construct($secs)
{
$this->secs = $secs;
}
/**
* Execute the command.
*
* #return void
*/
public function handle()
{
\Log::info('Writing to the log in ' . $this->secs);
}
}
After creating a command, to test it out I wrote a route in my routes file ...
app/Http/routes.php
Route::get('/', function(){
// some time to delay the job
$fiveSecs = \Carbon\Carbon::now()->addSeconds(5);
$tenSecs = \Carbon\Carbon::now()->addSeconds(10);
// adds job to queue
Queue::later($fiveSecs, new App\Commands\WriteToLog('5 secs'));
Queue::later($tenSecs, new App\Commands\WriteToLog('10 secs'));
return 'All done';
});
Before we hit the route we want to listen for any jobs in order to process them, just run php artisan queue:listen then you can go to your browser to the route, after hitting the route in my browser the console shows
$ php artisan queue:listen
Processed: Illuminate\Queue\CallQueuedHandler#call
Processed: Illuminate\Queue\CallQueuedHandler#call
And if I check my log file I see the following:
[2015-05-19 19:25:08] local.INFO: Writing to the log in 5 secs
[2015-05-19 19:25:10] local.INFO: Writing to the log in 10 secs
Not exactly 5 and 10 seconds apart but hopefully you get the idea!
For me this is really just the tip of the iceberg and queued jobs are something very powerful in laravel, I highly recommend checking out the docs here: http://laravel.com/docs/5.0/queues and here: http://laravel.com/docs/5.0/bus
You can also fire events from your queued jobs or queue an event handler, see here for more details: http://laravel.com/docs/5.0/events#queued-event-handlers
Laravel makes queues pretty straightforward, but a bit long to explain fully here. Check out these guides:
If you are using forge, it is really painless:
https://mattstauffer.co/blog/laravel-forge-adding-a-queue-worker-with-beanstalkd
If you aren't using forge, it is still pretty ok: http://fideloper.com/ubuntu-beanstalkd-and-laravel4