deferred.php
was the XF 1.5 mechanism.
In XF 2.x it usesjob.php
in the forum root directory - triggered by an Ajax call on certain page loads when the system detects jobs waiting to be run.
In XF 2.x, "jobs" are (typically) restartable processes which run in the background doing tasks which can sometimes take a long time to complete - it has built in mechanisms to process small chunks of work before stopping and then restarting again on the next trigger. Typically they are used for things like rebuilding data or caches, sending large batches of email, processing email bounces - all those background tasks which are not user-facing and aren't time-critical.
The cron system is actually one of these jobs!
The cron "job" looks through the list of cron entries and calculates which are due to run, then loops through and runs those cron tasks until the allowed execution time is reached - by default, that's 8 seconds and this is configurable via aconfig.php
option. Note that it doesn't forcefully stop a task from running if it takes longer than 8 seconds, it just won't start any new tasks if it works out that it has already been running the various cron tasks for more than 8 seconds. It will stop and then wait to be triggered by the job manager again.
Normally a job will do it's work and then if it runs out of time, will update the system with counters for where it is up to and wait to be triggered again (waits for a "resume"). Alternatively, if it has finished its task (rebuilding data, or sending mail, or whatever), it will mark itself as "complete" and stop execution. Execution will start again (from the beginning) once explicitly triggered by some process or user/admin action.
The trick with the Cron job is that it never completes. The last step it takes, is to mark itself as unfinished and calculate the time the next cron task is due to run. It then sets that as the trigger time for job manager to run it again. The job entry for the cron system remains in the database - and will be run by the job system again once the trigger time passes.
If you look in the xf_job table on XF2.x, you should always see an entry forXF\Job\Cron
- the trigger date will be the time it has calculated the next cron task is due to run. This is recalculated if you add or update a cron entry in the admin ui.
If you want a greater understanding of how it all hangs together - you can disable the browser based ajax trigger and trigger the job manager manually using my addon https://xenforo.com/community/resources/cli-job-runner.6478/ and watch what happens in the database as it does its thing.
That ajax call which triggers job.php will only appear on a page load if the system detects that there are jobs to be run.
If you look at the HTML tag at the top of the page - you'll seedata-run-jobs=""
appear whenever the system detects that there are jobs to be run:
HTML:<!DOCTYPE html> <html id="XF" lang="en-US" dir="LTR" data-app="public" data-template="forum_list" data-container-key="" data-content-key="" data-logged-in="true" data-cookie-prefix="xf_" class="has-no-js template-forum_list" data-run-jobs=""> <!-- <== this is the magic bit! -->
This is picked up by the XF JavaScript which posts an Ajax call tojob.php
- search forXF.JobRunner
injs/xf/core.js
to see details.
It has always been like this. A user visits the page and if there are outstanding jobs, an asynchronous request is made to job.php (previously deferred.php) which begins execution of the outstanding jobs. Crons are triggered like this a well. When it is triggered, it should execute any cron entries where the scheduled run time has passed.Cron jobs that are scheduled should run at the scheduled time, not based on page loads.
SELECT unique_key, trigger_date, last_run_date
FROM xf_job
ORDER BY trigger_date
cron
?It has always been like this. A user visits the page and if there are outstanding jobs, an asynchronous request is made to job.php (previously deferred.php) which begins execution of the outstanding jobs. Crons are triggered like this a well. When it is triggered, it should execute any cron entries where the scheduled run time has passed.
On a site that has literally zero visitors, it is possible that the jobs (and cron entries) queue up until such a time there is a visitor that lands on the page and the jobs are triggered.
I assume you have more than zero visitors, though, so I'm going to assume that isn't the situation here.
The job running also relies on a database table to store the scheduled jobs.
1) Can you get the output of this query:
SQL:SELECT unique_key, trigger_date, last_run_date FROM xf_job ORDER BY trigger_date
2) Does an entry appear with a unique_key ofcron
?
@squirrly
I don't think you understand how PHP works. Any php script runs once only. To run it again, you need to reload the page.
These are not cron jobs running on your server. They are php scripts running from within the php-based Xenforo software.
Ok, cool. But since we have the same traffic as yesterday, telling me page views is the problem isn't an actual viable solution.
It has always been like this. A user visits the page and if there are outstanding jobs, an asynchronous request is made to job.php (previously deferred.php) which begins execution of the outstanding jobs. Crons are triggered like this a well. When it is triggered, it should execute any cron entries where the scheduled run time has passed.
On a site that has literally zero visitors, it is possible that the jobs (and cron entries) queue up until such a time there is a visitor that lands on the page and the jobs are triggered.
I assume you have more than zero visitors, though, so I'm going to assume that isn't the situation here.
The job running also relies on a database table to store the scheduled jobs.
1) Can you get the output of this query:
SQL:SELECT unique_key, trigger_date, last_run_date FROM xf_job ORDER BY trigger_date
2) Does an entry appear with a unique_key ofcron
?
- your forum traffic is very low (ie a new site with few members) and thus the asynchronous ajax trigger is not being called enough
- you have modified your themes and inadvertently removed the code which triggers the ajax calls
- there is some kind of database or data corruption happening, causing the cron trigger to not find any data (eg the cron "job" is missing from the database as alluded to by @Chris D ) - I believe the cron job database entry (that triggers the cron tasks) can be recreated automatically by editing and saving any of the cron tasks in the admin UI.
- there is a job which taking too long to complete (and then being re-queued for completion) and is thus effectively blocking other tasks from being completed
We use essential cookies to make this site work, and optional cookies to enhance your experience.