任何终止

时间:2017-02-28 10:48:04

标签: php laravel-5.3 artisan

我有一个Laravel 5.3命令的以下(简单)锁码:

private $hash = null;
public final function handle() {
    try { 
        $this->hash = md5(serialize([ static::class, $this->arguments(), $this->options() ]));
        $this->info("Generated signature ".$this->hash,"v");

        if (Redis::exists($this->hash)) {
            $this->hash = null;
            throw new \Exception("Method ".$this->signature." is already running");
        }            
        Redis::set($this->hash, true);                                    
        $this->info("Running method","vv");
        $this->runMutuallyExclusiveCommand(); //Actual command is not important here
        $this->cleanup();
    } catch (\Exception $e) {
        $this->error($e->getMessage());
    } 
}

public function cleanup() {
    if (is_string($this->hash)) {
        Redis::del($this->hash);
    }
}

如果允许命令正常执行其执行周期(包括处理PHP异常时),这可以正常工作。但是,当通过其他方式(例如CTRL-C或终端窗口关闭)中断命令时会出现问题。在这种情况下,不运行清理代码,并且命令被认为仍然是"正在执行"所以我需要从缓存中手动删除该条目才能重新启动它。我尝试在cleanup函数中运行__destruct代码,但似乎也没有调用。

我的问题是,有没有办法设置一些代码在终止命令时运行,无论它是如何被终止的?

1 个答案:

答案 0 :(得分:1)

简短的回答是否定的。当您通过Ctrl-C终止正在运行的进程或只是关闭终端时,您将终止它。您需要在shell中有一个链接到清理代码的中断,但这超出了范围。

但是还有其他选择。 Cron作业可以间歇运行,以执行清理任务和其他有用的事情。您还可以创建一个在当前代码之前运行的启动例程。当您执行启动例程时,它可以为您执行清理,然后调用当前例程。我相信你最好的办法是使用一个只按给定间隔运行的cron作业,然后在缓存中查找不再合适的条目,然后清除它们。这是一个很好的网站,可以帮助您开始使用cron jobs https://www.linux.com/learn/scheduling-magic-intro-cron-linux