Skip to content

plan2net/safe-config-manager

Repository files navigation

Safe Configuration Manager for TYPO3 CMS

A thread-safe configuration manager extension for TYPO3 CMS that extends the core ConfigurationManager with built-in locking mechanisms to prevent race conditions during configuration read/write operations.

Background

In TYPO3, the ConfigurationManager is responsible for managing system configurations.

However, in multiprocess environments (like web servers), concurrent access to configuration files can lead to race conditions, file corruption, or lost updates if not properly synchronized. This is especially problematic when multiple processes attempt to read from or write to the same configuration file at the same time.

The most obvious problem then is this core exception you might encounter randomly:

Uncaught TYPO3 Exception: TYPO3\CMS\Core\Configuration\ConfigurationManager::getLocalConfiguration(): Return value must be of type array, int returned | TypeError thrown in file /var/www/html/vendor/typo3/cms-core/Classes/Configuration/ConfigurationManager.php in line 121.

Features

  • Thread-safe configuration access: Uses TYPO3's built-in locking API to prevent race conditions
  • Shared locks for reading: Multiple processes can read configuration simultaneously
  • Exclusive locks for writing: Ensures only one process can modify configuration at a time
  • Atomic writes: Uses temporary files and atomic moves to prevent corruption
  • Configurable timeouts: Adjustable lock timeout with exponential backoff
  • Compatible with TYPO3 13.4 LTS and 14.3: Tested against the matching Bootstrap patches shipped with the extension
  • Replaces the core ConfigurationManager: Wired in via a small Bootstrap core patch (see Installation)

Installation

Add the extension to your TYPO3 project:

composer require plan2net/safe-config-manager

As the ConfigurationManager is directly instantiated by TYPO3 through the new keyword (no DI container involvement), you have to patch the core Bootstrap class to use the SafeConfigurationManager instead.

The extension ships ready-to-apply patches for each supported TYPO3 major version:

  • patches/typo3-cms-core-13-bootstrap-safe-config-manager.patch — TYPO3 13.4 LTS
  • patches/typo3-cms-core-14-bootstrap-safe-config-manager.patch — TYPO3 14.3

Both wrap the replacement in a class_exists check, so the original ConfigurationManager is still used if the extension is ever disabled.

Use the "cweagans/composer-patches" plugin to apply the patch automatically during composer install. Pick the patch matching your TYPO3 major and reference it from your project's composer.json:

{
  "extra": {
    "patches": {
      "typo3/cms-core": {
        "Use SafeConfigurationManager for thread-safe configuration handling": "vendor/plan2net/safe-config-manager/patches/typo3-cms-core-13-bootstrap-safe-config-manager.patch"
      }
    }
  }
}

How It Works

Locking Strategy

The SafeConfigurationManager uses TYPO3's LockingStrategyInterface to provide:

  • Shared locks (LOCK_CAPABILITY_SHARED) for read operations (getLocalConfiguration()) — multiple readers run in parallel.
  • Exclusive locks (LOCK_CAPABILITY_EXCLUSIVE) for write operations (writeLocalConfiguration(), updateLocalConfiguration()) — writers serialize against readers and against each other.
  • Single exclusive lock around read-modify-write cycles for setLocalConfigurationValueByPath(), setLocalConfigurationValuesByPathValuePairs(), removeLocalConfigurationKeysByPath(), enableFeature(), and disableFeature() — without this, two concurrent updates could each read the old configuration and overwrite each other's changes.
  • Non-blocking acquire with bounded retry — acquire() is called with LOCK_CAPABILITY_NOBLOCK in an exponential-backoff loop, capped by the configured lockTimeout.

Atomic Writes

All write operations use atomic file operations:

  1. Write to a temporary file
  2. Perform atomic rename to final location
  3. Clear opcache for the configuration file
  4. Clean up temporary files on failure

Lock Identifiers

A single lock identifier is used per configuration file:

  • safe_config_manager_<md5 of configuration file path>

All operations contend for this one identifier; the SHARED or EXCLUSIVE mode passed to acquire() differentiates intent. Using a separate identifier per operation would put readers and writers on different locks and make the shared/exclusive distinction inert.

Configuration

Lock Timeout

Configure the default lock timeout in ext_localconf.php or AdditionalConfiguration.php:

$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['safe_config_manager']['lockTimeout'] = 15; // seconds

Locking Strategy Priority

You can configure which locking strategy to prefer:

// Prefer FileLockStrategy (default: 75)
$GLOBALS['TYPO3_CONF_VARS']['SYS']['locking']['strategies'][\TYPO3\CMS\Core\Locking\FileLockStrategy::class]['priority'] = 100;

// Configure custom lock directory
$GLOBALS['TYPO3_CONF_VARS']['SYS']['locking']['strategies'][\TYPO3\CMS\Core\Locking\FileLockStrategy::class]['lockFileDir'] = 'safe_config_locks';

Compatibility

  • TYPO3 Version: 13.4 LTS, 14.3
  • PHP Version: 8.2+
  • Locking Strategies: All TYPO3 core locking strategies supported
  • File Systems: Compatible with local and network file systems

Troubleshooting

Lock Timeout Errors

If you see LockAcquireException errors:

  1. Increase the lock timeout:

    $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['safe_config_manager']['lockTimeout'] = 30;
  2. Check for deadlocks in your configuration update logic

  3. Monitor lock file directory permissions and disk space

Performance Issues

  1. Use appropriate locking strategy for your environment:

    • Local filesystems: FileLockStrategy (default)
    • Network filesystems: SemaphoreLockStrategy or SimpleLockStrategy
  2. Avoid frequent configuration updates in tight loops

  3. Use bulk operations (setLocalConfigurationValuesByPathValuePairs) instead of multiple single updates

License

GPL-2.0-or-later

Author

plan2net GmbH - https://www.plan2.net

About

Thread-safe configuration manager for TYPO3 CMS that extends the core ConfigurationManager with built-in locking mechanisms

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages