Очистить консольную команду при любом завершении

У меня есть следующий (простой) код блокировки для команды 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 ответ

Решение

Краткий ответ - нет. Когда вы убиваете запущенный процесс, либо Ctrl-C, либо просто закрывая терминал, вы прекращаете его. Вам нужно иметь прерывание в вашей оболочке, которое ссылается на ваш код очистки, но это выходит за рамки.

Однако есть и другие варианты. Задания Cron могут выполняться с перерывами для выполнения задач очистки и других полезных вещей. Вы также можете создать подпрограмму запуска, которая запускается до вашего текущего кода. Когда вы выполняете процедуру запуска, она может выполнить очистку для вас, а затем вызвать вашу текущую процедуру. Я считаю, что вам лучше всего использовать задание cron, которое просто запускается с заданными интервалами, которое затем ищет записи в кеше, которые больше не подходят, а затем очищает их. Вот достойный сайт, с которого можно начать работу с cron https://www.linux.com/learn/scheduling-magic-intro-cron-linux

Другие вопросы по тегам