how to stop action scheduler 3.0 in wordpress 6.0? - wordpress

I want to stop all my action scheduler when I am login in my wp-admin, instead of it I want to manage all cron should be handle by cron background of my server. is it possible please tell me the way I already spend lot of time to stop it from wp-admin ajax process.
Currently its working as below
The async queue runner initiates action processing when an admin user logs into the WordPress administration dashboard. It also uses loopback requests to process multiple batches of actions in a sequence of requests so that instead of processing actions in just one request, once a queue starts processing, it will continue to process actions in a new request until there are no actions to process, or loopback limits are reached.
So I just want to break this flow and instead of this I want to set my cron that can handle all the stuff so I don't need to login in my admin every time to run the all scheduler.

Add this in your functions.php to disable Action Scheduler:
<?php
function just_disable_default_runner() {
if ( class_exists( 'ActionScheduler' ) ) {
remove_action( 'action_scheduler_run_queue', array( ActionScheduler::runner(), 'run' ) );
}
}

Related

Wordpress how to register global object before executing cron, so it's usable during cron job?

I have some background workers in Wordpress which are registered as global variables during init hook. Everything is ok until I'm trying to reference the workers during a cron job, they are undefined.
The cron job, if you are asking yourself what's the purpose of this, basically is looking if there are jobs to do, and if yes it's enqueueing them in the background worker.
So since the init hook seems to not run before executing cron job, what is the best hook if there is one, where i can register my workers earlier?
If there is a way I'd like to go on Wordpress way, without setting my own cron implementation with external trigger.
You need to set the priority of your action hook that registers the globals on init to a value below 10.
add_action('init', 'my_function_that_registers_global_variables', 9)
Source with more details: https://konstantin.blog/2013/tip-wp_cron-runs-during-init/

Understanding WordPress Cron

What will be the best way to activate WordPress cron if your site has no hits or visits?
Just starting out my new DAILY BIBLE QUOTE blog and I have no hits yet. I have scheduled a post to published “once every day at 6:00 AM”. Since I have no hits I’m afraid the scheduled post will not get published, so i add cronjob on my shared cpanel hosting using the code below:
0 6 * * * wget -O /dev/null --timeout=120 http://example.com/wp-cron.php?doing_wp_cron=true
So my question is,
Will the scheduled post gets published using the command above or querying only the site http://example.com/ on the cron command is enough to do the job?
Do i need to scheduled the post at 6:05AM and add crontab to run at 6:00AM?
Do not run cronjob on the site hosting since the IP is going to be same, so better use a cron service like EasyCron using the FREE plan https://www.easycron.com/user/plan since the IP is going to be different so that my site will think of it as a new visit, hence activating wp-cron.
To address your questions:
Yes, you would simply need to load the homepage of your site (though you could load any page of the site) to trigger the WP Cron event. When you load the WordPress stack, on any page, it will load the entire WordPress stack and part of that loading is checking the database to see if any cron events are ready to run. The cron information is saved in the database with information on the time the next instance of that cron runs and the function/hook to run at that time, if anything matches it will fire off the event.
For more information on WordPress cron, you can review their documentation here:
https://developer.wordpress.org/plugins/cron/
Why not schedule the post at 5:59AM and then run the cron at 6AM? That would ensure that it gets published right on the minute.

Triggering Wordress cron jobs function on server side

Suppose I have a Wordpresss cron job scheduler function ( which runs only on page loads ) on server as follows :
add_action('init','create_single_schedule');
add_action('single_cron_job','single_cron_function');
function single_cron_function(){
Do cron here
}
function create_single_schedule(){
//check if event scheduled before
if(!wp_next_scheduled('single_cron_job'))
//schedule event to run after 60 seconds (or one minute)
wp_schedule_single_event (time()+60, 'single_cron_job');
}
Now the problem is if no one opens my website , how can i call create_single_schedule() to schedule/trigger a cron job ?
You have to set up a real cron job on your server to call wp-cron.php at your desired interval.
First, disable WordPress cron on wp-config.php:
define('DISABLE_WP_CRON', true);
If you have cPanel, set up a cron job to run every 5 minutes, or every hour and to execute the command:
wget http://www.example.com/wp-cron.php
More info:
Hooking WP-Cron Into the System Task Scheduler | Plugin Developer Handbook | WordPress Developer Resources
Should I disable WP_CRON and instead trigger wp-cron.php from server every few mins?
Insights into WP-Cron: An Introduction to Scheduling Tasks in WordPress

Horizontal scaling and cron jobs

I was recently forced to move my app to Amazon and use auto-scaling, I have stumbled on to a issue with cron jobs and automatic scaling.
I have a cron job running every 15 minutes which checks if subscriptions should be charged, the query selects all subscriptions that are past due, and attempts to charge them. It changes their status once processed, but they are fetched In a batch, and the process takes 1-3 minutes.
If I have multiple instances with the same cron job, it could fire simultaneously and charge the subscriptions multiple times. This has actually happened once.
What is the Best approach here? Somehow locking the table?
I am using Amazon elastic beanstalk and symfony3.
At least you can use dedicated micro instance for subscription charging (not auto-scaled of course), just with cron jobs. Simplest way yet safest (obviously it will safe if you move your subscription handling logic from front-end servers which potentially can be hacked to the server behind VPC subnet that isn't available from global network).
But if you don't want, you still can use another approach. You mentioned you use Beanstalk. Beanstalk allow to use delayed jobs.
So possible approach is:
1) When you create subscription, you can calculate when it should be charged, and then push the job with calculated delay to Beanstalk tube.
2) Then, worker get the job (with subscription) on-time. Only one worker will get the particular job, so it will work if you use autoscaling.
3) In worker, you check the subscription (probably it can be deleted or inactive etc.) and if it ready to charge, just run the code for charging. Then calculate next charging time and push new delayed job (with subscription) to queue.
Beanstalk has Symfony bundle and powerful PHP library
You can make your job run only for one instance i.e make your functionality - charge subscription run only for one of instance.
You can use AWS api for fetching all instances and then matching the instances with current running one.
ec2 = Aws::EC2::Resource.new(region: 'region',
credentials: Aws::Credentials.new(IAM_KEY', 'IAM_SECRET')
)
metadata_endpoint = 'http://169.254.169.254/latest/meta-data/'
current_server_id = Net::HTTP.get( URI.parse( metadata_endpoint + 'instance-id' ) )
instances = []
ec2.instances.each do |i|
if (i.state.name == 'running')
instances << i.id
end
end
if (instances.first == current_server_id )
{
your functionality
}

Sending emails asynchronously: spool, queue, and cronjob/daemon

I want to send emails asynchronously for faster and lighter http responses, but I'm struggling with many new concepts.
For example, the documentation talks about spool. It says I should use spool with a file, and then send emails with a command. But how should I be running that command? If I set a cronjob to execute that command every 1 minute (the minimum available in cron), users will have to wait an average of 30 secs for their emails to be sent (eg, the registration email).
So I thought of using a queue instead. I'm already using RabbitMQBundle for image processing (eg, thumbnail creation). But I only use this one periodically, so it is consumed from within a cronjob.
Maybe I should create a daemon that is always waiting for new messages to arrive the email queue and deliver them ASAP?
The solution is to send every email to a queue, and then consume that queue with a service. My service is very simple, it just takes items out of the queue, where each item is an array with from, to, body, etc., and sends that email. I'm using Thumper which makes Rabbit easier to use: github.com/videlalvaro/Thumper . And I make sure the service is always up using 'sv' (from Runit): smarden.org/runit/sv.8.html . You can use any other service or daemon manager you like.
I have the same problem as you had. How you finally solved your problem?
For the moment I run a little script in the crontab in order to run in loop:
<?php
include('/var/www/vendor/symfony/symfony/src/Symfony/Component/Filesystem/LockHandler.php');
use Symfony\Component\Filesystem\LockHandler;
$lock = new LockHandler('mailer:loop');
if ($lock->lock()) {
system('cd /var/www && php app/console swiftmailer:spool:send');
sleep(1);
$lock->release();
shell_exec('cd /var/www && php LoopMailer.php > /dev/null 2>/dev/null &');
}
It's not very clean but it does his job.
You need 2 services one for spooling message and other for send instant emails. Check this

Resources