can run a task every X second with Laravel? - laravel-5

Hy guys, I have read the chapter called scheduling of Laravel's documentation, but
I haven't found much information. I'm trying to customize the execution of a task to make it run every 30 seconds. Is there a solution ?
Sorry for my english and have a good day.

By default CRON tasks are scheduled in minimal period 1 minute, but there is workaround for your issue.
In Console Kernel you should do something like this:
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('your_command:run', ['--delay'=> 0])->everyMinute();
$schedule->command('your_command:run', ['--delay'=> 30])->everyMinute();
}
In your Command class you should define the $signature variable that can take the delay parameter.
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'your_command:run {--delay= : Number of seconds to delay command}';
In the handle method you should read value of this parameter and sleep this task for specific number of second using built-in sleep() function.
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
// code
sleep(intval($this->option('delay')));
}
This solution will run your task every 30 seconds, you can multiply number of task with different delay. In this case you need to edit schedule method in Kernel class.

I've got this quote on the Laravel docs...
In the past, developers have generated a Cron entry for each task they need to schedule. However, this is a headache. Your task schedule is no longer in source control, and you must SSH into your server to add the Cron entries. The Laravel command scheduler allows you to fluently and expressively define your command schedule within Laravel itself, and only a single Cron entry is needed on your server.
You still need to use Cron to run your tasks but using the Laravel's Scheduling you set only one job on the Cron and control all the jobs of your application through the Task Scheduling.
Example:
Set this cron on your server:
* * * * * php /path/to/artisan schedule:run
It is gonna call the Laravel command scheduler every minute and then, Laravel evaluates your scheduled tasks and runs the tasks that are due.
Then on your file app/Console/Kernel.php you can configure all your tasks as the code below:
$schedule->call(function () {
DB::table('recent_users')->delete();
})->daily();
$schedule->command('inspire')->hourly();

Related

Laravel schedule not respecting time

I am using Laravel 9 and I am trying to set several tasks in my schedule.
One of them should be called every minutes the other every 5 minutes .
protected function schedule(Schedule $schedule)
{
$schedule->call(/* send myself a mail */)->everyMinute();
$schedule->call(/* send myself a mail */)->everyFiveMinutes();
}
On my host I have a cron task called every minutes :
/opt/alt/php81/usr/bin/php ~/my-path/artisan schedule:run
However every minutes I receive the mail from my everyMinute() task, and the mail from my everyFiveMinutes() task.
I tried with job and command instead of call but it doesn't changes anything, same with ->cron('* * * * *') instead of ->everyMinute()
I had the very same issue.
I discover that when I use the schedule like this:
$schedule->call( MyController::MyFunction() )->everyFiveMinutes();
It run every minute, not every 5 minute as it would suppose to run.
If I run like this, every works as expect:
$schedule->call(function () {MyController::MyFunction();})->everyFiveMinutes();

I am trying to run a task schedule on cPanel but not working

I am trying to run cron job on the daily bases at 16:00 but unfortunately not working please help me thanks
Note :- when i select schedule ->everMinute() it works perfectly.
/home3/urbanhq6/public_html/new/app/Console/Kernel.php
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('reminder:email')
->dailyAt('16:00');
}
cron job timing set
Minute Hour Day Month Weekday
0 16 * * *
First, you should adjust your cPanel cron to run every minute, with timings of * * * * *. Laravel handles its own scheduling via rules (like ->dailyAt('16:00')) in the Kernel.php file; running every minute lets Laravel do that without needing adjustments when you add a new command to the schedule.
Now, running at 0 16 * * * should still work for this particular set of rules. The likely answer is your server and your Laravel are on different timezones - check the timezone on the server with date, and check config/app.php's timezone value.
If there's a mismatch, your cron is running at 16:00 server time, but Laravel is adjusting the time to its own timezone, which means the two don't match. Switching your cron to * * * * * will fix this - the cron will start running (as it does with everyMinute()) - but the task will run at an unexpected hour.

Laravel Scheduler and Cron - how does Laravel know not to run the scheduled jobs based on daily(), hourly() etc

In Laravel, in my Kernel, I have:
protected $commands = [
Commands\SendRenewEmails::class,
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
$schedule->command('renew:emails')
->daily();
}
The said function renew:emails, works as intended if I run this manually trough Artisan.
And in my crontab I have:
* */8 * * * cd /path-to-my-project && php artisan schedule:run >> /dev/null 2>&1
I have this to run every 8th hour, instead of every minute at * * * * *, since this is live for testing, and just to ensure that the task wasnt run every minute.
So how does Laravel know, when to run the daily job on the kernal, and when does this happen?
From this setup (which seems to be the basic setup for cronjobs in Laravel, but to run every minute instead of every 8th hour), there is no logs (that I can see), and no table in DB to keep track of this.
So if I where to set my cron to * * * * *, how does Laravel know not to run the scheduled job every minute, just because I have put ->daily(); at the end of the job?
And when I have daily();, at what specific time is that? And at specific what time is hourly();?
TL;DR:
How does Laravel know not to run the same jobs again if it is not supposed to, for example with daily(); rule? Where is this information stored? How can I be certain that a job with rule daily(); wont run every minute if my cronjobs std:out's php artisan schedule:run every minute?
Under the hood, the Laravel Scheduler uses https://github.com/dragonmantank/cron-expression to determine if a command or job is scheduled to run at the given minute the schedule:run is called.
Each task you schedule translates to a cron expression, which is then passed into the package. A method called isDue is then run against that expression to determine whether or not it should run. So, if you set a task to run hourly, then isDue will yield true at the top of the hour, and Laravel will execute to the task within the cron cycle.
As such, the information does not need to be stored anywhere, as determination is done on the fly.
This might also lead you to wonder what might happen if you have a long-running task that might take longer than the interval. This is where withoutOverlapping comes into the picture. When called, it creates what is known as a mutex, which is similar to a 'lock' of sorts (see What is a mutex? for more information), when the task is initially run. If a mutex already exists for a particular task on subsquent cycles, it means that task is currently running in another cycle, and should not be triggered again in this one.
Where are mutexes stored? Simple: Laravel stores them in a cache, and when a mutexed task is finished, the mutex is removed from the cache. And so the cycle continues.
I could go into much further detail here, but I think this answers your question for the most part.

Laravel scheduled task: cron syntax for 'every 2 minutes' is ignored

I'am using the following syntax
$schedule->job(new PublishHighlightPlan())->cron('* */2 * * *');
Actually my job is executed every single minute, not every two as I expect.
What am I doing wrong?
I think you are making every 2nd hours as per your syntax.
Try below pattern.
$schedule->job(new PublishHighlightPlan())->cron('*/2 * * * *');
It might help you.

Laravel 5 / L5: Set number of attempts when pushing job to a queue using Database connection

I have setup the Queue system in L5 using the Databse connection and after i run the migration I have two tables in my DB failed_jobs and jobs. Everything is working fine so far but when the pushed operation failed its keep going and trying to process the operation and did not delete the job on fail or inserted on failed_jobs
Queue::push(function($job) use ($id)
{
Account::delete($id);
$job->delete();
});
In the above example how can I set number of attempts to try if not success and then insert into failed_jobs.
I know this can be done using
php artisan queue:listen --tries=3
But I want the same using the Closures as I have different cases
You can check the number of attempts:
if ($job->attempts() > 3)
{
//
}
This is clearly mentioned in the documentation here.
You can define the maximum number of attempts on the job class itself.
If the maximum number of attempts is specified on the job, it will take precedence over the value provided on the command line.
Add this to your job class:
/**
* The number of times the job may be attempted.
*
* #var int
*/
public $tries = 5;

Resources