22

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?

6 Answers 6

34

It's now in the semaphore table with the key name "cron". This can be removed via

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

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

\Drupal::lock()->release('cron');
0
9

Thanks to Shawns answer..

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

Seemed to help!

4
  • 1
    Does not work (D8.8.5). Commented May 17, 2020 at 22:44
  • It didn't work for me either, but then I tried drush php-eval "\Drupal::lock()->acquire('cron', 10);" first a couple of times and finally could call drush php-eval "\Drupal::lock()->release('cron');" to release the stuck lock Commented Jun 23, 2020 at 3:48
  • 3
    drush sqlq "DELETE FROM semaphore WHERE name = 'cron';" works
    – Pere
    Commented Mar 26, 2021 at 15:20
  • Trying to release another lock and running into issues? Try drush php-eval "\Drupal::service('lock.persistent')->release('my_lock_id); Commented Jul 17 at 18:33
2

If you can't get it to work in Drupal 8 with the suggested steps from above - perhaps you are using something like Redis and the cron lock is stored there. In this case you can progress with:

drush php-eval '\Drupal::service("lock")->release("all")'
1

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.)

1

In Drupal 8.9.x - I tried the below Drush commands & manually deleted the semaphore table. But, nothing is happening.

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

  drush php:eval '\Drupal::lock()->release("cron");'
  drush php-eval "\Drupal::lock()->release('cron');"
  drush php-eval '\Drupal::service("lock")->release("all")'
    
  DELETE FROM semaphore WHERE name = 'cron';

  drush php-eval "\Drupal::lock()->acquire('cron', 10);" 
  I ran first a couple of times and then I did 
  drush php-eval "\Drupal::lock()->release('cron');"

Finally I got the Solution. Run individual cron jobs with Drush. I ran the command one by one. then it works.

drush php-eval "webform_cron();"
drush php-eval "update_cron();" 
drush php-eval "system_cron();" 
drush php-eval "statistics_cron();"
drush php-eval "node_cron();"
drush php-eval "locale_cron();" 
drush php-eval "history_cron();" 
drush php-eval "file_cron();" 
drush php-eval "field_cron();" 
drush php-eval "dblog_cron();" 
drush php-eval "comment_cron();
0

I got to this error when the Drupal 7 installation stuck. I fixed it by using drush php-eval "drupal_cron_cleanup()".

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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