From 6e6d7ad85938fe0001de3621b19731439dd07664 Mon Sep 17 00:00:00 2001 From: Chris Boulton Date: Tue, 20 Apr 2010 10:02:34 +1000 Subject: [PATCH] Add setUp and tearDown callbacks for jobs --- CHANGELOG.markdown | 4 +++- README.markdown | 32 ++++++++++++++++++++++++++++++ TODO.markdown | 6 ++++-- lib/Resque/Job.php | 8 ++++++++ test/Resque/Tests/JobTest.php | 32 ++++++++++++++++++++++++++++++ test/Resque/Tests/bootstrap.php | 35 +++++++++++++++++++++++++++++++++ 6 files changed, 114 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 59b9d10..8c77002 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -1,6 +1,8 @@ ## 1.1 (????-??-??) ## * Change arguments for jobs to be an array as they're easier to work with in -PHP +PHP. +* Implement ability to have setUp and tearDown methods for jobs, called before +and after every single run. ## 1.0 (2010-04-18) ## diff --git a/README.markdown b/README.markdown index b8aa207..1daf4a2 100644 --- a/README.markdown +++ b/README.markdown @@ -33,6 +33,8 @@ In addition, it also: * Has the ability to track the status of jobs * Will mark a job as failed, if a forked child running a job does not exit with a status code as 0 +* Has built in support for `setUp` and `tearDown` methods, called +pre and post jobs ## Jobs ## @@ -68,6 +70,36 @@ Any exception thrown by a job will result in the job failing - be careful here and make sure you handle the exceptions that shouldn't result in a job failing. +Jobs can also have `setUp` and `tearDown` methods. If a `setUp` method +is defined, it will be called along with `$args` before the `perform` +method is run. The `tearDown` method if defined, will be called with +`$args` also, after the job finishes. + + class My_Job + { + public static function setUp($args) + { + // ... Set up environment for this job + } + + public static function perform($args) + { + // .. Run job + } + + public static function tearDown($args) + { + // ... Remove environment for this job + } + } + +It is **IMPORTANT** to note, that on operating systems where Resque +cannot fork to run a job (Mac OS X, or other platforms where the PHP +process control functions are unavailable), that because job classes +are static, their state will be retained between job calls. **ALWAYS** +reset the environment back to how you got it if you're using a `setUp` +method, by resetting changes in a `tearDown` method. + ### Tracking Job Statuses ### php-resque has the ability to perform basic status tracking of a queued diff --git a/TODO.markdown b/TODO.markdown index 2aaca82..d8ee07a 100644 --- a/TODO.markdown +++ b/TODO.markdown @@ -1,8 +1,10 @@ * Write tests for: * `Resque_Failure` * `Resque_Failure_Redis` -* Plugin/hook type system similar to Ruby version +* Plugin/hook type system similar to Ruby version (when done, implement the +setUp and tearDown methods as a plugin) * Change to preforking worker model * Clean up /bin and /demo * Add a way to store arbitrary text in job statuses (for things like progress -indicators) \ No newline at end of file +indicators) +* Write plugin for Ruby resque that calls setUp and tearDown methods \ No newline at end of file diff --git a/lib/Resque/Job.php b/lib/Resque/Job.php index f165f2f..375240a 100644 --- a/lib/Resque/Job.php +++ b/lib/Resque/Job.php @@ -129,8 +129,16 @@ class Resque_Job 'Job class ' . $this->payload['class'] . ' does not contain a perform method.' ); } + + if(method_exists($this->payload['class'], 'setUp')) { + call_user_func(array($this->payload['class'], 'setUp'), $this->payload['args']); + } call_user_func(array($this->payload['class'], 'perform'), $this->payload['args']); + + if(method_exists($this->payload['class'], 'tearDown')) { + call_user_func(array($this->payload['class'], 'tearDown'), $this->payload['args']); + } } /** diff --git a/test/Resque/Tests/JobTest.php b/test/Resque/Tests/JobTest.php index 46311e5..9e3b461 100644 --- a/test/Resque/Tests/JobTest.php +++ b/test/Resque/Tests/JobTest.php @@ -136,4 +136,36 @@ class Resque_Tests_JobTest extends Resque_Tests_TestCase $job->worker = $this->worker; $job->perform(); } + + public function testJobWithSetUpCallbackFiresSetUp() + { + $payload = array( + 'class' => 'Test_Job_With_SetUp', + 'args' => array( + 'somevar', + 'somevar2', + ), + ); + $job = new Resque_Job('jobs', $payload); + $job->perform(); + + $this->assertTrue(Test_Job_With_SetUp::$called); + $this->assertEquals($payload['args'], Test_Job_With_SetUp::$data); + } + + public function testJobWithTearDownCallbackFiresSetUp() + { + $payload = array( + 'class' => 'Test_Job_With_TearDown', + 'args' => array( + 'somevar', + 'somevar2', + ), + ); + $job = new Resque_Job('jobs', $payload); + $job->perform(); + + $this->assertTrue(Test_Job_With_TearDown::$called); + $this->assertEquals($payload['args'], Test_Job_With_TearDown::$data); + } } \ No newline at end of file diff --git a/test/Resque/Tests/bootstrap.php b/test/Resque/Tests/bootstrap.php index 502ade6..d2efc27 100644 --- a/test/Resque/Tests/bootstrap.php +++ b/test/Resque/Tests/bootstrap.php @@ -113,4 +113,39 @@ class Failing_Job class Test_Job_Without_Perform_Method { +} + +class Test_Job_With_SetUp +{ + public static $called = false; + public static $data = false; + + public function setUp($data) + { + self::$called = true; + self::$data = $data; + } + + public function perform($data) + { + + } +} + + +class Test_Job_With_TearDown +{ + public static $called = false; + public static $data = false; + + public function perform($data) + { + + } + + public function tearDown($data) + { + self::$called = true; + self::$data = $data; + } } \ No newline at end of file