From 855b0084c829345fbb1992ccb72abaf605f9183e Mon Sep 17 00:00:00 2001 From: Stefan Kleff Date: Sat, 1 Mar 2014 12:28:37 +0100 Subject: [PATCH 01/10] Added support for processed job status in event --- src/SlmQueue/Worker/AbstractWorker.php | 19 ++++++++++++++++++- src/SlmQueue/Worker/WorkerEvent.php | 23 +++++++++++++++++++++++ src/SlmQueue/Worker/WorkerInterface.php | 2 +- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/SlmQueue/Worker/AbstractWorker.php b/src/SlmQueue/Worker/AbstractWorker.php index 2c584b0..4ea550f 100644 --- a/src/SlmQueue/Worker/AbstractWorker.php +++ b/src/SlmQueue/Worker/AbstractWorker.php @@ -16,6 +16,21 @@ */ abstract class AbstractWorker implements WorkerInterface, EventManagerAwareInterface { + /** + * Status for successfully finished job + */ + const JOB_SUCCESSFUL = 1; + + /** + * Status for job that has failed and will not be processed again + */ + const JOB_FAILED = 2; + + /** + * Status for job that has failed but will be processed again + */ + const JOB_RESCHEDULED = 4; + /** * @var QueuePluginManager */ @@ -87,12 +102,14 @@ public function processQueue($queueName, array $options = array()) } $workerEvent->setJob($job); + $workerEvent->setStatus(null); $eventManager->trigger(WorkerEvent::EVENT_PROCESS_JOB_PRE, $workerEvent); - $this->processJob($job, $queue); + $result = $this->processJob($job, $queue); $count++; + $workerEvent->setResult($result); $eventManager->trigger(WorkerEvent::EVENT_PROCESS_JOB_POST, $workerEvent); // Check for internal stop condition diff --git a/src/SlmQueue/Worker/WorkerEvent.php b/src/SlmQueue/Worker/WorkerEvent.php index 5a165a6..3373a25 100644 --- a/src/SlmQueue/Worker/WorkerEvent.php +++ b/src/SlmQueue/Worker/WorkerEvent.php @@ -29,6 +29,12 @@ class WorkerEvent extends Event */ protected $job; + /** + * Result of the processed job. + * @var int + */ + protected $result; + /** * @param QueueInterface $queue */ @@ -61,4 +67,21 @@ public function getQueue() { return $this->queue; } + + /** + * @param int $result + */ + public function setResult($result) + { + $this->result = $result; + } + + /** + * @return int|null + */ + public function getResult() + { + return $this->result; + } + } diff --git a/src/SlmQueue/Worker/WorkerInterface.php b/src/SlmQueue/Worker/WorkerInterface.php index 0145584..015aa38 100644 --- a/src/SlmQueue/Worker/WorkerInterface.php +++ b/src/SlmQueue/Worker/WorkerInterface.php @@ -26,7 +26,7 @@ public function processQueue($queueName, array $options = array()); * * @param JobInterface $job * @param QueueInterface $queue - * @return void + * @return int Status of the job */ public function processJob(JobInterface $job, QueueInterface $queue); } From a2e5bf3791330af505de58109cca859abe6c1c1f Mon Sep 17 00:00:00 2001 From: Stefan Kleff Date: Sat, 1 Mar 2014 12:48:22 +0100 Subject: [PATCH 02/10] Updated according to comments --- src/SlmQueue/Worker/AbstractWorker.php | 17 +---------------- src/SlmQueue/Worker/WorkerEvent.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/SlmQueue/Worker/AbstractWorker.php b/src/SlmQueue/Worker/AbstractWorker.php index 4ea550f..32e553b 100644 --- a/src/SlmQueue/Worker/AbstractWorker.php +++ b/src/SlmQueue/Worker/AbstractWorker.php @@ -16,21 +16,6 @@ */ abstract class AbstractWorker implements WorkerInterface, EventManagerAwareInterface { - /** - * Status for successfully finished job - */ - const JOB_SUCCESSFUL = 1; - - /** - * Status for job that has failed and will not be processed again - */ - const JOB_FAILED = 2; - - /** - * Status for job that has failed but will be processed again - */ - const JOB_RESCHEDULED = 4; - /** * @var QueuePluginManager */ @@ -102,7 +87,7 @@ public function processQueue($queueName, array $options = array()) } $workerEvent->setJob($job); - $workerEvent->setStatus(null); + $workerEvent->setResult(null); $eventManager->trigger(WorkerEvent::EVENT_PROCESS_JOB_PRE, $workerEvent); diff --git a/src/SlmQueue/Worker/WorkerEvent.php b/src/SlmQueue/Worker/WorkerEvent.php index 3373a25..998eac8 100644 --- a/src/SlmQueue/Worker/WorkerEvent.php +++ b/src/SlmQueue/Worker/WorkerEvent.php @@ -19,6 +19,21 @@ class WorkerEvent extends Event const EVENT_PROCESS_JOB_PRE = 'processJob.pre'; const EVENT_PROCESS_JOB_POST = 'processJob.post'; + /** + * Status for successfully finished job + */ + const JOB_SUCCESSFUL = 1; + + /** + * Status for job that has failed and will not be processed again + */ + const JOB_FAILED = 2; + + /** + * Status for job that has failed but will be processed again + */ + const JOB_RESCHEDULED = 4; + /** * @var QueueInterface */ From a5715c829119f43b1072af95ad9c54c0eb4dfbfe Mon Sep 17 00:00:00 2001 From: Stefan Kleff Date: Sat, 1 Mar 2014 12:48:55 +0100 Subject: [PATCH 03/10] removed intent --- src/SlmQueue/Worker/WorkerEvent.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SlmQueue/Worker/WorkerEvent.php b/src/SlmQueue/Worker/WorkerEvent.php index 998eac8..52240bb 100644 --- a/src/SlmQueue/Worker/WorkerEvent.php +++ b/src/SlmQueue/Worker/WorkerEvent.php @@ -22,17 +22,17 @@ class WorkerEvent extends Event /** * Status for successfully finished job */ - const JOB_SUCCESSFUL = 1; + const JOB_SUCCESSFUL = 1; /** * Status for job that has failed and will not be processed again */ - const JOB_FAILED = 2; + const JOB_FAILED = 2; /** * Status for job that has failed but will be processed again */ - const JOB_RESCHEDULED = 4; + const JOB_RESCHEDULED = 4; /** * @var QueueInterface From 8affc2a8c9d505ecb7b3c920d169889dc1c97ac6 Mon Sep 17 00:00:00 2001 From: Stefan Kleff Date: Sat, 1 Mar 2014 12:52:52 +0100 Subject: [PATCH 04/10] Moved the constants back to worker --- src/SlmQueue/Worker/AbstractWorker.php | 15 +++++++++++++++ src/SlmQueue/Worker/WorkerEvent.php | 15 --------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/SlmQueue/Worker/AbstractWorker.php b/src/SlmQueue/Worker/AbstractWorker.php index 32e553b..8622ec9 100644 --- a/src/SlmQueue/Worker/AbstractWorker.php +++ b/src/SlmQueue/Worker/AbstractWorker.php @@ -16,6 +16,21 @@ */ abstract class AbstractWorker implements WorkerInterface, EventManagerAwareInterface { + /** + * Status for successfully finished job + */ + const JOB_SUCCESSFUL = 1; + + /** + * Status for job that has failed and will not be processed again + */ + const JOB_FAILED = 2; + + /** + * Status for job that has failed but will be processed again + */ + const JOB_RESCHEDULED = 4; + /** * @var QueuePluginManager */ diff --git a/src/SlmQueue/Worker/WorkerEvent.php b/src/SlmQueue/Worker/WorkerEvent.php index 52240bb..3373a25 100644 --- a/src/SlmQueue/Worker/WorkerEvent.php +++ b/src/SlmQueue/Worker/WorkerEvent.php @@ -19,21 +19,6 @@ class WorkerEvent extends Event const EVENT_PROCESS_JOB_PRE = 'processJob.pre'; const EVENT_PROCESS_JOB_POST = 'processJob.post'; - /** - * Status for successfully finished job - */ - const JOB_SUCCESSFUL = 1; - - /** - * Status for job that has failed and will not be processed again - */ - const JOB_FAILED = 2; - - /** - * Status for job that has failed but will be processed again - */ - const JOB_RESCHEDULED = 4; - /** * @var QueueInterface */ From 82d79548948477a0c798d198b66f14ddeada1f0b Mon Sep 17 00:00:00 2001 From: Jurian Sluiman Date: Thu, 24 Jul 2014 09:12:06 +0200 Subject: [PATCH 05/10] Move job status codes to worker event --- src/SlmQueue/Worker/AbstractWorker.php | 15 --------------- src/SlmQueue/Worker/WorkerEvent.php | 16 +++++++++++++++- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/SlmQueue/Worker/AbstractWorker.php b/src/SlmQueue/Worker/AbstractWorker.php index 8622ec9..32e553b 100644 --- a/src/SlmQueue/Worker/AbstractWorker.php +++ b/src/SlmQueue/Worker/AbstractWorker.php @@ -16,21 +16,6 @@ */ abstract class AbstractWorker implements WorkerInterface, EventManagerAwareInterface { - /** - * Status for successfully finished job - */ - const JOB_SUCCESSFUL = 1; - - /** - * Status for job that has failed and will not be processed again - */ - const JOB_FAILED = 2; - - /** - * Status for job that has failed but will be processed again - */ - const JOB_RESCHEDULED = 4; - /** * @var QueuePluginManager */ diff --git a/src/SlmQueue/Worker/WorkerEvent.php b/src/SlmQueue/Worker/WorkerEvent.php index 3373a25..4b729ae 100644 --- a/src/SlmQueue/Worker/WorkerEvent.php +++ b/src/SlmQueue/Worker/WorkerEvent.php @@ -19,6 +19,21 @@ class WorkerEvent extends Event const EVENT_PROCESS_JOB_PRE = 'processJob.pre'; const EVENT_PROCESS_JOB_POST = 'processJob.post'; + /** + * Status for successfully finished job + */ + const JOB_SUCCESS = 1; + + /** + * Status for job that has failed and cannot be processed again + */ + const JOB_FAILURE = 2; + + /** + * Status for job that has failed but can be processed again + */ + const JOB_FAILURE_RECOVERABLE = 4; + /** * @var QueueInterface */ @@ -83,5 +98,4 @@ public function getResult() { return $this->result; } - } From 57cb92769d54f56ad9c984412d65f8c7f7c2112a Mon Sep 17 00:00:00 2001 From: Jurian Sluiman Date: Thu, 24 Jul 2014 09:24:18 +0200 Subject: [PATCH 06/10] Add "unknown" status and use for unitialized jobs Add a 0 status for jobs which have an unknown status and use this status instead of a NULL value. --- src/SlmQueue/Worker/AbstractWorker.php | 2 +- src/SlmQueue/Worker/WorkerEvent.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/SlmQueue/Worker/AbstractWorker.php b/src/SlmQueue/Worker/AbstractWorker.php index 32e553b..202cb28 100644 --- a/src/SlmQueue/Worker/AbstractWorker.php +++ b/src/SlmQueue/Worker/AbstractWorker.php @@ -87,7 +87,7 @@ public function processQueue($queueName, array $options = array()) } $workerEvent->setJob($job); - $workerEvent->setResult(null); + $workerEvent->setResult(WorkerEvent::JOB_UNKNOWN); $eventManager->trigger(WorkerEvent::EVENT_PROCESS_JOB_PRE, $workerEvent); diff --git a/src/SlmQueue/Worker/WorkerEvent.php b/src/SlmQueue/Worker/WorkerEvent.php index 4b729ae..e775b83 100644 --- a/src/SlmQueue/Worker/WorkerEvent.php +++ b/src/SlmQueue/Worker/WorkerEvent.php @@ -19,6 +19,11 @@ class WorkerEvent extends Event const EVENT_PROCESS_JOB_PRE = 'processJob.pre'; const EVENT_PROCESS_JOB_POST = 'processJob.post'; + /** + * Status for unstarted jobs + */ + const JOB_UNKNOWN = 0; + /** * Status for successfully finished job */ From c4513515e0eaac549af92d6f3d71b0f6e5c81ba5 Mon Sep 17 00:00:00 2001 From: Jurian Sluiman Date: Thu, 24 Jul 2014 09:34:01 +0200 Subject: [PATCH 07/10] s/JOB/JOB_STATUS/g --- src/SlmQueue/Worker/AbstractWorker.php | 2 +- src/SlmQueue/Worker/WorkerEvent.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/SlmQueue/Worker/AbstractWorker.php b/src/SlmQueue/Worker/AbstractWorker.php index 202cb28..075e7f8 100644 --- a/src/SlmQueue/Worker/AbstractWorker.php +++ b/src/SlmQueue/Worker/AbstractWorker.php @@ -87,7 +87,7 @@ public function processQueue($queueName, array $options = array()) } $workerEvent->setJob($job); - $workerEvent->setResult(WorkerEvent::JOB_UNKNOWN); + $workerEvent->setResult(WorkerEvent::JOB_STATUS_UNKNOWN); $eventManager->trigger(WorkerEvent::EVENT_PROCESS_JOB_PRE, $workerEvent); diff --git a/src/SlmQueue/Worker/WorkerEvent.php b/src/SlmQueue/Worker/WorkerEvent.php index e775b83..70a1198 100644 --- a/src/SlmQueue/Worker/WorkerEvent.php +++ b/src/SlmQueue/Worker/WorkerEvent.php @@ -22,22 +22,22 @@ class WorkerEvent extends Event /** * Status for unstarted jobs */ - const JOB_UNKNOWN = 0; + const JOB_STATUS_UNKNOWN = 0; /** * Status for successfully finished job */ - const JOB_SUCCESS = 1; + const JOB_STATUS_SUCCESS = 1; /** * Status for job that has failed and cannot be processed again */ - const JOB_FAILURE = 2; + const JOB_STATUS_FAILURE = 2; /** * Status for job that has failed but can be processed again */ - const JOB_FAILURE_RECOVERABLE = 4; + const JOB_STATUS_FAILURE_RECOVERABLE = 4; /** * @var QueueInterface From 7e71fa3f7b112a378099d2db7c4eb6422f7c9a0e Mon Sep 17 00:00:00 2001 From: Jurian Sluiman Date: Thu, 24 Jul 2014 09:56:11 +0200 Subject: [PATCH 08/10] Add test to assert return value from job --- tests/SlmQueueTest/Asset/SimpleWorker.php | 2 +- .../Worker/AbstractWorkerTest.php | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/SlmQueueTest/Asset/SimpleWorker.php b/tests/SlmQueueTest/Asset/SimpleWorker.php index fc7a90f..e6a1828 100644 --- a/tests/SlmQueueTest/Asset/SimpleWorker.php +++ b/tests/SlmQueueTest/Asset/SimpleWorker.php @@ -10,6 +10,6 @@ class SimpleWorker extends AbstractWorker { public function processJob(JobInterface $job, QueueInterface $queue) { - $job->execute(); + return $job->execute(); } } diff --git a/tests/SlmQueueTest/Worker/AbstractWorkerTest.php b/tests/SlmQueueTest/Worker/AbstractWorkerTest.php index e4a2a69..bec8ccf 100644 --- a/tests/SlmQueueTest/Worker/AbstractWorkerTest.php +++ b/tests/SlmQueueTest/Worker/AbstractWorkerTest.php @@ -6,6 +6,7 @@ use SlmQueue\Options\WorkerOptions; use SlmQueue\Worker\WorkerEvent; use SlmQueueTest\Asset\SimpleWorker; +use Zend\EventManager\EventManager; class AbstractWorkerTest extends TestCase { @@ -118,6 +119,27 @@ public function testEventManagerTriggersEvents() $this->worker->processQueue('foo'); } + public function testWorkerSetsJobStatusInEventClass() + { + $eventManager = new EventManager; + $this->worker->setEventManager($eventManager); + + $this->job->expects($this->once()) + ->method('execute') + ->will($this->returnValue(WorkerEvent::JOB_STATUS_SUCCESS)); + + $this->queue->expects($this->once()) + ->method('pop') + ->will($this->returnValue($this->job)); + + $self = $this; + $eventManager->attach(WorkerEvent::EVENT_PROCESS_JOB_POST, function($e) use ($self) { + $self->assertEquals(WorkerEvent::JOB_STATUS_SUCCESS, $e->getResult()); + }); + + $this->worker->processQueue('foo'); + } + public function testMethod_hasMemoryExceeded() { $this->options->setMaxMemory(10000000000); $this->assertFalse($this->worker->isMaxMemoryExceeded()); From 1f5d83396434cc1976a9f156470bf83d2420bbc2 Mon Sep 17 00:00:00 2001 From: Jurian Sluiman Date: Tue, 29 Jul 2014 09:42:58 +0200 Subject: [PATCH 09/10] Add documentation about job status codes --- docs/3.Jobs.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ docs/6.Events.md | 19 ++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/docs/3.Jobs.md b/docs/3.Jobs.md index 1d2c56c..c078ce4 100644 --- a/docs/3.Jobs.md +++ b/docs/3.Jobs.md @@ -211,6 +211,65 @@ class MyController extends AbstractActionController } ``` +Job status codes +---------------- + +When using [events](6.Events.md) you might want to hook in the status process of a job. Has +a job successfully been executed or were there errors? The result of a job is expressed in +its status code. SlmQueue defines the following default status codes: + +0. `JOB_STATUS_UNKNOWN` +1. `JOB_STATUS_SUCCESS` +2. `JOB_STATUS_FAILURE` +3. `JOB_STATUS_FAILURE_RECOVERABLE` + +The status codes are stored in the WorkerEvent object (more on that at the +[event section](6.Events.md)). Normally when jobs are completely executed, the status is +success. If any exception is thrown, the status is set to failure. + +```php +use SlmQueue\Job\AbstractJob; + +class SuccessfulJob extends AbstractJob +{ + public function execute() + { + // all is OK + } +} +``` + +```php +use RuntimeException +use SlmQueue\Job\AbstractJob; + +class FailingJob extends AbstractJob +{ + public function execute() + { + throw new RuntimeException('Not going well'); + } +} +``` + +However, if you want to indicate `JOB_STATUS_FAILURE_RECOVERABLE` or you need to introduce +some custom job status codes, you can return a non-NULL value from the Job's `execute()` +method: + +```php +use SlmQueue\Job\AbstractJob; +use SlmQueue\Worker\WorkerEvent; + +class RecoverableJob extends AbstractJob +{ + public function execute() + { + // Ooops, something went wrong? + return WorkerEvent::JOB_STATUS_FAILURE_RECOVERABLE; + } +} +``` + Navigation ---------- diff --git a/docs/6.Events.md b/docs/6.Events.md index f24189b..170e5df 100644 --- a/docs/6.Events.md +++ b/docs/6.Events.md @@ -21,6 +21,25 @@ $em->attach(WorkerEvent::EVENT_PROCESS_JOB_PRE, function(WorkerEvent $e) { In above example, `$em` refers to the event manager inside the worker object: `$em = $worker->getEventManager();`. +Job status codes +---------------- + +When a job is processed, the [job or worker returns a status code](3.Jobs.md#job-status-codes). You +can use a listener to act upon this status, for example to log any failed jobs: + +```php +$logger = $sm->get('logger'); +$em->attach(WorkerEvent::EVENT_PROCESS_JOB_POST, function(WorkerEvent $e) use ($logger) { + $result = $e->getResult(); + if ($result & WorkerEvent::JOB_STATUS_FAILURE) { + $job = $e->getJob(); + $logger->warn(sprintf( + 'Job #%s (%s) failed executing', $job->getId, get_class($job) + )); + } +}); +``` + Using the shared event manager ------------------------------ From abece1280dd74fce05beac5c768af13fa3add676 Mon Sep 17 00:00:00 2001 From: Jurian Sluiman Date: Tue, 29 Jul 2014 14:02:55 +0200 Subject: [PATCH 10/10] Update CHANGELOG with job status codes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25e4b81..4deb5aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # 0.4.0 +- Add job status codes so listeners can act on the result of a job's outcome - Add controller plugin to ease push of jobs into queues - BC: job's jsonSerialize() removed in favour of the queue's serializeJob() method - BC: job's metadata field "name" is now reserved for SlmQueue and should not be used by end users