diff --git a/.travis.yml b/.travis.yml index 5d6fcbf..ef56f35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,8 @@ language: php +services: + - mysql + php: - 7.0 - 7.1 @@ -36,6 +39,7 @@ matrix: branches: only: - master + - 2.x before_script: - git clone -b master https://github.com/Oefenweb/travis --depth 1 ../travis diff --git a/Console/Command/QueueShell.php b/Console/Command/QueueShell.php index b583bfa..c970519 100644 --- a/Console/Command/QueueShell.php +++ b/Console/Command/QueueShell.php @@ -2,6 +2,7 @@ App::uses('Folder', 'Utility'); App::uses('QueuedTask', 'Model'); App::uses('AppShell', 'Console/Command'); +App::uses('CakeText', 'Utility'); declare(ticks = 1); @@ -119,7 +120,14 @@ public function getOptionParser() { ])->addSubcommand('runworker', [ 'help' => __d('queue', 'Run a queue worker.'), 'parser' => [ - 'description' => [__d('queue', 'Run a queue worker, which will look for a pending task it can execute.')] + 'description' => [__d('queue', 'Run a queue worker, which will look for a pending task it can execute.')], + 'options' => [ + 'type' => [ + 'short' => 't', + 'help' => 'Type (comma separated list possible)', + 'default' => null + ] + ] ] ])->addSubcommand('stats', [ 'help' => __d('queue', 'Display general statistics.'), @@ -204,10 +212,14 @@ public function runworker() { $this->__exit = false; $workerStartTime = time(); + + $typesParam = $this->param('type'); + $types = is_string($typesParam) ? $this->_stringToArray($typesParam) : []; + while (!$this->__exit) { $this->out(__d('queue', 'Looking for a job.'), 1, Shell::VERBOSE); - $data = $this->QueuedTask->requestJob($this->_getTaskConf()); + $data = $this->QueuedTask->requestJob($this->_getTaskConf(), $types); if ($this->QueuedTask->exit === true) { $this->__exit = true; } else { @@ -381,4 +393,25 @@ public function signalHandler($signalNumber) { } } +/** + * Converts string to array + * + * @param string|null $param String to convert + * @return array + */ + protected function _stringToArray(string $param = null) : array { + if (!$param) { + return []; + } + + $array = CakeText::tokenize($param); + if (is_string($array)) { + return [ + $array + ]; + } + + return array_filter($array); + } + } diff --git a/Model/QueuedTask.php b/Model/QueuedTask.php index 360608d..fdd8f9f 100644 --- a/Model/QueuedTask.php +++ b/Model/QueuedTask.php @@ -42,9 +42,10 @@ public function createJob($taskName, $data, $notBefore = null) { * Looks for a new job that can be processed with the current abilities * * @param array $capabilities Available queue worker tasks. + * @param array $types Request a job from these types (or exclude certain types), or any otherwise. * @return mixed Job data or false. */ - public function requestJob($capabilities) { + public function requestJob($capabilities, array $types = []) { $idlist = []; $wasFetched = []; @@ -64,6 +65,10 @@ public function requestJob($capabilities) { ]; $limit = Configure::read('Queue.workers'); + if ($types) { + $conditions = $this->_addFilter($conditions, 'task', $types); + } + // Generate the job specific conditions. foreach ($capabilities as $task) { list($plugin, $name) = pluginSplit($task['name']); @@ -179,7 +184,7 @@ public function getLength($taskName = null) { * @return array A list of task names */ public function getTypes() { - $fields = ['task']; + $fields = ['task', 'task']; $group = ['task']; return $this->find('list', compact('fields', 'group')); @@ -246,4 +251,33 @@ public function cleanFailedJobs($capabilities) { return $this->deleteAll($conditions, false); } +/** + * Filters field `key` based on the provided values. Values prefixed with '-' are excluded. + * + * @param array $conditions Conditions + * @param string $key Key + * @param array $values Values + * @return array the conditions + */ + protected function _addFilter(array $conditions, $key, array $values) : array { + $include = []; + $exclude = []; + foreach ($values as $value) { + if (substr($value, 0, 1) === '-') { + $exclude[] = substr($value, 1); + } else { + $include[] = $value; + } + } + + if ($include) { + $conditions[$key . ' IN'] = $include; + } + if ($exclude) { + $conditions[$key . ' NOT IN'] = $exclude; + } + + return $conditions; + } + } diff --git a/README.md b/README.md index 17518ca..6298947 100644 --- a/README.md +++ b/README.md @@ -73,3 +73,16 @@ Console/cake Queue.queue clean; # Manually call cleanup_failed function to delete task data of failed tasks. Console/cake Queue.queue clean_failed; ``` + +#### Running only specific tasks per worker +You can filter "running" by type: + +``` +Console/cake Queue.queue runworker -t MyType,AnotherType,-ThisOneToo +Console/cake Queue.queue runworker -t "-ThisOneNot" +``` + +Use `-` prefix to exclude. Note that you might need to use `""` around the value then to avoid it being seen as option key. + +That can be helpful when migrating servers and you only want to execute certain ones on the new system or want to test specific servers. +