ixarlie/mutex-bundle

PHP Mutex 实现的 Symfony 扩展包

安装量: 22,706

依赖项: 0

建议者: 0

安全性: 0

星标: 4

关注者: 1

分支: 1

开放性问题: 0

类型:symfony-bundle

v2.1.0 2023-01-04 18:43 UTC

README

GitHub Actions Codacy Badge Packagist

此扩展包将 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

  1. 装饰 ixarlie_mutex.naming_strategy (推荐)
services:
    app.mutex_naming_strategy:
        class: App\Mutex\NamingStrategy
        decorates: 'ixarlie_mutex.naming_strategy'
        arguments: ['app.mutex_naming_strategy.inner']
  1. 用您自己的服务 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 [];
    }
}