craftcms / cms

Build bespoke content experiences with Craft.
https://craftcms.com
Other
3.28k stars 635 forks source link

[4.x]: Could not acquire a lock when updating singles #14871

Closed LinneaHarts closed 6 months ago

LinneaHarts commented 6 months ago

What happened?

Description

I was getting a lot of errors of the form Could not acquire a lock to save a revision for element 60 when trying to apply project config. I turned off versioning on all sections and was able to apply proejct config.

Now I'm trying to turn it back on, and every single is giving me this error on its elementId when I try to turn on revisions.

Steps to reproduce

  1. Navigate to a single section in settings
  2. Check the box to Enable versioning for entries in this section
  3. Save

Expected behavior

Versioning can be turned on

Actual behavior

I get an error:

2024-04-26 08:12:09 [web.ERROR] [craft\errors\MutexException] craft\errors\MutexException: Could not acquire a lock to save a revision for element 60 in /var/www/html/imarc/vendor/craftcms/cms/src/services/Revisions.php:80
Stack trace:
#0 /var/www/html/imarc/vendor/craftcms/cms/src/elements/Entry.php(2072): craft\services\Revisions->createRevision(Object(craft\elements\Entry), NULL, NULL)
#1 /var/www/html/imarc/vendor/craftcms/cms/src/services/Elements.php(3470): craft\elements\Entry->afterPropagate(false)
#2 /var/www/html/imarc/vendor/craftcms/cms/src/services/Elements.php(1107): craft\services\Elements->_saveElementInternal(Object(craft\elements\Entry), false, false, true, Array, false, false)
#3 /var/www/html/imarc/vendor/craftcms/cms/src/services/Sections.php(1544): craft\services\Elements->saveElement(Object(craft\elements\Entry), false)
#4 /var/www/html/imarc/vendor/craftcms/cms/src/services/Sections.php(540): craft\services\Sections->_ensureSingleEntry(Object(craft\models\Section), Array)
#5 /var/www/html/imarc/vendor/craftcms/cms/src/controllers/SectionsController.php(180): craft\services\Sections->saveSection(Object(craft\models\Section))
#6 [internal function]: craft\controllers\SectionsController->actionSaveSection()
#7 /var/www/html/imarc/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#8 /var/www/html/imarc/vendor/yiisoft/yii2/base/Controller.php(178): yii\base\InlineAction->runWithParams(Array)
#9 /var/www/html/imarc/vendor/yiisoft/yii2/base/Module.php(552): yii\base\Controller->runAction('save-section', Array)
#10 /var/www/html/imarc/vendor/craftcms/cms/src/web/Application.php(341): yii\base\Module->runAction('sections/save-s...', Array)
#11 /var/www/html/imarc/vendor/craftcms/cms/src/web/Application.php(642): craft\web\Application->runAction('sections/save-s...', Array)
#12 /var/www/html/imarc/vendor/craftcms/cms/src/web/Application.php(303): craft\web\Application->_processActionRequest(Object(craft\web\Request))
#13 /var/www/html/imarc/vendor/yiisoft/yii2/base/Application.php(384): craft\web\Application->handleRequest(Object(craft\web\Request))
#14 /var/www/html/imarc/web/index.php(22): yii\base\Application->run()
#15 {main} {"memory":14315616,"exception":"[object] (craft\\errors\\MutexException(code: 0): Could not acquire a lock to save a revision for element 60 at /var/www/html/imarc/vendor/craftcms/cms/src/services/Revisions.php:80)"} 

Additional Information

Craft: 4.8.10 (though it was happening for previous versions as well) Plugins:

Craft CMS version

4.8.10

PHP version

8.1

Operating system and version

Mac, Linux

Database type and version

MySQL, Mariadb

Image driver and version

No response

Installed plugins and versions

Admin Bar 4.3.0 Asset Usage 3.3.0 Blitz 4.16.3 CKEditor 3.8.3 CodeMirror 2.0.0 Colorit 4.0.0 Element API 4.1.0 Field Manager 3.0.8 HOMM XML Sitemap 1.0.3 Hyper 1.1.27 Imager X Lite 4.4.0 Inlin Mix 1.7.1 Retcon 2.7.5 Retour 4.1.16 SuperTable 3.0.13

brandonkelly commented 6 months ago

I’m not able to reproduce this.

It could be that a previous mutex lock wasn’t released properly, for that single section’s entry.

Are you overriding the mutex component config from config/app.php? If so, please post the custom config. Or you could try just removing it entirely, since you’ll generally be better off with Craft’s default mutex config, especially since Craft 4.6.0.

LinneaHarts commented 6 months ago

Commenting out my mutex override fixed this. Thank you!

LinneaHarts commented 6 months ago

Before you close this, do we still need redis for multi-server sites? I had the code below, with the mutex commented out now, as you said.

use craft\helpers\App;

$cache = [
    'class' => yii\redis\Cache::class,
    'defaultDuration' => 86400,
    'keyPrefix' => App::env('REDIS_KEY_PREFIX'),
];

$enable_replicas = App::env('REDIS_ENABLE_REPLICAS');
if ($enable_replicas && strtolower($enable_replicas) !== 'false') {
    $cache['enableReplicas'] = true;
    $cache['replicas'] = ['redis'];

    $rep_1 = App::env('REDIS_REPLICA_1');

    if (strlen($rep_1)) {
        array_push($cache['replicas'], ['hostname' => $rep_1]);
    }

    $rep_2 = App::env('REDIS_REPLICA_2');
    if (strlen($rep_2)) {
        array_push($cache['replicas'], ['hostname' => $rep_2]);
    }
}

return [
    'modules' => [
        'my-module' => \modules\Module::class,
        'protect' => \modules\Protect::class,
        'external-cache-busting' => \modules\ExternalCacheBusting::class,
    ],
    'bootstrap' => [
        'my-module',
        'protect',
        'external-cache-busting',
    ],
    'components' => [
        'redis' => [
            'class' => 'yii\redis\Connection',
            'hostname' => App::env('REDIS_HOSTNAME') ?: 'redis',
            'port' => App::env('REDIS_PORT') ?: 6379,
            'database' => App::env('REDIS_DATABASE') ?: 0,
        ],
         'cache' => $cache,
        // 'mutex' => [
        //     'class' => 'yii\redis\Mutex',
        // ],
    ],
];
brandonkelly commented 6 months ago

Nope! As of 4.6 it’s fine to use the built-in mutex driver on multi-server sites :)