laravel 6 - task schedule withoutOverlapping still overlapp with heroku - laravel

I try to run a task withoutOverlapping but the task still called every minute even if i add
->withoutOverlapping()
Here is my task i have a sleep(240) to force the task to be longer than 1 min but the mails is still sent every minutes
$schedule->call(function() {
$user = User::find(4);
Mail::to('john.doe#gmail.com')->queue(new AccountConfirmation($user));
sleep(240);
})->name('update_game')->withoutOverlapping(20);
I use heroku with a scheduler here are the logs : the task "update_game" run every minutes even if the task takes more than 1 minute (with the sleep(240)) i wonder why

The Heroku scheduler starts a brand new dyno (basically, a server) every time it runs.
->withoutOverlapping() only applies to the current server, so it's not doing anything, because the next minute another server is running.
You'll want to call ->onOneServer() too, but to do that, you'll need to move off the file driver onto something like redis for your caching system, or you'll have the same problem - one server not knowing anything about the other, because they each have their own set of files.

Related

Deployed application on Heroku executes automatically

I am using Advanced Scheduler to schedule a cron job daily once at 12 PM. But the code executes automatically even though I have disabled the trigger and disconnected my GitHub repository. So far the code has executed three times in an interval of 2 hours.
I don't understand why it is executing automatically?
Any idea?

gcloud cron jobs and laravel

I am trying to execute an api in laravel every minute.
The api's method is GET. However I could not specify the method in the cron.yaml file. Could I use DELETE method here and how? The code should be deployed on google cloud.
I have created a cron.yaml file that has the following format:
cron:
- description: "every minutes job"
url: /deletestories
schedule: every 1 mins
retry_parameters:
min_backoff_seconds: 2.5
max_doublings: 5
I also created the api deletestories that delete rows under specific conditions.
However this isn't working, and when I open google cloud console I could not found any error or any cron job executed.
This cron.yaml file appears to be a Google App Engine cron configuration. If this is correct then only the GET method is supported, you cannot use DELETE.
The GAE cron service itself consists simply of scheduled GET requests that your app needs to handle. From Scheduling Tasks With Cron for Python (the same applies to other languages and to the flexible environment cron as well):
A cron job makes an HTTP GET request to a URL as scheduled. The
handler for that URL executes the logic when it is called.
You also need to deploy your cron.yaml file for it to be effective. You should be able to see the deployed cron configuration in the developer console's Cron Jobs tab under the Task Queues Menu (where you can also manually trigger any of the cron jobs). The performed GET requests for the respective cron jobs should appear in your app's request logs as well, when executed.

How to get ansible to stay on the machine after finishing a task?

I am using ansible to run a task which starts up build engines. Once they have all started, ansible returns control to me and I see that they all stop at once. When I add an async: 10 flag to the running of the script it works, but the problem is when there are multiple build engines it takes longer than 10 seconds for them to start, which makes the async kind of null.
I have tried using a
- pause:
seconds: 10
task below the running of the script, but the build engines stop, then it does the pause.
What I am asking is - Is there a way to make ansible stick around on the machine for a few seconds after it has finished running the command (i.e. after control has been returned to user)?
While it's unclear what kind of build system you are using and why it can't properly daemonize itself, i think wait_for module is perfectly suited for your needs. You can wait for tcp port to come up, if your build system opens one, wait for some file to be created, parse log files for string, indicating that build has started successfully or simply wait for some time.
Tried wait_for but that seems to exit the environment and then perform the task.
I fixed this problem by using the following in my shell execution task:
async: 300
poll: 5
This runs the task asynchronously and polls every 5 seconds for a response.

Laravel scheduler command never runs a 2nd time

I've configured scheduler to run once every minute to execute two commands:
$schedule->command('amazon:read-sqs')
->everyMinute()
->runInBackground()
->withoutOverlapping()
->sendOutputTo(storage_path('logs/cmd/amazon_read_sqs.log'), true)
->thenPing('http://beats.envoyer.io/heartbeat/SoMeRaNdOmHaSh1');
$schedule->command('jobs:dispatcher', ['--max' => 100])
->everyMinute()
->runInBackground()
->withoutOverlapping()
->sendOutputTo(storage_path('logs/cmd/jobs_dispatcher.log'), true)
->thenPing('http://beats.envoyer.io/heartbeat/SoMeRaNdOmHaSh2');
It's been running great for the past month of development. However, right after setting up our server to run with Envoyer, the scheduler suddenly never executes after the first time.
In other words, if the schedule is set to every minute in Forge, it runs once and then never appends the logs.
I added Envoyer heartbeats to track it every 10 min but it doesn't trigger the thenPing() method to notify Envoyer...even after that first run.
I can delete the cron entry and recreate it, forcing it to run that one time.
All of these run fine if they are given their own cronjob.
When I check for any /storage/framework/schedule-* lock files, I find nothing to delete that could be blocking them.
Nothing in the Laravel log files showing a problem.
Any ideas?
Solved this by changing the cronjob from php /home/forge/default/artisan schedule:run to php /home/forge/default/current/artisan schedule:run
This allowed the Laravel scheduler to run correctly. However, the methods thenPing and pingBefore still never actually do their job.
To fix that, I had to manually add this line after each command:
(new Client())->get('http://beats.envoyer.io/heartbeat/SoMeRaNdOmHaSh');
Why the built-in ping methods don't work is a mystery. Would love to know why.

Heroku - how to run Schedluer addon 4x per day?

I have an app hosted on Heroku and this app need to run some task several times per day, lets say 4 times (and in the best way - I would like to set up, which hour will be the task run - eg. 1. task at 1AM, 2. at 5AM, 3. at 11AM and 4. at 8PM).
Heroku offers the addon called Scheduler. Is there any way to run tasks by the time scheme above?
You can run the scheduler hourly but you'd need to check what hour it currently is via;
[1,5,11,20].include?(Time.now.hour)
in the task that you want to run to have it run at 1am, 5am, 11am and 8pm as per your question.

Resources