While working on the Kernel patch, I went to fix the bugs in cron.php. After looking at it a moment, I realized that there was no actual reason to have cron.php as a separate script anymore. One upon a time there was a good reason for it, but these days it is just vestigial. It still does a full bootstrap, and we can now bypass the page render stuff by returning a response object (which just about everything in the kernel patch will do that is not an HTML page), or in Drupal 7 by returning NULL.

After converting the kernel to just make cron a normal page callback, I realized that there was only incidental dependency on the Kernel functionality or anything from Symfony in the first place. So, this patch splits off just that part to kill cron.php, so that the eventual kernel diff is just that bit smaller.

This code is already in the kernel branch, adjusted for the new request handling. Also in the kernel branch cron will now return an HTTP 204 No Content rather than HTTP 200, which is more accurate as nothing actually gets returned.

Patch in a moment; I just need an issue ID. :-)

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Crell’s picture

Status: Active » Needs review
FileSize
11.76 KB

And patch.

sun’s picture

Title: Remove cron.php as it is vestigial » Convert cron.php into a regular menu router page callback
Status: Needs review » Needs work
Issue tags: +Framework Initiative, +API change, +API clean-up

To clarify:

We discussed this briefly in IRC and no one in #drupal-contribute was able to see why cron.php is a separate PHP file instead of a regular menu callback.

Unlike install.php/update.php (which are very special scripts) and xmlrpc.php (which is just plain horrible, but even that: #1033818: Move xmlrpc includes into xmlrpc.module), cron.php really does not do anything special.

cron.php is only ever invoked after the system is in place, at which point you know whether you will have to invoke /cron (clean) or index.php?q=cron (or upcoming index.php/cron, dirty). There is no difference to /cron.php.

The contained code is trivial and uses Drupal's standard bootstrap mechanism. Bootstrap is followed by some inlined code, but that can be easily moved into System module, as this patch demonstrates.

Adding functionality to System module generally is a won't fix ;-) but in this case it makes sense and seems to be valid (and could have done years before).

Apparently, moving the cron functionality into a regular menu router page callback allows alternative implementations in contrib to enhance or override it more easily (because no one hard-codes his cron command to cron.php anymore, which then has to be changed for alternative implementations). So there's an additional benefit in this conversion.

Almost RTBC.

+++ b/core/modules/system/system.module
@@ -5,6 +5,8 @@
+use Symfony\Component\HttpFoundation\Response;
+

Unless I'm missing something, this shouldn't in this patch :)

+++ b/core/modules/system/system.module
@@ -580,6 +582,12 @@ function system_element_info() {
+  $items['cron'] = array(
+    'title' => 'Run cron',
...
+    'type' => MENU_CALLBACK,

I realize the other items defined nearby serve as poor example, but there's no point in specifying a title for a MENU_CALLBACK, since no menu links are generated for them.

Well, we can also leave it and defer those titles to a separate issue.

+++ b/core/modules/system/system.module
@@ -1129,6 +1137,36 @@ function system_menu() {
+ * Page callback; Execute cron tasks.
...
+function system_cron_callback() {

Let's name this system_cron_page(). "callback" doesn't really mean anything. :)

+++ b/core/modules/system/system.module
@@ -1129,6 +1137,36 @@ function system_menu() {
+ *Access callback for system_cron().

Missing leading space.

Crell’s picture

Status: Needs work » Needs review
FileSize
11.51 KB

I kinda like the explicitness of MENU_CALLBACK, but since we're likely going to kill that later on I don't much care. Also "page" is technically inaccurate since there's no "page" returned, but again, it's going to change later so meh. :-)

I hadn't thought of the potential for alternate cron implementations with this approach, but you're right, it does become possible. Nifty.

New patch attached.

Crell’s picture

FileSize
11.51 KB

Correction. THIS one.

Status: Needs review » Needs work

The last submitted patch, 1551626-kill-cron.patch, failed testing.

Crell’s picture

Say what? How is cron affecting logging tests?

sun’s picture

errr, what I meant was to remove the 'title', not the MENU_CALLBACK type -- it has to be a MENU_CALLBACK, or the menu system will auto-generate a menu link for the router item, which then appears in the Navigation menu. Don't think we want that ;)

ActionsLookTestCase failing means that something is throwing a PHP warning or notice. The test implements hook_watchdog() and logs whatever is getting through watchdog(). Probably a typo or similar somewhere in the recent patches.

sun’s picture

Status: Needs work » Needs review
FileSize
11.54 KB

Restored the type, left the title alone. Can be cleaned up later.

sun’s picture

Status: Needs review » Reviewed & tested by the community

I merely fixed the test failure, so RTBC it is.

RobLoach’s picture

Status: Needs work » Reviewed & tested by the community

Still RTBC! Just thought of a couple things that could be follow up issues...

+++ b/core/modules/system/system.moduleundefined
@@ -1129,6 +1135,36 @@ function system_menu() {
+function system_cron_page() {
+  drupal_cron_run();
+
+  // Returning nothing causes no output to be generated.

We can't just reference "drupal_cron_run" directly from system_menu(), can we?

+++ b/core/modules/system/system.moduleundefined
@@ -1129,6 +1135,36 @@ function system_menu() {
+function system_cron_access() {
+  $cron_key = isset($_GET['cron_key']) ? $_GET['cron_key'] : '';
+  if ($cron_key != variable_get('cron_key', 'drupal')) {
+    watchdog('cron', 'Cron could not run because an invalid key was used.', array(), WATCHDOG_NOTICE);
+    return FALSE;

I understand this is somewhat changing the way /cron works, but what if we used 'cron/%system_cron_key' and 'access arguments' => array(1) for the menu callback, system_cron_access($cron_key) and system_cron_key_load()?

chx’s picture

Status: Reviewed & tested by the community » Needs work

#10 actually merits a CNW. The patch so far is really nice but why not go the full nine yards and use a nice url and use the menu capabilities.

sun’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
11.67 KB

Incorporated #10.

http://drupal.org/cron needs to be updated as a result of this patch.

sun’s picture

system_cron_page() cannot be replaced with drupal_cron_run(), since the latter returns a status/success (boolean) code, which would be mistaken as page callback return value (response).

RobLoach’s picture

Status: Needs review » Reviewed & tested by the community

Two things I absolutely love about this patch:

  1. The removal of direct $_GET usage
  2. Another ugly looking php file bites the dust

Status: Reviewed & tested by the community » Needs work

The last submitted patch, drupal8.cron_.12.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
12.07 KB

Testbot apparently reported the same test assertion failures two times. We need to stop bashing our testing system and infrastructure and instead help that 1.4 person who desperately tries to keep it running.

Crell’s picture

Status: Needs review » Reviewed & tested by the community

Another reason to not just map directly to drupal_run_cron(): The kernel version of this code has a menu callback because it will eventually turn into a new-style controller. No sense over-optimizing the code here when it just makes it harder for me to change later. :-)

I quite like using a path element rather than a GET query here! So, I'll RTBC #16 now.

chx’s picture

Agreed.

catch’s picture

I know it's NIH but

+curl --silent --compressed http://example.com/cron

Shouldn't this and similar examples be referencing the cron key. Don't need to fix it here, just want to make sure I'm not going mad.

Crell’s picture

Probably. I suspect the documentation was never updated for D7's key; I don't quite know how the lynx and curl shell scripts can work either, but I didn't want to get into that debate. :-) (I'd be happy to drop them all, personally.)

sun’s picture

FileSize
12.12 KB

Appended /YOURKEY to both scripts.

Crell’s picture

Still RTBC.

catch’s picture

Priority: Normal » Critical
Status: Reviewed & tested by the community » Active

Thanks! Committed/pushed to 8.x. This will need a change notification.

Crell’s picture

Priority: Critical » Normal
Status: Active » Fixed
moshe weitzman’s picture

I bet some sites deleted cron.php and thus prevented one DOS attack vector since running cron can be expensive. They would use `drush cron`, presumably. Now those sites are going to have to edit .htaccess in order to get similar protection. Not that big a deal. This change still makes sense.

sun’s picture

@moshe weitzman: That's why we introduced the cron key. Without a valid one, cron is just a full bootstrap only.

That said - now that it's a page callback, do we need to prevent the page cache from kicking in when page caching is enabled?

Crell’s picture

I've already converted the page callback to return a response object in the kernel branch, and I fully intend to convert page caching to the Kernel component's HttpCache. We can just set the response object to include a no-cache header and it should work fine.

So yes we should exclude it from the cache, but not right now. :-) That will simply get much easier fairly soon, so let's just wait and do it there.

tstoeckler’s picture

Seems like we should open a task for that anyway, with "revisit before release" or whatever, so we don't forget?!

moshe weitzman’s picture

Status: Fixed » Needs review
FileSize
425 bytes

It is a one line patch so rather than open a new major task, lets just fix it. Patch attached.

Crell’s picture

Status: Needs review » Reviewed & tested by the community

I didn't even realize we had that utility function now. OK, that's easy enough that it shouldn't break the kernel.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed the follow-up thanks!http://drupal.org/files/no_cache.patch

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

David_Rothstein’s picture