olafnorge/console-mutex

此包已被废弃,不再维护。作者建议使用illuminated/console-mutex包。

防止Laravel控制台命令重叠。

1.4.5 2017-04-19 15:08 UTC

README

Latest Stable Version Latest Unstable Version Total Downloads License

防止Laravel控制台命令重叠。

目录

要求

  • PHP >=5.5.9
  • Laravel >=5.1

使用方法

  1. 通过composer安装包

    composer require olafnorge/console-mutex
  2. 使用olafnorge\Console\WithoutOverlapping特质

    use olafnorge\Console\WithoutOverlapping;
    
    class ExampleCommand extends Command
    {
        use WithoutOverlapping;
    
        // ...
    }

策略

可以通过多种策略来防止重叠

  • file(默认)
  • mysql
  • redis
  • memcached

对于部署在单个服务器上的小型应用,默认的file策略就足够好了。如果您的应用更加复杂,例如部署在多个节点上,那么您可能希望使用其他互斥策略。

您可以通过指定$mutexStrategy字段来更改互斥策略

class ExampleCommand extends Command
{
    use WithoutOverlapping;

    protected $mutexStrategy = 'mysql';

    // ...
}

或者通过使用setMutexStrategy方法

class ExampleCommand extends Command
{
    use WithoutOverlapping;

    public function __construct()
    {
        parent::__construct();

        $this->setMutexStrategy('mysql');
    }

    // ...
}

高级

设置自定义超时

默认情况下,互斥锁会检查是否有正在运行的命令,如果找到,则直接退出。但是,您可以手动设置互斥锁的超时时间,使其等待另一个命令完成执行,而不是立即退出。

您可以通过指定$mutexTimeout字段来更改互斥锁超时时间

class ExampleCommand extends Command
{
    use WithoutOverlapping;

    protected $mutexTimeout = 3000; // milliseconds

    // ...
}

或者通过使用setMutexTimeout方法

class ExampleCommand extends Command
{
    use WithoutOverlapping;

    public function __construct()
    {
        parent::__construct();

        $this->setMutexTimeout(3000); // milliseconds
    }

    // ...
}

$mutexTimeout字段有三个可能的选项

  • 0 - 不等待检查(默认);
  • {milliseconds} - 检查,并等待最多指定的毫秒数;
  • null - 等待,直到正在运行的命令完成执行;

处理多个命令

有时为多个命令设置共同的互斥锁很有用。您可以通过设置相同的互斥锁名称轻松实现这一点。默认情况下,互斥锁名称基于命令名称和参数生成。要更改此设置,只需在您的命令中覆盖getMutexName方法即可。

class ExampleCommand extends Command
{
    use WithoutOverlapping;

    public function getMutexName()
    {
        return "icmutex-for-command1-and-command2";
    }

    // ...
}

故障排除

包含特质但无反应?

注意,WithoutOverlapping特质会覆盖initialize方法

trait WithoutOverlapping
{
    protected function initialize(InputInterface $input, OutputInterface $output)
    {
        $this->initializeMutex();
    }

    // ...
}

如果您的命令也覆盖了initialize方法,那么您应该自己调用initializeMutex方法

class ExampleCommand extends Command
{
    use WithoutOverlapping;

    protected function initialize(InputInterface $input, OutputInterface $output)
    {
        $this->initializeMutex();

        $this->foo = $this->argument('foo');
        $this->bar = $this->argument('bar');
        $this->baz = $this->argument('baz');
    }

    // ...
}

多个特质冲突?

如果您正在使用一些其他的酷炫的olafnorge/console-%包,那么您可能会遇到“特性冲突”的问题。例如,如果您尝试构建一个可记录命令,该命令可以防止重叠

class ExampleCommand extends Command
{
    use Loggable;
    use WithoutOverlapping;

    // ...
}

您将会遇到致命错误,“特性冲突”,因为这两个特性都覆盖了initialize方法

如果两个特性插入了一个同名的方法,如果没有明确解决冲突,将会产生一个致命错误

但请不要担心,解决方案非常简单。自己覆盖initialize方法,并按照所需顺序初始化特性

class ExampleCommand extends Command
{
    use Loggable;
    use WithoutOverlapping;

    protected function initialize(InputInterface $input, OutputInterface $output)
    {
        $this->initializeMutex();
        $this->initializeLogging();
    }

    // ...
}