This feature request may also solve the http://drupal.org/node/24001 issue with thrashed user session state.

This request comes out of the following situation:
- Logging in to Drupal sites using stored passwords (browser feature), is very slow, as the browser password auto-fill-in does not finish until poormanscron has finished. So the user has to wait for poormanscron to finish before the login information is filled in. The response time is longer the more syndication sources the actual site is using.

I suggest adding a setting that allows the administrator to specify the amount of seconds/minutes one want poormanscron to wait before execution, whenever it is triggered by anonymous users. There should be a way to run it instantly as when typing cron.php in the URL, so the new setting should perhaps only be related to anonymous?

PS. There is another nice side effect of being able to set it to several minutes:
Then a user can log in, post a quick post, and have the new post instantly taking part in the notification that the delayed cron will trigger a few minutes later. It should be possible to set as long as 15 minutes (or more). No need to be able to specify seconds, I think.

Comments

fgm’s picture

Version: 4.6.x-1.x-dev » 4.7.x-1.x-dev

Bumping to current version, because this is still current.

Adding a setting to make poormanscron only fire on authenticated sessions might be interesting for some sites where the site admin/team is often online, but might be inappropriate for "publish" sites, which receive mostly anonymous visitors, which are served pages from cache.

Going further, 5.0 agressive caching is already incompatible with the module anyway.

What do oyther think of this ?

peterx’s picture

Something I implemented on 5.0. 5.0 has stuff that uses Curl. Curl gives a way to quickly return to the user. If you are already using Curl then the Curl part of this approach will work. The second part is an alternative for occasions when Curl is not available. I created the second part then added the first part without bothering to delete the second part.

1/ Rename poormanscron_exit to poormanscron_exit_process then add the following new poormanscron_exit followed by the extra menu entry.

poormanscron_exit will start poormanscron_exit_process as another page request and wait only for the header. Curl is instructed, by the NOBODY option, to get only the header which means Curl should get a status code of 200 immediately the headers are sent and return to poormanscron_exit.

I use this on a site where Drupal is running from the base directory, not from a subdirectory and am not using multisite.

2/
The test for $_REQUEST['form_id'] should bypass poormanscron whenever the processing is within pages that pass forms information the the next page. If the Curl stuff is not usable then the check for form_id will take care of some problems with slow responses at the wrong time. You could add in other checks to exclude occasions where you are within items called from Ajax.

function poormanscron_exit() {
/* From PeterMoulding.com.
1/ Remove Poormanscron processing from page end.
2/ Stop Poormanscron during forms processing.
*/
	if(arg(0) == 'poormanscron' // Do not process when within process.
	or isset($_REQUEST['form_id'])) // Do not process when within forms handling process.
		{
		return;
		}
	$url = 'http://' . $_SERVER['HTTP_HOST'] . '/poormanscron';
	$curly = curl_init($url);
	curl_setopt($curly, CURLOPT_NOBODY, true);
	curl_setopt($curly, CURLOPT_RETURNTRANSFER, true);
	$result = curl_exec($curly);
	if($result)
		{
		watchdog('cron', 'poormanscron_exit-process: process started successfully.', WATCHDOG_NOTICE);
		}
	else
		{
		watchdog('cron', 'poormanscron_exit-process: process failed: '
			. curl_errno($curly). ': ' . curl_error($curly), WATCHDOG_NOTICE);
		}
	curl_close($curly);
	}
/* From PeterMoulding.com.
2/ Stop Poormanscron during forms processing.
*/
		$items[] = array('path' => 'poormanscron',
			'title' => t('Cronline module'),
			'callback' => 'poormanscron_exit_process',
			'access' => user_access('access content'),
			'type' => MENU_CALLBACK);

peterx’s picture

Not much point in Curling if it is not time so add the following check after the check of arg(0) and for form_id.

	// Calculate when the next poormanscron run is due.
	$lastrun = variable_get('poormanscron_lastrun', 0);
	$nextrun = $lastrun + 60 * variable_get('poormanscron_interval', 60);
	// If it is not yet time, do not start the next poormanscron run.
	if(time() < $nextrun)
		{
		return;
		}
sun’s picture

Title: Delayed startup setting. » Delayed cron runs
Version: 4.7.x-1.x-dev » 7.x-2.x-dev

Did you already try to register drupal_run_cron() as a shutdown function?
http://php.net/manual/en/function.register-shutdown-function.php

sun’s picture

dave reid’s picture

Status: Active » Closed (duplicate)