ixarlie / mutex-bundle
A Symfony bundle for Mutex implementation for PHP
Installs: 23 279
Dependents: 0
Suggesters: 0
Security: 0
Stars: 4
Watchers: 1
Forks: 1
Open Issues: 0
Type:symfony-bundle
Requires
- php: ^8.1
- symfony/config: ^5.4 || ^6.0
- symfony/dependency-injection: ^5.4 || ^6.0
- symfony/event-dispatcher: ^5.4 || ^6.0
- symfony/http-foundation: ^5.4 || ^6.0
- symfony/http-kernel: ^5.4 || ^6.0
- symfony/lock: ^5.4 || ^6.0
Requires (Dev)
- phpunit/phpunit: ^9.5
- roave/security-advisories: dev-latest
- symfony/security-core: ^5.4 || ^6.0
README
This bundle integrates the symfony/lock
capabilities into kernel.controller
events.
For previous releases with arvenil/ninja-mutex
dependency follow the version 1
Before continuing, please read the following links for more information.
Install
composer require ixarlie/mutex-bundle "^2.1"
Add the bundle in the kernel class:
$bundles = [ // ... IXarlie\MutexBundle\IXarlieMutexBundle::class => ['all' => true], // ... ];
Configuration
# Symfony lock configuration framework: lock: main: flock alt: semaphore
i_xarlie_mutex: # Add the Symfony lock factories services id factories: - 'lock.default.factory' - 'lock.main.factory' - 'lock.alt.factory'
Locking Strategy
This bundle ships 3 different locking strategies:
-
block
(BlockLockingStrategy
)It attempts to acquire the lock. If the lock is already acquired then an exception is thrown. This strategy does not block until the release of the lock.
-
force
(ForceLockingStrategy
)It acquires the lock. Whether the lock is acquired, it forces a release before acquire it.
-
queue
(QueueLockingStrategy
)It attempts to acquire the lock. Whether the lock is acquired, this strategy will wait until the release of the lock. The
queue
strategy will work depending on theservice
configuration.Read
Blocking
section in Symfony Docs
You can implement your own LockingStrategy
classes. Use the tag ixarlie_mutex.strategy
in your services to register
them in the LockExecutor
service.
services: app.mutex_locking_strategy: class: App\Mutex\LockingStrategy tags: - { name: ixarlie_mutex.strategy }
Naming Strategy
The name
option is not required in the annotation. However, a name is mandatory in order to create a LockInterface
instance.
This bundle ships 2 naming strategies:
DefaultNamingStrategy
, if aname
is not set in the annotation, this class will use the request information.UserIsolationNamingStrategy
, if theuserIsolation
is enabled, this class will append the token user information to thename
value. It decoratesDefaultNamingStrategy
.
You can implement your own NamingStrategy
.
- Decorating
ixarlie_mutex.naming_strategy
(recommended)
services: app.mutex_naming_strategy: class: App\Mutex\NamingStrategy decorates: 'ixarlie_mutex.naming_strategy' arguments: ['app.mutex_naming_strategy.inner']
- Replacing the alias definition
ixarlie_mutex.naming_strategy
with your own service id. This will execute only your logic.
services: app.mutex_naming_strategy: class: App\Mutex\NamingStrategy ixarlie_mutex.naming_strategy: alias: app.mutex_naming_strategy
Annotation
The MutexRequest
annotation can be used only on controller methods.
Options
service
(required)
The lock factory service name. It should be one of the services listed in the factories
setting.
Examples:
framework: lock: semaphore i_xarlie_mutex: factories: - 'lock.default.factory'
#[MutexRequest(service: 'lock.default.factory')]
framework: lock: main_lock: flock secondary_lock: semaphore i_xarlie_mutex: factories: - 'lock.main_lock.factory'
#[MutexRequest(service: 'lock.main_lock.factory')]
strategy
(required)
One of the registered locking strategies. Read the Locking Strategy
section.
Examples:
#[MutexRequest(service: 'lock.default.factory', strategy: 'block')] #[MutexRequest(service: 'lock.default.factory', strategy: 'queue')] #[MutexRequest(service: 'lock.default.factory', strategy: 'force')]
name
(optional)
The lock's name. If no name is provided, the name will be generated using the registered naming strategies.
Note: Read userIsolation
option to know how it affects to the name.
Note: The prefix ixarlie_mutex_
is prefixed to the name.
Note: The naming strategy output is md5 hashed to avoid any issue with some PersistingStoreInterface implementations.
Examples:
#[MutexRequest(service: 'lock.default.factory', strategy: 'block')] #[MutexRequest(service: 'lock.default.factory', strategy: 'block', name: 'lock_name')]
message
(optional)
This is a custom message for the exception in case the lock cannot be acquired.
Examples:
#[MutexRequest(service: 'lock.default.factory', strategy: 'block', message: 'Busy!')]
userIsolation
(optional, default: false)
This option will add token user context to the name
option in order to have isolated locks for different users.
Example:
#[MutexRequest(service: 'lock.default.factory', strategy: 'block', userIsolation: true)]
Note: If security.token_storage
is not available and userIsolation
is set to true, an exception will be thrown.
Note: Be aware about using userIsolation
in anonymous routes.
ttl
(optional)
Maximum expected lock duration in seconds.
Example:
use IXarlie\MutexBundle\MutexRequest; class MyController { #[MutexRequest( service: 'lock.default.factory', strategy: 'block', name: 'action_name', userIsolation: true, message: 'Busy!', ttl: 20.0 )] public function foo() { return []; } }