Laravel Scheduler fire 2 Commands at different times - php

I have 1 custom Command I've created:
php artisan protal:process {name}
I need to fire this command for 2 different Portals (different name), so If I run this in my console everything works:
php artisan protal:process nameone
//wait for it to finish
php artisan protal:process nametwo
I need to do the same at night with a cron, so this is what I came up with:
app/console/Kernel.php
protected function schedule(Schedule $schedule)
{
$schedule->command('portal:process nameone')->daily()->withoutOverlapping();
$schedule->command('portal:process nametwo')->dailyAt('00:10')->withoutOverlapping();
}
For some reasons only the first command fires and the second one gets ignored. If I run the second one commenting the first one it works ok.
Perhaps to fire 2 commands in different times do I have to take some different method other than the above?

Added as answer for reference, was a comment:
I've had this problem before. The problem was that I never properly closed the first command (with a return for example), which caused Laravel to think the command never ended and never started the next command as a result. PHP executes line for line, so the problem is probably in the withoutOverlapping.

Related

Laravel 8, how to run a job (script) in the background?

I am trying to run a time consuming script in the background with Laravel 8, but cant quite get it to work. I try to follow the docs from here https://laravel.com/docs/8.x/queues in combination with the tutorial found here: https://learn2torials.com/a/how-to-create-background-job-in-laravel
As per docs, I should run the following commands to get strateted with Queue/jobs in Laravel
php artisan queue:table
php artisan migrate
Then we should create our Job with the following command
php artisan make:job TestJob
In App\Jobs\ is our newly created job-file: TestJob.php
Again following the docs, I should put my time consuming script/code in the handle() method of TestJob.php. I have written the following code in handle() for test purposes:
public function handle()
{
//Do some time-consuming stuff
sleep(30);
}
Next, according to the docs, we should dispatch our job with the following line of code TestJob::dispatch(), anywhere in our app, so for test purposes, I put this line directly into our routes file, like this:
Route::get('/', function () {
//Run this job in the background and continue
\App\Jobs\TestJob::dispatch();
//After job is started/Queued return view
return view('welcome');
});
That should be it, as I understand from the docs, but it is not working as I expected. The code in handle() gets executed, but the return view('welcome'); is executed AFTER the the job is completed.
I was expecting the script to be executed and while running in the background the next line of code will be executed. How can I make it run in the background so the user do not have to wait for the script to finish?
I have googled a lot and according to the tutorial linked to earlier, I should have the following line: QUEUE_DRIVER=database​ in my .env file. I have sat this, and also sat it in Config\queue.php with the following line: 'default' => env('QUEUE_CONNECTION', 'database'),, but still same result
I also found the following solution for Laravel 5 here on SO (link), where there is suggested that we also should run the following code to get it to work: php artisan queue:listen, but its the same result again
Any help would be much appreciated!
By default the .env file has QUEUE_CONNECTION=sync.
Meaning, the sync connection uses the main thread for the execution of tasks. Hence, it has to first complete before moving on to the next line of code.
To make tasks run in the background so that your main application thread won't block and you can serve your client requests more quickly, try using a different connection i.e database.
To do this, simply change QUEUE_CONNECTION=database in your .env file.
You may run php artisan queue:listen on your local computer set-up to process tasks as they come in.
NOTE: On the production server, it may be more convenient to set-up something more robust to automatically restart your processes if they fail. Supervisor Configuration

Why aren't my changes to the scheduler in Laravel being reflected?

I am working on updating the schedule function in my Kernel.php file. I have versions of this file locally and on a production instance. There is a $schedule->call function that was set to run 4 different functions every 5 minutes. One of those functions is outdated and shouldn't be run anymore, so I commented it out locally and in the production instance.
I have a database table that logs the name of each function each time they are ran. When I checked my table, I saw that all 4 functions are still being run every 5 minutes. When I ran php artisan: schedule:run, the log showed only the 3 desired functions. But that's only when I run it manually, and it had no change on what was being run automatically.
I have seen stuff about cron, but I am confused if this is something I need to enter on the command line or if it might be some file I need to set up to get my scheduler to properly update?
This is what I am referring to that I saw on the Laravel documentation site:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
Any advice or direction would be much appreciated:
I've been bitten by this more often than I care to admit. It is potentially a caching issues. Run the following:
php artisan cache:clear
php artisan queue:restart
The queue is the one that gets me every time.

Laravel Scheduled Command doesn't run

Using Laravel, I have a cron in Kernel.php that doesn't seem to run when just left to run, if I run php artisan command-name manually, it does work. Below is what I have in Kernel.php, I'm not sure what's stopping it running every 5 minutes, automatically:
$schedule->command('command-name')
->everyFiveMinutes()
->withoutOverlapping()
->runInBackground()
->sendOutputTo(storage_path('logs/command-name.log'));
withoutOverlapping should create a file in storage folder with a name as
schedule_123456....
If the command stopped abruptly this file could remain undeleted. I think you have to delete it manually.
Two things:
withoutOverlapping create a lock for 24 hours that avoids to run a new instance of same, while runInBackground let more than one instance to run concurrently. I'ld use only one of the two options..
you can pass a parameter to withoutOverlapping to let the check to last less than 24 hours

Multiple Cron jobs in one crontab file

I wanted to implement two cronjobs with different execution time. One cron job is for sending emails and second cron job for validating my application subscriptions.
I write one crontab file and write to two cronjob as follows:
2 * * * * path to mailCronjob mail.php
20 * * * * path to check my application's subscriptions sub.php
The problem is first cronjob is working fine. Mail will delivers fine, but the second cronjob
is not working. I tried to run second job manually, its also working fine.
I am using command to set cronjob as:
crontab crontab_file
when I give command crontab -l
it also shows both cronjob in command line.
I wanted to ask, am I missing something here, or what should I do to run those cronjobs.
FACT: you can run as many cron jobs from a single crontab file as you wish.
FACT: you can also run different jobs as different users, each with their own crontab file.
SUGGESTION:
1) Just debug what's wrong with your second job.
2) It could be path, it could be permissions; it's more than likely environment (the environment for "cron" can be different from the environment for the same user from a command line).
PS:
Try this, too:
How to simulate the environment cron executes a script with?
Debugging crontab jobs
Check the owning user's email and see if an error report has been sent to it.
If you need to be a certain user and have that user's environment change your call to
su - -c "/path/to/sub.php" SubScriptUser
If your script only works from a certain directory use
cd /path/to/ && ./sub.php
I recall the same problem. For some reason, I had to press enter after my second cron job. Even in the first cron job, if it is the only job, needs a CR/LF (enter). Cursor needs to be on second line (if there is one cron job)... cursor needs to be on the third line, if there is two cron jobs. I guess, needs to read the file completely to interpret the cron job command. I just share this, because if you dont do that, only the first job will be executed, and skips the second one totally unless enter is pressed at the end of the second job. Best regards and cheers... Test that and let us know.
You need to add an empty line to the end of the config file
I never did 2 actuall cronjobs in one cron-tab file, but rather had the one cronjob execute every 15 minutes and query the database or look into a config file what tasks are there to execute, maybe this concept helps you.

How to call drupal cron multipe times until done

I'm working on a wamp development environment and testing how long it takes to get the site indexed. I'm doing this by running cron manually.
The problem is that if there's 700 jobs in the job_queue, each run of cron does only some of them, so I need to run cron several times. How could I keep calling cron in a loop until there are no more jobs left in the job_queue?
Also, I'm open to any drush alternatives. I'm aware of drush cron, but this also does only some of the jobs each run, so needs to be run again manually.
If you want to run something all at once until it's done, cron is the wrong tool for the job; batch API is the tool for that. Unfortunately the search module is written to update only on cron, but there's not a lot of code in search_cron to copy into a batch function. So I'd suggest going the batch route rather wrapping some sort of pseudo-batch around cron, as your end goal doesn't seem to involve cron at all.
step 1. - Run cron every minute
step 2. - Just check if the script is already running. If so - close the "new script"
$lid='';
if(is_array($argv) && isset($argv[1])) {
$lid=$argv[1];
}
if($lid!=='') {
$xx=array();
exec('ps x | grep "thefile.php '.$lid.'" | grep -v "grep"', &$xx);
if(count($xx)>1) {
die('Script '.$lid.' running already... exiting... '."\n");
}
}
Put it in cron with every minute php thefile.php 1
php thefile.php 2
php thefile.php 3 to run 3 scripts at the same time.
drush search-index will generate the remaining search index for you.

Categories