13

I ran cron and aborted the execution. Now I get this message:

Attempting to re-run cron while it is already running.

In Drupal 7, I could delete the cron_semaphore variable.

What's the way to achieve the same in Drupal 8?

22

It's now in the semaphore table with the key name "cron". This can be removed via a drush sqlq "DELETE FROM semaphore WHERE name = 'cron';" command.

Or, if you can execute PHP in Drupal bootstrapped environment, you can run the line:

\Drupal::lock()->release('cron');
  • 1
    drush php:eval '\Drupal::lock()->release("cron");' – gogowitsch Jul 14 '18 at 18:17
7

Thanks to Shawns answer..

drush php-eval "\Drupal::lock()->release('cron');"

Seemed to help!

1

For Drupal 8 run:

drush sqlq "DELETE FROM semaphore WHERE name = 'cron';"
0

Got to this page when my D7 installation stuck. I released it by using

php-eval "drupal_cron_cleanup()"

  • The question is for Drupal 8, not Drupal 7. Furthermore, in Drupal 7 that function is marked deprecated. – kiamlaluno Dec 17 '17 at 17:05
  • In fact, Drupal 7 itself uses lock_release('cron') to release the cron lock. – kiamlaluno Dec 17 '17 at 17:07
0

Drupal 7 doesn't anymore uses the cron_semaphore variable, but a lock. See drupal_cron_run(), and in particular the following lines, part of that function.

// Try to acquire cron lock.
if (!lock_acquire('cron', 240.0)) {
  // Omissis
}
// Release cron lock.
lock_release('cron');

Porting those lines to Drupal 8 is quite straight, since Drupal 8 has a service for getting and releasing a lock.

The equivalent code is in Cron::run().

// Try to acquire cron lock.
if (!$this->lock->acquire('cron', 900.0)) {
  // Omissis
}
// Release cron lock.
$this->lock->release('cron');

If you need to unlock it in a host where you cannot use Drush, as it happens to me, to achieve the same from an external script that bootstraps Drupal would require code similar to the following one.

use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Drupal\Core\Site\Settings;

chdir('..');

$autoloader = require_once 'autoload.php';

function cron_unlock_access_allowed(Request $request) {
  $account = \Drupal::service('authentication')->authenticate($request);
  if ($account) {
    \Drupal::currentUser()->setAccount($account);
  }
  return \Drupal::currentUser()->hasPermission('administer site configuration');
}

try {
  $request = Request::createFromGlobals();
  $kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
  $kernel->prepareLegacyRequest($request);
}
catch (HttpExceptionInterface $e) {
  $response = new Response('', $e->getStatusCode());
  $response->prepare($request)->send();
  exit;
}

\Drupal::moduleHandler()->addModule('system', 'core/modules/system');
\Drupal::moduleHandler()->addModule('user', 'core/modules/user');
\Drupal::moduleHandler()->load('system');
\Drupal::moduleHandler()->load('user');

if (cron_unlock_access_allowed($request)) {
  \Drupal::lock()->release('cron');
  $status_code = 200;
}
else {
  $status_code = 403;
}
$response = new Response('', $status_code);
$response->prepare($request)->send();

I adapted the code of authorize.php. I changed the user permission required to run the script, which I placed in the directory containing the authorize.php file, in the cron_cleanup.php file.

If you can run Drush, it gets easier. (See @dman's answer.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.