Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stoppable behavior #102

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
102 changes: 102 additions & 0 deletions src/behaviors/StopBehavior.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/

namespace yii\queue\behaviors;

use yii\base\Behavior;
use yii\caching\Cache;
use yii\di\Instance;
use yii\queue\ExecEvent;
use yii\queue\Queue;

/**
* Stoppable behavior allow stopping scheduled jobs in a queue.
*
* This behavior provides a [[stop()]] method, which allows to mark scheduled jobs as "stopped", which
* will prevent their execution.
*
* This behavior should be attached to the [[Queue]] component.
*
* @author Roman Zhuravlev <[email protected]>
* @since 2.0.1
*/
class StopBehavior extends Behavior
{
/**
* @var Cache|array|string the cache instance used to store stopped status.
*/
public $cache = 'cache';
/**
* @var bool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

documentation is missing, its not really clear to me what this switch is for.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The option allows to turn off status usage that is not supported for AMQP driver.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be in the phpdoc.

*/
public $checkWaiting = true;
/**
* @var Queue
* @inheritdoc
*/
public $owner;

/**
* @inheritdoc
*/
public function init()
{
parent::init();
$this->cache = Instance::ensure($this->cache, Cache::class);
}

/**
* @inheritdoc
*/
public function events()
{
return [
Queue::EVENT_BEFORE_EXEC => function (ExecEvent $event) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

making this a beforeExec() method instead of a closure could make it easier to extend this class.

$event->handled = $this->isStopped($event->id);
},
];
}

/**
* Sets stop flag.
*
* @param string $id of a job
* @return bool
*/
public function stop($id)
{
if (!$this->checkWaiting || $this->owner->isWaiting($id)) {
$this->setStopping($id);
return true;
} else {
return false;
}
}

/**
* @param string $id of a job
* @return bool
*/
protected function setStopping($id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably markAsStopped would be a better name.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it make sense.

{
$this->cache->set(__CLASS__ . $id, true);
}

/**
* @param string $id of a job
* @return bool
*/
protected function isStopped($id)
{
if ($this->cache->exists(__CLASS__ . $id)) {
$this->cache->delete(__CLASS__ . $id);
return true;
} else {
return false;
}
}
}