Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Create event to allow job instance creation to be delegated outside Resque #51

Closed
wants to merge 3 commits into from

3 participants

@ebernhardson

The addition of a createInstance event allows the code using Resque to implement its own instantation methods. My use case was to extract jobs pre-configured with their object dependencies from a DIC.

This event can also handle instances of providing a backward compatible instantiation method if the current instantiation method changes .

@ShonM ShonM referenced this pull request in ShonM/php-resque
Closed

Look into job instantiation deferral #3

@danhunsaker

I'd be more inclined to have my job classes handle that kind of operation, personally. Jobs should be composed of classes designed for that express purpose - being used as a Resque job. The job class can then extract and instantiate/initialize whatever other objects you've stored as the actual work, and can make appropriate calls to ensure that work gets done. This is a far cleaner approach than trying to shoehorn existing classes/objects into the role of a Resque job.

@chrisboulton

Thanks for chiming in Dan - I definitely agree with your thoughts on this one. Am going to close for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
4 lib/Resque/Event.php
@@ -73,7 +73,7 @@ public static function stopListening($event, $callback)
$key = array_search($callback, self::$events[$event]);
if ($key !== false) {
- unset(self::$events[$key]);
+ unset(self::$events[$event][$key]);
}
return true;
@@ -86,4 +86,4 @@ public static function clearListeners()
{
self::$events = array();
}
-}
+}
View
60 lib/Resque/Event/CreateInstance.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Resque job instance creation event
+ *
+ * @package Resque/Event
+ * @author Chris Boulton <chris.boulton@interspire.com>
+ * @copyright (c) 2010 Chris Boulton
+ * @license http://www.opensource.org/licenses/mit-license.php
+ */
+class Resque_Event_CreateInstance
+{
+ /**
+ * @var Resque_Job The job that triggered the event
+ */
+ protected $job;
+
+ /**
+ * @var object Instance of the object that $this->job belongs to
+ */
+ protected $instance;
+
+ /**
+ * Instantiate a new instance of the event
+ *
+ * @param Resque_Job $job The job that triggered the event
+ */
+ public function __construct($job)
+ {
+ $this->job = $job;
+ }
+
+ /**
+ * Get the Resque_Job instance that triggered the event.
+ *
+ * @return Resque_Job Instance of the job that triggered the event.
+ */
+ public function getJob()
+ {
+ return $this->job;
+ }
+
+ /**
+ * Set the instantiated object for $this->job that will be performing work.
+ */
+ public function setInstance($instance)
+ {
+ $this->instance = $instance;
+ }
+
+ /**
+ * Get the instantiated object for $this->job that will be performing work, or null
+ *
+ * @return object Instance of the object that $this->job belongs to
+ */
+ public function getInstance()
+ {
+ return $this->instance ?: null;
+ }
+}
+?>
View
26 lib/Resque/Job.php
@@ -1,5 +1,6 @@
<?php
require_once dirname(__FILE__) . '/Event.php';
+require_once dirname(__FILE__) . '/Event/CreateInstance.php';
require_once dirname(__FILE__) . '/Job/Status.php';
require_once dirname(__FILE__) . '/Job/DontPerform.php';
@@ -144,22 +145,27 @@ public function getInstance()
return $this->instance;
}
- if(!class_exists($this->payload['class'])) {
- throw new Resque_Exception(
- 'Could not find job class ' . $this->payload['class'] . '.'
- );
+ $event = new Resque_Event_CreateInstance($this);
+ Resque_Event::trigger('createInstance', $event);
+ if (null === ($this->instance = $event->getInstance())) {
+ if(!class_exists($this->payload['class'])) {
+ throw new Resque_Exception(
+ 'Could not find job class ' . $this->payload['class'] . '.'
+ );
+ }
+
+ $this->instance = new $this->payload['class']();
+ $this->instance->job = $this;
+ $this->instance->args = $this->getArguments();
+ $this->instance->queue = $this->queue;
}
- if(!method_exists($this->payload['class'], 'perform')) {
+ if(!method_exists($this->instance, 'perform')) {
+ $this->instance = null;
throw new Resque_Exception(
'Job class ' . $this->payload['class'] . ' does not contain a perform method.'
);
}
-
- $this->instance = new $this->payload['class']();
- $this->instance->job = $this;
- $this->instance->args = $this->getArguments();
- $this->instance->queue = $this->queue;
return $this->instance;
}
View
22 test/Resque/Tests/JobTest.php
@@ -181,4 +181,24 @@ public function testJobWithNamespace()
Resque_Redis::prefix('resque');
$this->assertEquals(Resque::size($queue), 0);
}
-}
+
+ public function testCreateInstanceEventOverridesDefault()
+ {
+ $callback = array($this, 'createInstanceCallback');
+ Resque_Event::listen('createInstance', $callback);
+ $payload = array(
+ 'class' => 'Test_Job_With_SetUp',
+ 'args' => '',
+ );
+ $job = new Resque_Job('jobs', $payload);
+ $instance = $job->getInstance();
+ Resque_Event::stopListening('createInstance', $callback);
+
+ $this->assertInstanceOf('Test_Job_With_TearDown', $instance);
+ }
+
+ public function createInstanceCallback($event)
+ {
+ $event->setInstance(new Test_Job_With_TearDown());
+ }
+}
Something went wrong with that request. Please try again.