-
-
Save mikemadisonweb/147d2b30f8d4e560c2f6c1a3d5f17cdd to your computer and use it in GitHub Desktop.
Yii2 console controller behavior. Prevents double run console command
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace console\controllers\behaviors; | |
use Yii; | |
use yii\base\ActionEvent; | |
use yii\base\Behavior; | |
use yii\base\Exception; | |
use yii\console\Controller; | |
/** | |
* Предотвращает одновременный запуск нескольких инстансов консольной команды | |
* Class OneInstanceBehavior | |
* @package console\components | |
*/ | |
class OneInstanceBehavior extends Behavior | |
{ | |
/** | |
* If process executes more than $longRunningTimeout seconds, | |
* it will be considered as long-running | |
* and warning message will be logged | |
* @var int seconds | |
*/ | |
public $longRunningTimeout = 3600; | |
/** | |
* Start command if there isn't another active instance | |
* @var bool | |
*/ | |
public $nonFailureShutdown = true; | |
/** | |
* @var string | |
*/ | |
protected $lockFileName; | |
/** | |
* @return array | |
*/ | |
public function events() | |
{ | |
return [ | |
Controller::EVENT_BEFORE_ACTION => 'checkInstance', | |
Controller::EVENT_AFTER_ACTION => 'cleanUp', | |
]; | |
} | |
/** | |
* @param ActionEvent $event | |
* @throws Exception | |
*/ | |
public function checkInstance($event) | |
{ | |
$this->lockFileName = Yii::$app->runtimePath . '/' . str_replace('/', '-', $event->action->uniqueId) . '.lock'; | |
if (file_exists($this->lockFileName)) { | |
$processExists = file_exists('/proc/' . trim(file_get_contents($this->lockFileName))); | |
if ($processExists) { | |
$event->isValid = false; | |
if (filemtime($this->lockFileName) + $this->longRunningTimeout < time()) { | |
throw new Exception("{$event->action->uniqueId} sleeped since " . | |
date('r', filemtime($this->lockFileName))); | |
} | |
} else { | |
if ($this->nonFailureShutdown) { | |
@unlink($this->lockFileName); | |
} else { | |
$event->isValid = false; | |
throw new Exception("{$event->action->uniqueId} failed since " . | |
date('r', filemtime($this->lockFileName))); | |
} | |
} | |
} else { | |
if (!file_put_contents($this->lockFileName, posix_getpid())) { | |
throw new Exception('Can\'t write lock file ' . $this->lockFileName); | |
} | |
} | |
} | |
/** | |
* @param ActionEvent $event | |
*/ | |
public function cleanUp($event) | |
{ | |
if ($event->result == 0) { | |
@unlink($this->lockFileName); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment