{"record":{"id":"035152c6a1bd0fdb","repo":"phalcon/cphalcon","slug":"the-component-name-cannot-be","errorCode":null,"errorMessage":"The component name cannot be '*'","messagePattern":"The component name cannot be '\\*'","errorType":"exception","errorClass":"Phalcon\\Acl\\Exceptions\\ForbiddenWildcard","httpStatus":null,"severity":"error","filePath":"phalcon/Acl/Component.zep","lineNumber":26,"sourceCode":" * file that was distributed with this source code.\n */\n\nnamespace Phalcon\\Acl;\n\nuse Phalcon\\Acl\\Exceptions\\ForbiddenWildcard;\n\n/**\n * This class defines component entity and its description\n */\nclass Component extends AbstractElement implements ComponentInterface\n{\n    /**\n     * Phalcon\\Acl\\Component constructor\n     */\n    public function __construct( string name, string description = null)\n    {\n        if unlikely name === \"*\" {\n            throw new ForbiddenWildcard(\"component\");\n        }\n\n        let this->name = name,\n            this->description = description;\n    }\n}\n","sourceCodeStart":8,"sourceCodeEnd":33,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Acl/Component.zep#L8-L33","documentation":"The Redis session adapter (Phalcon\\Session\\Adapter\\Redis) optionally serializes session access: with 'lockingEnabled' => true, read() must acquire a per-session Redis lock (SET <prefix><id>-lock <token> NX EX <lockExpiry>) before reading. It retries lockRetries times pausing lockWaitTime microseconds between attempts (defaults: 100 x 50,000us = ~5s budget); if every attempt fails because another request holds the lock, AdapterRuntimeError is thrown with the lock key name.","triggerScenarios":"Two concurrent requests sharing a session id where the first holds the lock longer than lockRetries * lockWaitTime (default ~5s): parallel AJAX calls while a slow page renders; a previous request crashed after acquiring but before close()/destroy() released the lock; a lockExpiry (default 30s) longer than the wait budget with a stuck key.","commonSituations":"Dashboards firing many simultaneous same-session XHRs; long-running reports blocking reads; leaked lock keys after PHP-FPM worker kills; locking enabled in production but not in dev, so it only explodes under real concurrency.","solutions":["Raise the wait budget above the longest concurrent request: increase 'lockRetries' and/or 'lockWaitTime'.","Reduce session lock hold time: shorten requests, or serialize same-session AJAX from the browser side.","Set 'lockExpiry' above the longest expected request so the lock survives, and remember a request running past lockExpiry silently loses it (per the class docblock) — tune both together.","Unblock immediately by deleting the stuck key '<prefix><session-id>-lock' in Redis.","If strict serialization is not required, disable it: 'lockingEnabled' => false."],"exampleFix":"// before\n$session = new \\Phalcon\\Session\\Adapter\\Redis(\n    $factory,\n    ['lockingEnabled' => true] // defaults: 100 retries x 50ms ~= 5s budget\n);\n\n// after — budget tuned for slow pages + parallel XHR\n$session = new \\Phalcon\\Session\\Adapter\\Redis(\n    $factory,\n    [\n        'lockingEnabled' => true,\n        'lockRetries'    => 400,    // 400 x 50ms = 20s wait budget\n        'lockWaitTime'   => 50000,\n        'lockExpiry'     => 60,     // > longest expected request\n    ]\n);","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"use Phalcon\\Session\\Adapter\\Exceptions\\AdapterRuntimeError;\n\nsession_start(); // triggers read() -> lock acquisition\n\ntry {\n    $session = new \\Phalcon\\Session\\Adapter\\Redis($factory, $sessionOptions);\n    $manager = new \\Phalcon\\Session\\Manager();\n    $manager->setAdapter($session)->start();\n} catch (AdapterRuntimeError $e) {\n    if (str_contains($e->getMessage(), 'Could not acquire the session lock')) {\n        // lock contention: back off briefly and retry once; longer term,\n        // raise lockRetries/lockWaitTime above the longest concurrent request\n        usleep(250000);\n        $manager->start();\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Set lockRetries/lockWaitTime so the wait budget exceeds your slowest same-session request.","Keep lockExpiry above the longest request, and remember requests running past lockExpiry silently lose the lock (class docblock).","Serialize same-session XHRs client-side to avoid lock queues on dashboards.","Know the recovery key name: '<prefix><session-id>-lock' — deleting it in Redis unblocks a stuck session instantly."],"tags":["session","redis","locking","concurrency"],"backgroundTag":"session-lock-contention","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}