ixarlie / mutex-bundle
PHP Mutex 实现的 Symfony 扩展包
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
此扩展包将 symfony/lock
的功能集成到 kernel.controller
事件中。
对于之前版本,包含 arvenil/ninja-mutex
依赖的,请遵循 版本 1
在继续之前,请阅读以下链接以获取更多信息。
安装
composer require ixarlie/mutex-bundle "^2.1"
在内核类中添加扩展包
$bundles = [ // ... IXarlie\MutexBundle\IXarlieMutexBundle::class => ['all' => true], // ... ];
配置
# 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'
锁定策略
此扩展包提供了3种不同的锁定策略
-
block
(BlockLockingStrategy
)尝试获取锁。如果锁已经被获取,则抛出异常。此策略不会在锁释放之前阻塞。
-
force
(ForceLockingStrategy
)获取锁。无论是否获取到锁,都会在获取锁之前强制释放。
-
queue
(QueueLockingStrategy
)尝试获取锁。无论是否获取到锁,此策略将等待直到锁被释放。根据
service
配置,队列策略将生效。阅读Symfony 文档中的
Blocking
部分
您可以实现自己的 LockingStrategy
类。使用标签 ixarlie_mutex.strategy
在您的服务中注册它们到 LockExecutor
服务。
services: app.mutex_locking_strategy: class: App\Mutex\LockingStrategy tags: - { name: ixarlie_mutex.strategy }
命名策略
在注解中不需要 name
选项。然而,为了创建一个 LockInterface
实例,必须提供一个名称。
此扩展包提供了2种命名策略
DefaultNamingStrategy
,如果注解中没有设置name
,则此类将使用请求信息。UserIsolationNamingStrategy
,如果启用了userIsolation
,则此类将在name
值中附加用户令牌信息。它装饰了DefaultNamingStrategy
。
您可以实现自己的 NamingStrategy
。
- 装饰
ixarlie_mutex.naming_strategy
(推荐)
services: app.mutex_naming_strategy: class: App\Mutex\NamingStrategy decorates: 'ixarlie_mutex.naming_strategy' arguments: ['app.mutex_naming_strategy.inner']
- 用您自己的服务 id 替换别名定义
ixarlie_mutex.naming_strategy
。这将只执行您的逻辑。
services: app.mutex_naming_strategy: class: App\Mutex\NamingStrategy ixarlie_mutex.naming_strategy: alias: app.mutex_naming_strategy
注解
仅可以在控制器方法上使用 MutexRequest
注解。
选项
service
(必需)
锁工厂服务名称。它应该是 factories
设置中列出的服务之一。
示例
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
(必需)
已注册的锁定策略之一。请参阅 锁定策略
部分。
示例
#[MutexRequest(service: 'lock.default.factory', strategy: 'block')] #[MutexRequest(service: 'lock.default.factory', strategy: 'queue')] #[MutexRequest(service: 'lock.default.factory', strategy: 'force')]
name
(可选)
锁的名称。如果没有提供名称,将使用已注册的命名策略生成名称。
注意:阅读 userIsolation
选项以了解它如何影响名称。
注意:名称前会添加前缀 ixarlie_mutex_
。
注意:命名策略输出是经过 md5 哈希的,以避免与某些 PersistingStoreInterface 实现相关的任何问题。
示例
#[MutexRequest(service: 'lock.default.factory', strategy: 'block')] #[MutexRequest(service: 'lock.default.factory', strategy: 'block', name: 'lock_name')]
message
(可选)
这是当无法获取锁时的自定义异常消息。
示例
#[MutexRequest(service: 'lock.default.factory', strategy: 'block', message: 'Busy!')]
userIsolation
(可选,默认:false)
此选项将为 name
选项添加令牌用户上下文,以便为不同的用户提供隔离锁。
示例
#[MutexRequest(service: 'lock.default.factory', strategy: 'block', userIsolation: true)]
注意:如果security.token_storage
不可用且userIsolation
设置为true,将抛出异常。
请注意在匿名路由中使用userIsolation
。
ttl
(可选)
最大期望锁持续时长(秒)。
示例
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 []; } }