20

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?

30

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');
0
10

Thanks to Shawns answer..

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

Seemed to help!

3
  • Does not work (D8.8.5). May 17 '20 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 Jun 23 '20 at 3:48
  • 1
    drush sqlq "DELETE FROM semaphore WHERE name = 'cron';" works
    – Pere
    Mar 26 at 15:20
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.)

0

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")'
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.
    – apaderno
    Dec 17 '17 at 17:05
  • In fact, Drupal 7 itself uses lock_release('cron') to release the cron lock.
    – apaderno
    Dec 17 '17 at 17:07
0

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();

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.