From 37bf42a2ea97c9fe148479efceb43134a6903fae Mon Sep 17 00:00:00 2001 From: Marco Manieri Date: Wed, 29 Jul 2015 12:53:52 +0200 Subject: [PATCH 1/8] Patched for cakePHP3: - Resque_Job_Creator can return an array containing the class instance, the class method to invoke and the arguments to be passed to it, and the beforePerform and tearDown methods' names Improved Exceptions message expliciting "Resque_Job_Creator not loaded" --- lib/Resque/Job.php | 61 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/lib/Resque/Job.php b/lib/Resque/Job.php index ef7191b..0969258 100755 --- a/lib/Resque/Job.php +++ b/lib/Resque/Job.php @@ -161,7 +161,7 @@ public function getInstance() } else { if(!class_exists($this->payload['class'])) { throw new Resque_Exception( - 'Could not find job class ' . $this->payload['class'] . '.' + 'Could not find job class ' . $this->payload['class'] . ' (Resque_Job_Creator not loaded).' ); } @@ -173,9 +173,18 @@ public function getInstance() $this->instance = new $this->payload['class'](); } - $this->instance->job = $this; - $this->instance->args = $this->getArguments(); - $this->instance->queue = $this->queue; + if (is_array($instance)) + { + $_realinstance =& $instance[0]; + } + else + { + $_realinstance =& $instance; + } + + $_realinstance->job = $this; + $_realinstance->args = $this->getArguments(); + $_realinstance->queue = $this->queue; return $this->instance; } @@ -188,18 +197,48 @@ public function getInstance() */ public function perform() { + + $method = 'perform'; + $beforePerformMethod = 'setUp'; + $tearDownMethod = 'tearDown'; $instance = $this->getInstance(); + if (is_array($instance)) + { + if (isset($instance[4])) + { + $tearDownMethod = $instance[4]; + } + if (isset($instance[3])) + { + $beforePerformMethod = $instance[3]; + } + if (isset($instance[2])) + { + $args = $instance[2]; + } + if (isset($instance[1])) + { + $method = $instance[1]; + } + $instance = $instance[0]; + } + try { Resque_Event::trigger('beforePerform', $this); - if(method_exists($instance, 'setUp')) { - $instance->setUp(); + if(method_exists($instance, $beforePerformMethod)) { + $instance->$beforePerformMethod(); } - - $instance->perform(); - - if(method_exists($instance, 'tearDown')) { - $instance->tearDown(); + if (isset($args)) + { + $instance->$method($args); + } + else + { + $instance->$method(); + } + if(method_exists($instance, $tearDownMethod)) { + $instance->$tearDownMethod(); } Resque_Event::trigger('afterPerform', $this); From 60f0b900b232f54b14b29bb1d78390976158ddba Mon Sep 17 00:00:00 2001 From: Marco Manieri Date: Wed, 29 Jul 2015 16:56:27 +0200 Subject: [PATCH 2/8] fix bug! --- lib/Resque/Job.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Resque/Job.php b/lib/Resque/Job.php index 0969258..38e817d 100755 --- a/lib/Resque/Job.php +++ b/lib/Resque/Job.php @@ -173,13 +173,13 @@ public function getInstance() $this->instance = new $this->payload['class'](); } - if (is_array($instance)) + if (is_array($this->instance)) { - $_realinstance =& $instance[0]; + $_realinstance =& $this->instance[0]; } else { - $_realinstance =& $instance; + $_realinstance =& $this->instance; } $_realinstance->job = $this; From f5641438e31e1200b97b29f0f576186b579aa552 Mon Sep 17 00:00:00 2001 From: Marco Manieri Date: Thu, 30 Jul 2015 17:20:51 +0200 Subject: [PATCH 3/8] $instance properties (job, ars,queue) must not be set on classes instantiated by the Resque_Job_Creator class (for CakePHP the args property equals the argv from the CLI that include as 0th element the script file name, this must be mocked inside the Resque_Job_Creator class) --- lib/Resque/Job.php | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/lib/Resque/Job.php b/lib/Resque/Job.php index 38e817d..f059acd 100755 --- a/lib/Resque/Job.php +++ b/lib/Resque/Job.php @@ -170,21 +170,15 @@ public function getInstance() 'Job class ' . $this->payload['class'] . ' does not contain a perform method.' ); } + $this->instance = new $this->payload['class'](); - } - if (is_array($this->instance)) - { - $_realinstance =& $this->instance[0]; - } - else - { - $_realinstance =& $this->instance; + $this->instance->job = $this; + $this->instance->args = $this->getArguments(); + $this->instance->queue = $this->queue; + } - $_realinstance->job = $this; - $_realinstance->args = $this->getArguments(); - $_realinstance->queue = $this->queue; return $this->instance; } @@ -229,6 +223,7 @@ public function perform() if(method_exists($instance, $beforePerformMethod)) { $instance->$beforePerformMethod(); } + if (isset($args)) { $instance->$method($args); From 95b4347a38e9c2dbc15fea67250b920618d9aca5 Mon Sep 17 00:00:00 2001 From: Marco Manieri Date: Fri, 31 Jul 2015 17:23:25 +0200 Subject: [PATCH 4/8] when class in instantiated not in CLI (i.e. invoking ::all from CakeResque::getWorkers()) STDOUT is not defined. --- lib/Resque/Worker.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/Resque/Worker.php b/lib/Resque/Worker.php index 0d0e4d3..9a7ef8a 100755 --- a/lib/Resque/Worker.php +++ b/lib/Resque/Worker.php @@ -49,7 +49,7 @@ class Resque_Worker const LOG_TYPE_CRITICAL = 500; const LOG_TYPE_ALERT = 550; - public $logOutput = STDOUT; + public $logOutput = null; /** * @var int Current log level of this worker. @@ -166,6 +166,11 @@ public function setId($workerId) */ public function __construct($queues) { + if (defined('STDOUT')) + { + $this->logOutput = STDOUT; + } + if (!is_array($queues)) { $queues = array($queues); } @@ -626,7 +631,9 @@ public function log($message, $code = self::LOG_TYPE_INFO) if (($this->logLevel === self::LOG_NORMAL || $this->logLevel === self::LOG_VERBOSE) && $code !== self::LOG_TYPE_DEBUG) { if ($this->logger === null) { - fwrite($this->logOutput, "[" . date('c') . "] " . $message . "\n"); + if (!is_null($this->logOutput)) { + fwrite($this->logOutput, "[" . date('c') . "] " . $message . "\n"); + } } else { switch ($code) { case self::LOG_TYPE_INFO: @@ -650,7 +657,9 @@ public function log($message, $code = self::LOG_TYPE_INFO) } else if ($code === self::LOG_TYPE_DEBUG && $this->logLevel === self::LOG_VERBOSE) { if ($this->logger === null) { - fwrite($this->logOutput, "[" . date('c') . "] " . $message . "\n"); + if (!is_null($this->logOutput)) { + fwrite($this->logOutput, "[" . date('c') . "] " . $message . "\n"); + } } else { $this->logger->addDebug($message, $extra); } From 47f0a7bb421f69af43003e16696c1a7cd869ea26 Mon Sep 17 00:00:00 2001 From: Marco Manieri Date: Wed, 5 Aug 2015 11:38:43 +0200 Subject: [PATCH 5/8] fixed workerPids() ps command --- lib/Resque/Worker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Resque/Worker.php b/lib/Resque/Worker.php index 9a7ef8a..ba07e45 100755 --- a/lib/Resque/Worker.php +++ b/lib/Resque/Worker.php @@ -514,7 +514,7 @@ public function pruneDeadWorkers() public function workerPids() { $pids = array(); - exec('ps -A -o pid,comm | grep [r]esque', $cmdOutput); + exec('ps -A -o pid,command | grep [r]esque', $cmdOutput); foreach ($cmdOutput as $line) { list($pids[]) = explode(' ', trim($line), 2); } From 0d22a3729c87168c85a8a01477fef03fde9326ea Mon Sep 17 00:00:00 2001 From: Marco Manieri Date: Wed, 5 Aug 2015 19:08:03 +0200 Subject: [PATCH 6/8] fix workerPids() to not include pid of workers parents --- lib/Resque/Worker.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/Resque/Worker.php b/lib/Resque/Worker.php index ba07e45..c5d2699 100755 --- a/lib/Resque/Worker.php +++ b/lib/Resque/Worker.php @@ -514,9 +514,13 @@ public function pruneDeadWorkers() public function workerPids() { $pids = array(); - exec('ps -A -o pid,command | grep [r]esque', $cmdOutput); + exec('ps -A -o pid,comm,command | grep [r]esque', $cmdOutput); foreach ($cmdOutput as $line) { - list($pids[]) = explode(' ', trim($line), 2); + $cols = explode(' ', trim($line), 3); + if (trim($cols[1])=='php') + { + $pids[] = trim($cols[0]); + } } return $pids; } From 0159d2b76451fba78619d092b35021f8775ed25a Mon Sep 17 00:00:00 2001 From: Marco Manieri Date: Thu, 6 Aug 2015 12:56:11 +0200 Subject: [PATCH 7/8] trigger an event after the job has been processed and redis has been updated --- lib/Resque/Worker.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Resque/Worker.php b/lib/Resque/Worker.php index c5d2699..1e9dbed 100755 --- a/lib/Resque/Worker.php +++ b/lib/Resque/Worker.php @@ -265,6 +265,7 @@ public function work($interval = 5) $this->child = null; $this->doneWorking(); + Resque_Event::trigger('afterdoneworking', $job); } $this->unregisterWorker(); From c6b288da9ed621e010890fa0a0ac1f78512fcc91 Mon Sep 17 00:00:00 2001 From: Marco Manieri Date: Thu, 6 Aug 2015 17:23:18 +0200 Subject: [PATCH 8/8] Resque_Event::trigger returns the number of "fired" callbacks that are then logged for debugging purpose --- lib/Resque/Event.php | 21 +++++++++++---------- lib/Resque/Worker.php | 4 +++- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/Resque/Event.php b/lib/Resque/Event.php index 20072ff..704a505 100644 --- a/lib/Resque/Event.php +++ b/lib/Resque/Event.php @@ -22,22 +22,23 @@ class Resque_Event */ public static function trigger($event, $data = null) { + $fired = 0; + if (!is_array($data)) { $data = array($data); } - - if (empty(self::$events[$event])) { - return true; - } - - foreach (self::$events[$event] as $callback) { - if (!is_callable($callback)) { - continue; + if (!empty(self::$events[$event])) { + foreach (self::$events[$event] as $callback) { + if (!is_callable($callback)) { + continue; + } + $fired++; + call_user_func_array($callback, $data); } - call_user_func_array($callback, $data); + } - return true; + return $fired; } /** diff --git a/lib/Resque/Worker.php b/lib/Resque/Worker.php index 1e9dbed..1b920c7 100755 --- a/lib/Resque/Worker.php +++ b/lib/Resque/Worker.php @@ -265,7 +265,9 @@ public function work($interval = 5) $this->child = null; $this->doneWorking(); - Resque_Event::trigger('afterdoneworking', $job); + + $fired = Resque_Event::trigger('afterdoneworking', $job); + $this->log(array('message' => "afterdoneworking triggered {$fired} callbacks", 'data' => compact('job')), self::LOG_TYPE_INFO); } $this->unregisterWorker();