2.0.0 Add namespacing + PHP8.0 support (#1)

2.0.0 (2021-02-19)

Moved to PSR-4
Namespaced codebase
Added more comments throughout
Co-Authored-By: idanoo <daniel@m2.nz>
Co-Committed-By: idanoo <daniel@m2.nz>
This commit is contained in:
idanoo 2021-02-19 12:23:32 +13:00
parent ebec2f7bf7
commit 80d64e79ff
56 changed files with 2215 additions and 1423 deletions

3
.gitignore vendored
View File

@ -1,3 +1,2 @@
vendor/ vendor/
phpunit.xml .phpunit.result.cache
*.swp

View File

@ -12,9 +12,6 @@
&& docker-php-ext-enable redis && docker-php-ext-enable redis
docker-php-ext-install pcntl docker-php-ext-install pcntl
# Hack to fix mismatched php versions
rm composer.lock
# Install Composer # Install Composer
wget https://getcomposer.org/composer.phar wget https://getcomposer.org/composer.phar
php composer.phar install --dev php composer.phar install --dev
@ -28,6 +25,26 @@ test:7.4:
before_script: before_script:
- *docker_boostrap - *docker_boostrap
script: script:
- php vendor/bin/phpunit --verbose --configuration phpunit.xml.dist - php vendor/bin/phpunit --verbose --configuration phpunit.xml
tags: tags:
- docker - docker
# Test PHP 8.0
test:8.0:
image: php:8.0
before_script:
- *docker_boostrap
script:
- php vendor/bin/phpunit --verbose --configuration phpunit.xml
tags:
- docker
# Codestandards
lint:
image: php:8.0
allow_failure: true
script:
- apt update && apt install -y wget unzip git
- wget https://getcomposer.org/composer.phar
- php composer.phar install --dev
- php -d memory_limit=256M vendor/bin/phpcs -s --standard=ruleset.xml

View File

@ -1,13 +0,0 @@
language: php
php:
- 7.0
- 7.1
- 7.2
services:
- redis-server
before_script:
- echo "extension = redis.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- composer install

View File

@ -1,3 +1,8 @@
## 2.0.0 (2021-02-19)
- Moved to PSR-4
- Namespaced codebase
- Added more comments throughout
## 1.4.7 (2020-04-11) ## 1.4.7 (2020-04-11)
- Update PHPUnit to 9 - Update PHPUnit to 9
- Start adding return types - Start adding return types
@ -93,7 +98,7 @@ Changes by iskandar introduce improved support for using DSNs to connect to Redi
* Pass queue name to afterEvent callback * Pass queue name to afterEvent callback
* Only declare RedisException if it doesn't already exist (Matt Heath) * Only declare RedisException if it doesn't already exist (Matt Heath)
* Add support for Composer * Add support for Composer
* Fix missing and incorrect paths for Resque and Resque_Job_Status classes in demo (jjfrey) * Fix missing and incorrect paths for Resque and \Resque\Job\Status classes in demo (jjfrey)
* Disable autoload for the RedisException class_exists call (scragg0x) * Disable autoload for the RedisException class_exists call (scragg0x)
* General tidy up of comments and files/folders * General tidy up of comments and files/folders

View File

@ -14,9 +14,9 @@ What happens when you call `Resque::enqueue()`?
4. `Resque_Job::create()` pushes the job to the requested queue (first 4. `Resque_Job::create()` pushes the job to the requested queue (first
argument) argument)
5. `Resque_Job::create()`, if status monitoring is enabled for the job (fourth 5. `Resque_Job::create()`, if status monitoring is enabled for the job (fourth
argument), calls `Resque_Job_Status::create()` with the job ID as its only argument), calls `\Resque\Job\Status::create()` with the job ID as its only
argument argument
6. `Resque_Job_Status::create()` creates a key in Redis with the job ID in its 6. `\Resque\Job\Status::create()` creates a key in Redis with the job ID in its
name, and the current status (as well as a couple of timestamps) as its name, and the current status (as well as a couple of timestamps) as its
value, then returns control to `Resque_Job::create()` value, then returns control to `Resque_Job::create()`
7. `Resque_Job::create()` returns control to `Resque::enqueue()`, with the job 7. `Resque_Job::create()` returns control to `Resque::enqueue()`, with the job
@ -85,15 +85,15 @@ How do the workers process the queues?
* Worker * Worker
1. The worker waits for the job process to complete 1. The worker waits for the job process to complete
2. If the exit status is not 0, the worker calls `Resque_Job->fail()` with 2. If the exit status is not 0, the worker calls `Resque_Job->fail()` with
a `Resque_Job_DirtyExitException` as its only argument. a `Resque\Job\DirtyExitException` as its only argument.
3. `Resque_Job->fail()` triggers an `onFailure` event 3. `Resque_Job->fail()` triggers an `onFailure` event
4. `Resque_Job->fail()` updates the job status from `RUNNING` to `FAILED` 4. `Resque_Job->fail()` updates the job status from `RUNNING` to `FAILED`
5. `Resque_Job->fail()` calls `Resque_Failure::create()` with the job 5. `Resque_Job->fail()` calls `Resque_Failure::create()` with the job
payload, the `Resque_Job_DirtyExitException`, the internal ID of the payload, the `Resque\Job\DirtyExitException`, the internal ID of the
worker, and the queue name as arguments worker, and the queue name as arguments
6. `Resque_Failure::create()` creates a new object of whatever type has 6. `Resque_Failure::create()` creates a new object of whatever type has
been set as the `Resque_Failure` "backend" handler; by default, this is been set as the `Resque_Failure` "backend" handler; by default, this is
a `Resque_Failure_Redis` object, whose constructor simply collects the a `ResqueFailureRedis` object, whose constructor simply collects the
data passed into `Resque_Failure::create()` and pushes it into Redis data passed into `Resque_Failure::create()` and pushes it into Redis
in the `failed` queue in the `failed` queue
7. `Resque_Job->fail()` increments two failure counters in Redis: one for 7. `Resque_Job->fail()` increments two failure counters in Redis: one for

View File

@ -1,6 +1,8 @@
php-resque: PHP Resque Worker (and Enqueue) php-resque: PHP Resque Worker (and Enqueue)
=========================================== ===========================================
[![pipeline status](https://gitlab.com/idanoo/php-resque/badges/master/pipeline.svg)](https://gitlab.com/idanoo/php-resque/-/commits/master)
Resque is a Redis-backed library for creating background jobs, placing Resque is a Redis-backed library for creating background jobs, placing
those jobs on one or more queues, and processing them later. those jobs on one or more queues, and processing them later.
@ -367,8 +369,6 @@ your `APP_INCLUDE` script should initialize and register any listeners required
for operation. If you have rolled your own worker manager, then it is again your for operation. If you have rolled your own worker manager, then it is again your
responsibility to register listeners. responsibility to register listeners.
A sample plugin is included in the `extras` directory.
### Events ### ### Events ###
#### beforeFirstFork #### #### beforeFirstFork ####

View File

@ -9,7 +9,6 @@ $files = [
__DIR__ . '/../vendor/autoload.php', __DIR__ . '/../vendor/autoload.php',
]; ];
$found = false;
foreach ($files as $file) { foreach ($files as $file) {
if (file_exists($file)) { if (file_exists($file)) {
require_once $file; require_once $file;
@ -25,6 +24,7 @@ if (!class_exists('Composer\Autoload\ClassLoader', false)) {
); );
} }
// Set which queues to monitor '*'
$QUEUE = getenv('QUEUE'); $QUEUE = getenv('QUEUE');
if (empty($QUEUE)) { if (empty($QUEUE)) {
die("Set QUEUE env var containing the list of queues to work.\n"); die("Set QUEUE env var containing the list of queues to work.\n");
@ -38,22 +38,24 @@ if (empty($QUEUE)) {
*/ */
$REDIS_BACKEND = getenv('REDIS_BACKEND'); $REDIS_BACKEND = getenv('REDIS_BACKEND');
// A redis database number // Override redis DB numbers
$REDIS_BACKEND_DB = getenv('REDIS_BACKEND_DB'); $REDIS_BACKEND_DB = getenv('REDIS_BACKEND_DB');
if (!empty($REDIS_BACKEND)) { if (!empty($REDIS_BACKEND)) {
if (empty($REDIS_BACKEND_DB)) { if (empty($REDIS_BACKEND_DB)) {
Resque::setBackend($REDIS_BACKEND); \Resque\Resque::setBackend($REDIS_BACKEND);
} else { } else {
Resque::setBackend($REDIS_BACKEND, $REDIS_BACKEND_DB); \Resque\Resque::setBackend($REDIS_BACKEND, $REDIS_BACKEND_DB);
} }
} }
// Set Logging level
$logLevel = false; $logLevel = false;
$LOGGING = getenv('LOGLEVEL'); $LOGGING = getenv('LOGLEVEL');
if (!empty($LOGGING)) { if (!empty($LOGGING)) {
$logLevel = $LOGGING; $logLevel = $LOGGING;
} }
// Bootstrap file
$APP_INCLUDE = getenv('APP_INCLUDE'); $APP_INCLUDE = getenv('APP_INCLUDE');
if ($APP_INCLUDE) { if ($APP_INCLUDE) {
if (!file_exists($APP_INCLUDE)) { if (!file_exists($APP_INCLUDE)) {
@ -66,41 +68,45 @@ if ($APP_INCLUDE) {
// See if the APP_INCLUDE containes a logger object, // See if the APP_INCLUDE containes a logger object,
// If none exists, fallback to internal logger // If none exists, fallback to internal logger
if (!isset($logger) || !is_object($logger)) { if (!isset($logger) || !is_object($logger)) {
$logger = new Resque_Log($logLevel); $logger = new \Resque\Log($logLevel);
} }
// Determines if blocking or not
$BLOCKING = getenv('BLOCKING') !== FALSE; $BLOCKING = getenv('BLOCKING') !== FALSE;
// Interval to check for jobs
$interval = 5; $interval = 5;
$INTERVAL = getenv('INTERVAL'); $INTERVAL = getenv('INTERVAL');
if (!empty($INTERVAL)) { if (!empty($INTERVAL)) {
$interval = $INTERVAL; $interval = $INTERVAL;
} }
// Sets worker count
$count = 1; $count = 1;
$COUNT = getenv('COUNT'); $COUNT = getenv('COUNT');
if (!empty($COUNT) && $COUNT > 1) { if (!empty($COUNT) && $COUNT > 1) {
$count = $COUNT; $count = $COUNT;
} }
// Determines redis key prefix
$PREFIX = getenv('PREFIX'); $PREFIX = getenv('PREFIX');
if (!empty($PREFIX)) { if (!empty($PREFIX)) {
$logger->log(Psr\Log\LogLevel::INFO, 'Prefix set to {prefix}', ['prefix' => $PREFIX]); $logger->log(\Psr\Log\LogLevel::INFO, 'Prefix set to {prefix}', ['prefix' => $PREFIX]);
Resque_Redis::prefix($PREFIX); \Resque\Redis::prefix($PREFIX);
} }
if ($count > 1) { if ($count > 1) {
for ($i = 0; $i < $count; ++$i) { for ($i = 0; $i < $count; ++$i) {
$pid = Resque::fork(); $pid = \Resque\Resque::fork();
if ($pid === false || $pid === -1) { if ($pid === false || $pid === -1) {
$logger->log(Psr\Log\LogLevel::EMERGENCY, 'Could not fork worker {count}', ['count' => $i]); $logger->log(\Psr\Log\LogLevel::EMERGENCY, 'Could not fork worker {count}', ['count' => $i]);
die(); die();
} elseif (!$pid) { } elseif (!$pid) {
// Child, start the worker // Child, start the worker
$queues = explode(',', $QUEUE); $queues = explode(',', $QUEUE);
$worker = new Resque_Worker($queues); $worker = new \Resque\Worker($queues);
$worker->setLogger($logger); $worker->setLogger($logger);
$logger->log(Psr\Log\LogLevel::NOTICE, 'Starting worker {worker}', ['worker' => $worker]); $logger->log(\Psr\Log\LogLevel::NOTICE, 'Starting worker {worker}', ['worker' => $worker]);
$worker->work($interval, $BLOCKING); $worker->work($interval, $BLOCKING);
break; break;
} }
@ -108,7 +114,7 @@ if ($count > 1) {
} else { } else {
// Start a single worker // Start a single worker
$queues = explode(',', $QUEUE); $queues = explode(',', $QUEUE);
$worker = new Resque_Worker($queues); $worker = new \Resque\Worker($queues);
$worker->setLogger($logger); $worker->setLogger($logger);
$PIDFILE = getenv('PIDFILE'); $PIDFILE = getenv('PIDFILE');
@ -117,6 +123,6 @@ if ($count > 1) {
die('Could not write PID information to ' . $PIDFILE); die('Could not write PID information to ' . $PIDFILE);
} }
$logger->log(Psr\Log\LogLevel::NOTICE, 'Starting worker {worker}', ['worker' => $worker]); $logger->log(\Psr\Log\LogLevel::NOTICE, 'Starting worker {worker}', ['worker' => $worker]);
$worker->work($interval, $BLOCKING); $worker->work($interval, $BLOCKING);
} }

View File

@ -1,18 +0,0 @@
<!--suppress PhingDomInspection -->
<project name="php-resque" default="build">
<target name="clean">
<delete dir="${basedir}/build" />
</target>
<target name="prepare">
<mkdir dir="${basedir}/build" />
<mkdir dir="${basedir}/build/logs" />
</target>
<target name="phpunit">
<exec dir="${basedir}" executable="phpunit">
<arg line="--log-junit ${basedir}/build/logs/phpunit.xml
--coverage-clover ${basedir}/build/logs/clover.xml
--coverage-html ${basedir}/build/coverage" />
</exec>
</target>
<target name="build" depends="clean,prepare,phpunit" />
</project>

View File

@ -1,6 +1,5 @@
{ {
"name": "idanoo/php-resque", "name": "idanoo/php-resque",
"version": "1.4.7",
"type": "library", "type": "library",
"replace": { "replace": {
"chrisboulton/php-resque": "*", "chrisboulton/php-resque": "*",
@ -17,21 +16,25 @@
} }
], ],
"require": { "require": {
"php": "^7.0", "php": ">7.4",
"ext-pcntl": "*", "psr/log": "^1.1.0",
"ext-redis": "*", "colinmollenhour/credis": "^1.12.0"
"psr/log": "~1.0",
"colinmollenhour/credis": "^1.10"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9" "phpunit/phpunit": "^9",
"squizlabs/php_codesniffer": "3.*"
}, },
"bin": [ "bin": [
"bin/resque" "bin/resque"
], ],
"autoload": { "autoload": {
"psr-0": { "psr-4": {
"Resque": "lib" "Resque\\": "src/Resque"
}
},
"autoload-dev": {
"psr-4": {
"Resque\\Test\\": "tests/Resque/Tests"
} }
}, },
"support": { "support": {

1470
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +0,0 @@
<?php
class Bad_PHP_Job
{
public function perform()
{
throw new Exception('Unable to run this job!');
}
}

View File

@ -1,9 +0,0 @@
<?php /** @noinspection PhpUndefinedFunctionInspection */
class PHP_Error_Job
{
public function perform()
{
callToUndefinedFunction();
}
}

View File

@ -1,7 +0,0 @@
<?php
date_default_timezone_set('GMT');
require 'bad_job.php';
require 'job.php';
require 'php_error_job.php';
require '../bin/resque';

11
examples/BadPHPJob.php Normal file
View File

@ -0,0 +1,11 @@
<?php
namespace Resque\Example;
class BadPHPJob
{
public function perform()
{
throw new \Exception('Unable to run this job!');
}
}

View File

@ -1,4 +1,7 @@
<?php <?php
namespace Resque\Example;
if (empty($argv[1])) { if (empty($argv[1])) {
die('Specify the ID of a job to monitor the status of.'); die('Specify the ID of a job to monitor the status of.');
} }
@ -6,12 +9,12 @@ if (empty($argv[1])) {
require __DIR__ . '/init.php'; require __DIR__ . '/init.php';
date_default_timezone_set('GMT'); date_default_timezone_set('GMT');
Resque::setBackend('127.0.0.1:6379'); \Resque\Resque::setBackend('127.0.0.1:6379');
// You can also use a DSN-style format: // You can also use a DSN-style format:
//Resque::setBackend('redis://user:pass@127.0.0.1:6379'); //Resque::setBackend('redis://user:pass@127.0.0.1:6379');
//Resque::setBackend('redis://user:pass@a.host.name:3432/2'); //Resque::setBackend('redis://user:pass@a.host.name:3432/2');
$status = new Resque_Job_Status($argv[1]); $status = new \Resque\Job\Status($argv[1]);
if (!$status->isTracking()) { if (!$status->isTracking()) {
die("Resque is not tracking the status of this job.\n"); die("Resque is not tracking the status of this job.\n");
} }

View File

@ -1,4 +1,7 @@
<?php <?php
namespace Resque\Example;
// Find and initialize Composer // Find and initialize Composer
// NOTE: You should NOT use this when developing against php-resque. // NOTE: You should NOT use this when developing against php-resque.
// The autoload code below is specifically for this demo. // The autoload code below is specifically for this demo.
@ -8,7 +11,6 @@ $files = [
__DIR__ . '/../vendor/autoload.php', __DIR__ . '/../vendor/autoload.php',
]; ];
$found = false;
foreach ($files as $file) { foreach ($files as $file) {
if (file_exists($file)) { if (file_exists($file)) {
require_once $file; require_once $file;

View File

@ -1,6 +1,8 @@
<?php <?php
class Long_PHP_Job namespace Resque\Example;
class LongPHPJob
{ {
public function perform() public function perform()
{ {

13
examples/PHPErrorJob.php Normal file
View File

@ -0,0 +1,13 @@
<?php
/** @noinspection PhpUndefinedFunctionInspection */
namespace Resque\Example;
class PHPErrorJob
{
public function perform()
{
callToUndefinedFunction();
}
}

View File

@ -1,6 +1,8 @@
<?php <?php
class PHP_Job namespace Resque\Example;
class PHPJob
{ {
public function perform() public function perform()
{ {

View File

@ -1,14 +1,17 @@
<?php <?php
// Somewhere in our application, we need to register:
Resque_Event::listen('afterEnqueue', ['My_Resque_Plugin', 'afterEnqueue']);
Resque_Event::listen('beforeFirstFork', ['My_Resque_Plugin', 'beforeFirstFork']);
Resque_Event::listen('beforeFork', ['My_Resque_Plugin', 'beforeFork']);
Resque_Event::listen('afterFork', ['My_Resque_Plugin', 'afterFork']);
Resque_Event::listen('beforePerform', ['My_Resque_Plugin', 'beforePerform']);
Resque_Event::listen('afterPerform', ['My_Resque_Plugin', 'afterPerform']);
Resque_Event::listen('onFailure', ['My_Resque_Plugin', 'onFailure']);
class Sample_Resque_Plugin namespace Resque\Example;
// Somewhere in our application, we need to register:
// \Resque\Event::listen('afterEnqueue', ['My_Resque_Plugin', 'afterEnqueue']);
// \Resque\Event::listen('beforeFirstFork', ['My_Resque_Plugin', 'beforeFirstFork']);
// \Resque\Event::listen('beforeFork', ['My_Resque_Plugin', 'beforeFork']);
// \Resque\Event::listen('afterFork', ['My_Resque_Plugin', 'afterFork']);
// \Resque\Event::listen('beforePerform', ['My_Resque_Plugin', 'beforePerform']);
// \Resque\Event::listen('afterPerform', ['My_Resque_Plugin', 'afterPerform']);
// \Resque\Event::listen('onFailure', ['My_Resque_Plugin', 'onFailure']);
class SampleResquePlugin
{ {
public static function afterEnqueue($class, $arguments) public static function afterEnqueue($class, $arguments)
{ {

View File

@ -1,11 +1,14 @@
<?php <?php
namespace Resque\Example;
if (empty($argv[1])) { if (empty($argv[1])) {
die('Specify the name of a job to add. e.g, php queue.php PHP_Job'); die('Specify the name of a job to add. e.g, php queue.php PHPJob');
} }
require __DIR__ . '/init.php'; require __DIR__ . '/init.php';
date_default_timezone_set('GMT'); date_default_timezone_set('GMT');
Resque::setBackend('127.0.0.1:6379'); \Resque\Resque::setBackend('127.0.0.1:6379');
// You can also use a DSN-style format: // You can also use a DSN-style format:
//Resque::setBackend('redis://user:pass@127.0.0.1:6379'); //Resque::setBackend('redis://user:pass@127.0.0.1:6379');
@ -18,9 +21,9 @@ $args = [
], ],
]; ];
if (empty($argv[2])) { if (empty($argv[2])) {
$jobId = Resque::enqueue('default', $argv[1], $args, true); $jobId = \Resque\Resque::enqueue('default', $argv[1], $args, true);
} else { } else {
$jobId = Resque::enqueue($argv[1], $argv[2], $args, true); $jobId = \Resque\Resque::enqueue($argv[1], $argv[2], $args, true);
} }
echo "Queued job " . $jobId . "\n\n"; echo "Queued job " . $jobId . "\n\n";

View File

@ -5,6 +5,6 @@
compress compress
compressoptions -4 compressoptions -4
notifempty notifempty
create 640 root adm create 640 root www-data
copytruncate copytruncate
} }

View File

@ -1,15 +0,0 @@
# Borrowed with modifications from
# https://github.com/defunkt/resque/blob/master/examples/monit/resque.monit
# Replace these with your own:
# [QUEUE]
# [PATH/TO/RESQUE]
# [UID]
# [GID]
# [APP_INCLUDE]
check process resque_worker_[QUEUE]
with pidfile /var/run/resque/worker_[QUEUE].pid
start program = "/bin/sh -c 'APP_INCLUDE=[APP_INCLUDE] QUEUE=[QUEUE] VERBOSE=1 PIDFILE=/var/run/resque/worker_[QUEUE].pid nohup php -f [PATH/TO/RESQUE]/bin/resque > /var/log/resque/worker_[QUEUE].log &'" as uid [UID] and gid [GID]
stop program = "/bin/sh -c 'kill -s QUIT `cat /var/run/resque/worker_[QUEUE].pid` && rm -f /var/run/resque/worker_[QUEUE].pid; exit 0;'"
if totalmem is greater than 300 MB for 10 cycles then restart # eating up memory?
group resque_workers

View File

@ -1,12 +0,0 @@
<?php
interface Resque_Job_FactoryInterface
{
/**
* @param $className
* @param array $args
* @param $queue
* @return Resque_JobInterface
*/
public function create($className, $args, $queue);
}

View File

@ -1,24 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false" <phpunit backupGlobals="false"
bootstrap="test/bootstrap.php" bootstrap="tests/bootstrap.php"
backupStaticAttributes="false" backupStaticAttributes="false"
colors="true" colors="true"
convertErrorsToExceptions="true" convertErrorsToExceptions="true"
convertNoticesToExceptions="true" convertNoticesToExceptions="true"
convertWarningsToExceptions="true" convertWarningsToExceptions="true"
processIsolation="false" processIsolation="true"
stopOnFailure="false" stopOnFailure="false"
syntaxCheck="false"
> >
<testsuites> <testsuites>
<testsuite name="Resque Test Suite"> <testsuite name="Resque Test Suite">
<directory>./test/Resque/</directory> <directory>./tests/Resque/</directory>
</testsuite> </testsuite>
</testsuites> </testsuites>
<filter>
<whitelist>
<directory suffix=".php">./lib/Resque/</directory>
</whitelist>
</filter>
</phpunit> </phpunit>

25
ruleset.xml Normal file
View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<ruleset name="phpresque" namespace="ezyVet\PHPCS">
<description>PSR12</description>
<file>.</file>
<exclude-pattern>vendor/</exclude-pattern>
<exclude-pattern>tests/</exclude-pattern>
<arg name="extensions" value="php" />
<arg name="colors"/>
<arg value="sp"/>
<arg name="parallel" value="16"/>
<arg name="report-width" value="140" />
<ini name="memory_limit" value="256M"/>
<rule ref="PSR12">
<!-- <severity>8</severity> -->
<show_warnings>0</show_warnings>
</rule>
<!-- <rule ref="PSR1.Classes.ClassDeclaration.MissingNamespace">
<exclude-pattern>src</exclude-pattern>
</rule> -->
</ruleset>

View File

@ -1,14 +1,16 @@
<?php <?php
namespace Resque;
/** /**
* Resque event/plugin system class * Resque event/plugin system class
* *
* @package Resque/Event * @package Resque/Event
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Event class Event
{ {
/** /**
* @var array Array containing all registered callbacks, indexked by event name. * @var array Array containing all registered callbacks, indexked by event name.
@ -36,7 +38,8 @@ class Resque_Event
if (!is_callable($callback)) { if (!is_callable($callback)) {
continue; continue;
} }
call_user_func_array($callback, $data);
call_user_func_array($callback, array_values($data));
} }
return true; return true;

View File

@ -1,13 +1,16 @@
<?php <?php
namespace Resque;
/** /**
* Resque exception. * Resque exception.
* *
* @package Resque * @package Resque
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Exception extends Exception class Exception extends \Exception
{ {
} }

View File

@ -1,14 +1,16 @@
<?php <?php
namespace Resque\Failure;
/** /**
* Failed Resque job. * Failed Resque job.
* *
* @package Resque/Failure * @package Resque/Failure
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Failure class Failure
{ {
/** /**
* @var string Class name representing the backend to pass failed jobs off to. * @var string Class name representing the backend to pass failed jobs off to.
@ -19,11 +21,11 @@ class Resque_Failure
* Create a new failed job on the backend. * Create a new failed job on the backend.
* *
* @param array $payload The contents of the job that has just failed. * @param array $payload The contents of the job that has just failed.
* @param Exception $exception The exception generated when the job failed to run. * @param \Exception $exception The exception generated when the job failed to run.
* @param Resque_Worker $worker Instance of Resque_Worker that was running this job when it failed. * @param \Resque\Worker $worker Instance of Resque_Worker that was running this job when it failed.
* @param string $queue The name of the queue that this job was fetched from. * @param string $queue The name of the queue that this job was fetched from.
*/ */
public static function create($payload, Exception $exception, Resque_Worker $worker, $queue) public static function create($payload, \Exception $exception, \Resque\Worker $worker, $queue)
{ {
$backend = self::getBackend(); $backend = self::getBackend();
new $backend($payload, $exception, $worker, $queue); new $backend($payload, $exception, $worker, $queue);
@ -37,7 +39,7 @@ class Resque_Failure
public static function getBackend() public static function getBackend()
{ {
if (self::$backend === null) { if (self::$backend === null) {
self::$backend = 'Resque_Failure_Redis'; self::$backend = '\\Resque\\Failure\\ResqueFailureRedis';
} }
return self::$backend; return self::$backend;

View File

@ -1,13 +1,15 @@
<?php <?php
namespace Resque\Failure;
/** /**
* Interface that all failure backends should implement. * Interface that all failure backends should implement.
* *
* @package Resque/Failure * @package Resque\Failure
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
interface Resque_Failure_Interface interface ResqueFailureInterface
{ {
/** /**
* Initialize a failed job class and save it (where appropriate). * Initialize a failed job class and save it (where appropriate).

View File

@ -1,13 +1,16 @@
<?php <?php
namespace Resque\Failure;
/** /**
* Redis backend for storing failed Resque jobs. * Redis backend for storing failed Resque jobs.
* *
* @package Resque/Failure * @package Resque\Failure
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Failure_Redis implements Resque_Failure_Interface class ResqueFailureRedis implements ResqueFailureInterface
{ {
/** /**
* Initialize a failed job class and save it (where appropriate). * Initialize a failed job class and save it (where appropriate).
@ -16,11 +19,11 @@ class Resque_Failure_Redis implements Resque_Failure_Interface
* @param object $exception Instance of the exception that was thrown by the failed job. * @param object $exception Instance of the exception that was thrown by the failed job.
* @param object $worker Instance of Resque_Worker that received the job. * @param object $worker Instance of Resque_Worker that received the job.
* @param string $queue The name of the queue the job was fetched from. * @param string $queue The name of the queue the job was fetched from.
* @throws Resque_RedisException * @throws \Resque\RedisException
*/ */
public function __construct($payload, $exception, $worker, $queue) public function __construct($payload, $exception, $worker, $queue)
{ {
$data = new stdClass; $data = new \stdClass();
$data->failed_at = strftime('%a %b %d %H:%M:%S %Z %Y'); $data->failed_at = strftime('%a %b %d %H:%M:%S %Z %Y');
$data->payload = $payload; $data->payload = $payload;
$data->exception = get_class($exception); $data->exception = get_class($exception);
@ -29,6 +32,6 @@ class Resque_Failure_Redis implements Resque_Failure_Interface
$data->worker = (string)$worker; $data->worker = (string)$worker;
$data->queue = $queue; $data->queue = $queue;
$data = json_encode($data); $data = json_encode($data);
Resque::redis()->rpush('failed', $data); \Resque\Resque::redis()->rpush('failed', $data);
} }
} }

View File

@ -1,13 +1,15 @@
<?php <?php
namespace Resque\Job;
/** /**
* Runtime exception class for a job that does not exit cleanly. * Runtime exception class for a job that does not exit cleanly.
* *
* @package Resque/Job * @package Resque/Job
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Job_DirtyExitException extends RuntimeException class DirtyExitException extends \RuntimeException
{ {
} }

View File

@ -1,13 +1,15 @@
<?php <?php
namespace Resque\Job;
/** /**
* Exception to be thrown if while enqueuing a job it should not be created. * Exception to be thrown if while enqueuing a job it should not be created.
* *
* @package Resque/Job * @package Resque/Job
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Job_DontCreate extends Exception class DontCreate extends \Exception
{ {
} }

View File

@ -1,14 +1,15 @@
<?php <?php
namespace Resque\Job;
/** /**
* Exception to be thrown if a job should not be performed/run. * Exception to be thrown if a job should not be performed/run.
* *
* @package Resque/Job * @package Resque/Job
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class DontPerform extends \Exception
class Resque_Job_DontPerform extends Exception
{ {
} }

View File

@ -1,30 +1,39 @@
<?php <?php
class Resque_Job_Factory implements Resque_Job_FactoryInterface namespace Resque\Job;
/**
* Job Factory!
*
* @package Resque/Job
* @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php
*/
class Factory implements FactoryInterface
{ {
/** /**
* @param $className * @param $className
* @param array $args * @param array $args
* @param $queue * @param $queue
* @return Resque_JobInterface * @return \Resque\Job\JobInterface
* @throws Resque_Exception * @throws \Resque\Exception
*/ */
public function create($className, $args, $queue) public function create($className, $args, $queue)
{ {
if (!class_exists($className)) { if (!class_exists($className)) {
throw new Resque_Exception( throw new \Resque\Exception(
'Could not find job class ' . $className . '.' 'Could not find job class ' . $className . '.'
); );
} }
if (!method_exists($className, 'perform')) { if (!method_exists($className, 'perform')) {
throw new Resque_Exception( throw new \Resque\Exception(
'Job class ' . $className . ' does not contain a perform method.' 'Job class ' . $className . ' does not contain a perform method.'
); );
} }
$instance = new $className; $instance = new $className();
$instance->args = $args; $instance->args = $args;
$instance->queue = $queue; $instance->queue = $queue;
return $instance; return $instance;

View File

@ -0,0 +1,21 @@
<?php
namespace Resque\Job;
/**
* Job Interface
*
* @package Resque/Job
* @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php
*/
interface FactoryInterface
{
/**
* @param $className
* @param array $args
* @param $queue
* @return \Resque\Job\JobInterface
*/
public function create($className, $args, $queue);
}

View File

@ -1,14 +1,16 @@
<?php <?php
namespace Resque\Job;
/** /**
* Resque job. * Resque job.
* *
* @package Resque/Job * @package Resque/Job
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Job class Job
{ {
/** /**
* @var string The name of the queue that this job belongs to. * @var string The name of the queue that this job belongs to.
@ -16,7 +18,7 @@ class Resque_Job
public $queue; public $queue;
/** /**
* @var Resque_Worker Instance of the Resque worker running this job. * @var \Resque\Worker Instance of the Resque worker running this job.
*/ */
public $worker; public $worker;
@ -26,12 +28,12 @@ class Resque_Job
public $payload; public $payload;
/** /**
* @var object|Resque_JobInterface Instance of the class performing work for this job. * @var object|\Resque\Job\JobInterface Instance of the class performing work for this job.
*/ */
private $instance; private $instance;
/** /**
* @var Resque_Job_FactoryInterface * @var \Resque\Job\FactoryInterface
*/ */
private $jobFactory; private $jobFactory;
@ -57,20 +59,20 @@ class Resque_Job
* @param string $id Unique identifier for tracking the job. Generated if not supplied. * @param string $id Unique identifier for tracking the job. Generated if not supplied.
* *
* @return string * @return string
* @throws InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public static function create($queue, $class, $args = null, $monitor = false, $id = null) public static function create($queue, $class, $args = null, $monitor = false, $id = null)
{ {
if (is_null($id)) { if (is_null($id)) {
$id = Resque::generateJobId(); $id = \Resque\Resque::generateJobId();
} }
if ($args !== null && !is_array($args)) { if ($args !== null && !is_array($args)) {
throw new InvalidArgumentException( throw new \InvalidArgumentException(
'Supplied $args must be an array.' 'Supplied $args must be an array.'
); );
} }
Resque::push($queue, [ \Resque\Resque::push($queue, [
'class' => $class, 'class' => $class,
'args' => [$args], 'args' => [$args],
'id' => $id, 'id' => $id,
@ -78,7 +80,7 @@ class Resque_Job
]); ]);
if ($monitor) { if ($monitor) {
Resque_Job_Status::create($id); Status::create($id);
} }
return $id; return $id;
@ -86,43 +88,43 @@ class Resque_Job
/** /**
* Find the next available job from the specified queue and return an * Find the next available job from the specified queue and return an
* instance of Resque_Job for it. * instance of \Resque\Job\Job for it.
* *
* @param string $queue The name of the queue to check for a job in. * @param string $queue The name of the queue to check for a job in.
* @return false|object Null when there aren't any waiting jobs, instance of Resque_Job when a job was found. * @return false|object Null when there aren't any waiting jobs, instance of \Resque\Job\Job when a job was found.
*/ */
public static function reserve($queue) public static function reserve($queue)
{ {
$payload = Resque::pop($queue); $payload = \Resque\Resque::pop($queue);
if (!is_array($payload)) { if (!is_array($payload)) {
return false; return false;
} }
return new Resque_Job($queue, $payload); return new Job($queue, $payload);
} }
/** /**
* Find the next available job from the specified queues using blocking list pop * Find the next available job from the specified queues using blocking list pop
* and return an instance of Resque_Job for it. * and return an instance of \Resque\Job\Job for it.
* *
* @param array $queues * @param array $queues
* @param int $timeout * @param int $timeout
* @return false|object Null when there aren't any waiting jobs, instance of Resque_Job when a job was found. * @return false|object Null when there aren't any waiting jobs, instance of \Resque\Job\Job when a job was found.
*/ */
public static function reserveBlocking(array $queues, $timeout = null) public static function reserveBlocking(array $queues, $timeout = null)
{ {
$item = Resque::blpop($queues, $timeout); $item = \Resque\Resque::blpop($queues, $timeout);
if (!is_array($item)) { if (!is_array($item)) {
return false; return false;
} }
return new Resque_Job($item['queue'], $item['payload']); return new Job($item['queue'], $item['payload']);
} }
/** /**
* Update the status of the current job. * Update the status of the current job.
* *
* @param int $status Status constant from Resque_Job_Status indicating the current status of a job. * @param int $status Status constant from \Resque\Job\Status indicating the current status of a job.
*/ */
public function updateStatus($status): bool public function updateStatus($status): bool
{ {
@ -130,7 +132,7 @@ class Resque_Job
return false; return false;
} }
$statusInstance = new Resque_Job_Status($this->payload['id']); $statusInstance = new Status($this->payload['id']);
$statusInstance->update($status); $statusInstance->update($status);
return true; return true;
} }
@ -138,11 +140,11 @@ class Resque_Job
/** /**
* Return the status of the current job. * Return the status of the current job.
* *
* @return int The status of the job as one of the Resque_Job_Status constants. * @return int The status of the job as one of the \Resque\Job\Status constants.
*/ */
public function getStatus() public function getStatus()
{ {
$status = new Resque_Job_Status($this->payload['id']); $status = new Status($this->payload['id']);
return $status->get(); return $status->get();
} }
@ -162,7 +164,7 @@ class Resque_Job
/** /**
* Get the instantiated object for this job that will be performing work. * Get the instantiated object for this job that will be performing work.
* @return Resque_JobInterface Instance of the object that this job belongs to. * @return \Resque\Job\JobInterface Instance of the object that this job belongs to.
*/ */
public function getInstance() public function getInstance()
{ {
@ -180,12 +182,12 @@ class Resque_Job
* associated with the job with the supplied arguments. * associated with the job with the supplied arguments.
* *
* @return bool * @return bool
* @throws Resque_Exception When the job's class could not be found or it does not contain a perform method. * @throws \Resque\Exception When the job's class could not be found or it does not contain a perform method.
*/ */
public function perform() public function perform()
{ {
try { try {
Resque_Event::trigger('beforePerform', $this); \Resque\Event::trigger('beforePerform', $this);
$instance = $this->getInstance(); $instance = $this->getInstance();
if (method_exists($instance, 'setUp')) { if (method_exists($instance, 'setUp')) {
@ -198,9 +200,9 @@ class Resque_Job
$instance->tearDown(); $instance->tearDown();
} }
Resque_Event::trigger('afterPerform', $this); \Resque\Event::trigger('afterPerform', $this);
} // beforePerform/setUp have said don't perform this job. Return. } catch (DontPerform $e) {
/** @noinspection PhpRedundantCatchClauseInspection */ catch (Resque_Job_DontPerform $e) { /** @noinspection PhpRedundantCatchClauseInspection */
return false; return false;
} }
@ -214,20 +216,20 @@ class Resque_Job
*/ */
public function fail($exception) public function fail($exception)
{ {
Resque_Event::trigger('onFailure', [ \Resque\Event::trigger('onFailure', [
'exception' => $exception, 'exception' => $exception,
'job' => $this, 'job' => $this,
]); ]);
$this->updateStatus(Resque_Job_Status::STATUS_FAILED); $this->updateStatus(Status::STATUS_FAILED);
Resque_Failure::create( \Resque\Failure\Failure::create(
$this->payload, $this->payload,
$exception, $exception,
$this->worker, $this->worker,
$this->queue $this->queue
); );
Resque_Stat::incr('failed'); \Resque\Stat::incr('failed');
Resque_Stat::incr('failed:' . $this->worker); \Resque\Stat::incr('failed:' . $this->worker);
} }
/** /**
@ -236,7 +238,7 @@ class Resque_Job
*/ */
public function recreate() public function recreate()
{ {
$status = new Resque_Job_Status($this->payload['id']); $status = new Status($this->payload['id']);
$monitor = false; $monitor = false;
if ($status->isTracking()) { if ($status->isTracking()) {
$monitor = true; $monitor = true;
@ -266,10 +268,10 @@ class Resque_Job
} }
/** /**
* @param Resque_Job_FactoryInterface $jobFactory * @param FactoryInterface $jobFactory
* @return Resque_Job * @return Job
*/ */
public function setJobFactory(Resque_Job_FactoryInterface $jobFactory) public function setJobFactory(FactoryInterface $jobFactory)
{ {
$this->jobFactory = $jobFactory; $this->jobFactory = $jobFactory;
@ -277,12 +279,12 @@ class Resque_Job
} }
/** /**
* @return Resque_Job_FactoryInterface * @return FactoryInterface
*/ */
public function getJobFactory() public function getJobFactory()
{ {
if ($this->jobFactory === null) { if ($this->jobFactory === null) {
$this->jobFactory = new Resque_Job_Factory(); $this->jobFactory = new Factory();
} }
return $this->jobFactory; return $this->jobFactory;
} }

View File

@ -1,6 +1,8 @@
<?php <?php
interface Resque_JobInterface namespace Resque\Job;
interface JobInterface
{ {
/** /**
* @return bool * @return bool

View File

@ -1,19 +1,21 @@
<?php <?php
namespace Resque\Job;
/** /**
* Status tracker/information for a job. * Status tracker/information for a job.
* *
* @package Resque/Job * @package Resque/Job
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Job_Status class Status
{ {
const STATUS_WAITING = 1; public const STATUS_WAITING = 1;
const STATUS_RUNNING = 2; public const STATUS_RUNNING = 2;
const STATUS_FAILED = 3; public const STATUS_FAILED = 3;
const STATUS_COMPLETE = 4; public const STATUS_COMPLETE = 4;
/** /**
* @var string The ID of the job this status class refers back to. * @var string The ID of the job this status class refers back to.
@ -57,7 +59,7 @@ class Resque_Job_Status
'updated' => time(), 'updated' => time(),
'started' => time(), 'started' => time(),
]; ];
Resque::redis()->set('job:' . $id . ':status', json_encode($statusPacket)); \Resque\Resque::redis()->set('job:' . $id . ':status', json_encode($statusPacket));
} }
/** /**
@ -72,7 +74,7 @@ class Resque_Job_Status
return false; return false;
} }
if (!Resque::redis()->exists((string)$this)) { if (!\Resque\Resque::redis()->exists((string)$this)) {
$this->isTracking = false; $this->isTracking = false;
return false; return false;
} }
@ -84,7 +86,7 @@ class Resque_Job_Status
/** /**
* Update the status indicator for the current job with a new status. * Update the status indicator for the current job with a new status.
* *
* @param int The status of the job (see constants in Resque_Job_Status) * @param int The status of the job (see constants in \Resque\Job\Status)
*/ */
public function update($status) public function update($status)
{ {
@ -96,11 +98,11 @@ class Resque_Job_Status
'status' => $status, 'status' => $status,
'updated' => time(), 'updated' => time(),
]; ];
Resque::redis()->set((string)$this, json_encode($statusPacket)); \Resque\Resque::redis()->set((string)$this, json_encode($statusPacket));
// Expire the status for completed jobs after 24 hours // Expire the status for completed jobs after 24 hours
if (in_array($status, self::$completeStatuses)) { if (in_array($status, self::$completeStatuses)) {
Resque::redis()->expire((string)$this, 86400); \Resque\Resque::redis()->expire((string)$this, 86400);
} }
} }
@ -108,7 +110,7 @@ class Resque_Job_Status
* Fetch the status for the job being monitored. * Fetch the status for the job being monitored.
* *
* @return mixed False if the status is not being monitored, otherwise the status as * @return mixed False if the status is not being monitored, otherwise the status as
* as an integer, based on the Resque_Job_Status constants. * as an integer, based on the \Resque\Job\Status constants.
*/ */
public function get() public function get()
{ {
@ -116,7 +118,7 @@ class Resque_Job_Status
return false; return false;
} }
$statusPacket = json_decode(Resque::redis()->get((string)$this), true); $statusPacket = json_decode(\Resque\Resque::redis()->get((string)$this), true);
if (!$statusPacket) { if (!$statusPacket) {
return false; return false;
} }
@ -129,7 +131,7 @@ class Resque_Job_Status
*/ */
public function stop() public function stop()
{ {
Resque::redis()->del((string)$this); \Resque\Resque::redis()->del((string)$this);
} }
/** /**

View File

@ -1,14 +1,16 @@
<?php <?php
namespace Resque;
/** /**
* Resque default logger PSR-3 compliant * Resque default logger PSR-3 compliant
* *
* @package Resque/Stat * @package Resque
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Log extends Psr\Log\AbstractLogger class Log extends \Psr\Log\AbstractLogger
{ {
public $logLevel; public $logLevel;
@ -35,7 +37,7 @@ class Resque_Log extends Psr\Log\AbstractLogger
"warning", "warning",
"notice", "notice",
"info", "info",
"debug" "debug",
]; ];
/** /**

View File

@ -1,18 +1,20 @@
<?php <?php
namespace Resque;
/** /**
* Set up phpredis connection * Set up phpredis connection
* *
* @package Resque/Redis * @package Resque/Redis
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Redis class Redis
{ {
/** /**
* Redis Client * Redis Client
* @var Credis_Client * @var \Credis_Client
*/ */
private $driver; private $driver;
@ -25,17 +27,17 @@ class Resque_Redis
/** /**
* A default host to connect to * A default host to connect to
*/ */
const DEFAULT_HOST = 'localhost'; public const DEFAULT_HOST = 'localhost';
/** /**
* The default Redis port * The default Redis port
*/ */
const DEFAULT_PORT = 6379; public const DEFAULT_PORT = 6379;
/** /**
* The default Redis Database number * The default Redis Database number
*/ */
const DEFAULT_DATABASE = 0; public const DEFAULT_DATABASE = 0;
/** /**
* @var array List of all commands in Redis that supply a key as their * @var array List of all commands in Redis that supply a key as their
@ -116,8 +118,8 @@ class Resque_Redis
* @param string|array $server A DSN or array * @param string|array $server A DSN or array
* @param int $database A database number to select. However, if we find a valid database number in the DSN the * @param int $database A database number to select. However, if we find a valid database number in the DSN the
* DSN-supplied value will be used instead and this parameter is ignored. * DSN-supplied value will be used instead and this parameter is ignored.
* @param object $client Optional Credis_Client instance instantiated by you * @param object $client Optional \Credis_Client instance instantiated by you
* @throws Resque_RedisException * @throws \Resque\RedisException
*/ */
public function __construct($server, $database = null, $client = null) public function __construct($server, $database = null, $client = null)
{ {
@ -131,7 +133,7 @@ class Resque_Redis
$timeout = isset($options['timeout']) ? intval($options['timeout']) : null; $timeout = isset($options['timeout']) ? intval($options['timeout']) : null;
$persistent = isset($options['persistent']) ? $options['persistent'] : ''; $persistent = isset($options['persistent']) ? $options['persistent'] : '';
$maxRetries = isset($options['max_connect_retries']) ? $options['max_connect_retries'] : 0; $maxRetries = isset($options['max_connect_retries']) ? $options['max_connect_retries'] : 0;
$this->driver = new Credis_Client($host, $port, $timeout, $persistent); $this->driver = new \Credis_Client($host, $port, $timeout, $persistent);
$this->driver->setMaxConnectRetries($maxRetries); $this->driver->setMaxConnectRetries($maxRetries);
if ($password) { if ($password) {
$this->driver->auth($password); $this->driver->auth($password);
@ -145,8 +147,8 @@ class Resque_Redis
if ($database !== null) { if ($database !== null) {
$this->driver->select($database); $this->driver->select($database);
} }
} catch (Exception $e) { } catch (\Exception $e) {
throw new Resque_RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e); throw new RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e);
} }
} }
@ -185,7 +187,7 @@ class Resque_Redis
// Check the URI scheme // Check the URI scheme
$validSchemes = ['redis', 'tcp']; $validSchemes = ['redis', 'tcp'];
if (isset($parts['scheme']) && !in_array($parts['scheme'], $validSchemes)) { if (isset($parts['scheme']) && !in_array($parts['scheme'], $validSchemes)) {
throw new InvalidArgumentException("Invalid DSN. Supported schemes are " . implode(', ', $validSchemes)); throw new \InvalidArgumentException("Invalid DSN. Supported schemes are " . implode(', ', $validSchemes));
} }
// Allow simple 'hostname' format, which `parse_url` treats as a path, not host. // Allow simple 'hostname' format, which `parse_url` treats as a path, not host.
@ -238,7 +240,7 @@ class Resque_Redis
{ {
if (in_array($name, $this->keyCommands)) { if (in_array($name, $this->keyCommands)) {
if (is_array($args[0])) { if (is_array($args[0])) {
foreach ($args[0] AS $i => $v) { foreach ($args[0] as $i => $v) {
$args[0][$i] = self::$defaultNamespace . $v; $args[0][$i] = self::$defaultNamespace . $v;
} }
} else { } else {
@ -247,8 +249,8 @@ class Resque_Redis
} }
try { try {
return $this->driver->__call($name, $args); return $this->driver->__call($name, $args);
} catch (CredisException $e) { } catch (\CredisException $e) {
throw new Resque_RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e); throw new RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e);
} }
} }

View File

@ -1,14 +1,16 @@
<?php <?php
namespace Resque;
/** /**
* Redis related exceptions * Redis related exceptions
* *
* @package Resque * @package Resque
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_RedisException extends Resque_Exception class RedisException extends \Exception
{ {
} }

View File

@ -1,18 +1,20 @@
<?php <?php
namespace Resque;
/** /**
* Base Resque class. * Base Resque class.
* *
* @package Resque * @package Resque
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque class Resque
{ {
const VERSION = '1.4.7'; public const VERSION = '2.0.0';
const DEFAULT_INTERVAL = 5; public const DEFAULT_INTERVAL = 5;
/** /**
* @var Resque_Redis Instance of Resque_Redis that talks to redis. * @var Resque_Redis Instance of Resque_Redis that talks to redis.
@ -50,9 +52,9 @@ class Resque
/** /**
* Return an instance of the Resque_Redis class instantiated for Resque. * Return an instance of the Resque_Redis class instantiated for Resque.
* *
* @return Resque_Redis Instance of Resque_Redis. * @return \Resque\Redis Instance of Resque_Redis.
* *
* @throws Resque_RedisException * @throws \Resque\RedisException
*/ */
public static function redis() public static function redis()
{ {
@ -63,7 +65,7 @@ class Resque
if (is_callable(self::$redisServer)) { if (is_callable(self::$redisServer)) {
self::$redis = call_user_func(self::$redisServer, self::$redisDatabase); self::$redis = call_user_func(self::$redisServer, self::$redisDatabase);
} else { } else {
self::$redis = new Resque_Redis(self::$redisServer, self::$redisDatabase); self::$redis = new \Resque\Redis(self::$redisServer, self::$redisDatabase);
} }
return self::$redis; return self::$redis;
@ -90,7 +92,7 @@ class Resque
$pid = pcntl_fork(); $pid = pcntl_fork();
if ($pid === -1) { if ($pid === -1) {
throw new RuntimeException('Unable to fork child worker.'); throw new \RuntimeException('Unable to fork child worker.');
} }
return $pid; return $pid;
@ -179,7 +181,7 @@ class Resque
*/ */
public static function blpop(array $queues, $timeout) public static function blpop(array $queues, $timeout)
{ {
$list = array(); $list = [];
foreach ($queues as $queue) { foreach ($queues as $queue) {
$list[] = 'queue:' . $queue; $list[] = 'queue:' . $queue;
} }
@ -228,20 +230,20 @@ class Resque
public static function enqueue($queue, $class, $args = null, $trackStatus = false) public static function enqueue($queue, $class, $args = null, $trackStatus = false)
{ {
$id = Resque::generateJobId(); $id = Resque::generateJobId();
$hookParams = array( $hookParams = [
'class' => $class, 'class' => $class,
'args' => $args, 'args' => $args,
'queue' => $queue, 'queue' => $queue,
'id' => $id, 'id' => $id,
); ];
try { try {
Resque_Event::trigger('beforeEnqueue', $hookParams); \Resque\Event::trigger('beforeEnqueue', $hookParams);
} catch (Resque_Job_DontCreate $e) { } catch (\Resque\Job\DontCreate $e) {
return false; return false;
} }
Resque_Job::create($queue, $class, $args, $trackStatus, $id); \Resque\Job\Job::create($queue, $class, $args, $trackStatus, $id);
Resque_Event::trigger('afterEnqueue', $hookParams); \Resque\Event::trigger('afterEnqueue', $hookParams);
return $id; return $id;
} }
@ -251,11 +253,11 @@ class Resque
* *
* @param string $queue Queue to fetch next available job from. * @param string $queue Queue to fetch next available job from.
* *
* @return false|object|Resque_Job * @return false|object|\Resque\Job\Job
*/ */
public static function reserve($queue) public static function reserve($queue)
{ {
return Resque_Job::reserve($queue); return \Resque\Job\Job::reserve($queue);
} }
/** /**
@ -347,8 +349,11 @@ class Resque
# class name with args , example: item[0] = ['class' => {'foo' => 1, 'bar' => 2}] # class name with args , example: item[0] = ['class' => {'foo' => 1, 'bar' => 2}]
} elseif (is_array($val)) { } elseif (is_array($val)) {
$decodedArgs = (array)$decoded['args'][0]; $decodedArgs = (array)$decoded['args'][0];
if ($decoded['class'] == $key && if (
count($decodedArgs) > 0 && count(array_diff($decodedArgs, $val)) == 0) { $decoded['class'] == $key
&& count($decodedArgs) > 0
&& count(array_diff($decodedArgs, $val)) == 0
) {
return true; return true;
} }
# class name with ID, example: item[0] = ['class' => 'id'] # class name with ID, example: item[0] = ['class' => 'id']
@ -369,7 +374,7 @@ class Resque
* @params string $queue the name of the queue * @params string $queue the name of the queue
* @param $queue * @param $queue
* @return integer number of deleted items belongs to this list * @return integer number of deleted items belongs to this list
* @throws Resque_RedisException * @throws \Resque\RedisException
*/ */
private static function removeList($queue) private static function removeList($queue)
{ {

View File

@ -1,14 +1,16 @@
<?php <?php
namespace Resque;
/** /**
* Resque statistic management (jobs processed, failed, etc) * Resque statistic management (jobs processed, failed, etc)
* *
* @package Resque/Stat * @package Resque
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Stat class Stat
{ {
/** /**
* Get the value of the supplied statistic counter for the specified statistic. * Get the value of the supplied statistic counter for the specified statistic.

View File

@ -1,17 +1,20 @@
<?php <?php
declare(ticks=1); declare(ticks=1);
namespace Resque;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
/** /**
* Resque worker that handles checking queues for jobs, fetching them * Resque worker that handles checking queues for jobs, fetching them
* off the queues, running them and handling the result. * off the queues, running them and handling the result.
* *
* @package Resque/Worker * @package Resque
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Worker class Worker
{ {
/** /**
* @var LoggerInterface Logging object that impliments the PSR-3 LoggerInterface * @var LoggerInterface Logging object that impliments the PSR-3 LoggerInterface
@ -44,7 +47,7 @@ class Resque_Worker
private $id; private $id;
/** /**
* @var Resque_Job Current job, if any, being processed by this worker. * @var \Resque\Job\Job Current job, if any, being processed by this worker.
*/ */
private $currentJob = null; private $currentJob = null;
@ -66,7 +69,7 @@ class Resque_Worker
*/ */
public function __construct($queues) public function __construct($queues)
{ {
$this->logger = new Resque_Log(); $this->logger = new Log();
if (!is_array($queues)) { if (!is_array($queues)) {
$queues = [$queues]; $queues = [$queues];
@ -162,8 +165,14 @@ class Resque_Worker
$job = false; $job = false;
if (!$this->paused) { if (!$this->paused) {
if ($blocking === true) { if ($blocking === true) {
$this->logger->log(Psr\Log\LogLevel::INFO, 'Starting blocking with timeout of {interval}', ['interval' => $interval]); $this->logger->log(
$this->updateProcLine('Waiting for ' . implode(',', $this->queues) . ' with blocking timeout ' . $interval); \Psr\Log\LogLevel::INFO,
'Starting blocking with timeout of {interval}',
['interval' => $interval],
);
$this->updateProcLine(
'Waiting for ' . implode(',', $this->queues) . ' with blocking timeout ' . $interval
);
} else { } else {
$this->updateProcLine('Waiting for ' . implode(',', $this->queues) . ' with interval ' . $interval); $this->updateProcLine('Waiting for ' . implode(',', $this->queues) . ' with interval ' . $interval);
} }
@ -179,7 +188,12 @@ class Resque_Worker
if ($blocking === false) { if ($blocking === false) {
// If no job was found, we sleep for $interval before continuing and checking again // If no job was found, we sleep for $interval before continuing and checking again
$this->logger->log(Psr\Log\LogLevel::INFO, 'Sleeping for {interval}', ['interval' => $interval]); $this->logger->log(
\Psr\Log\LogLevel::INFO,
'Sleeping for {interval}',
['interval' => $interval],
);
if ($this->paused) { if ($this->paused) {
$this->updateProcLine('Paused'); $this->updateProcLine('Paused');
} else { } else {
@ -192,8 +206,8 @@ class Resque_Worker
continue; continue;
} }
$this->logger->log(Psr\Log\LogLevel::NOTICE, 'Starting work on {job}', ['job' => $job]); $this->logger->log(\Psr\Log\LogLevel::NOTICE, 'Starting work on {job}', ['job' => $job]);
Resque_Event::trigger('beforeFork', $job); Event::trigger('beforeFork', $job);
$this->workingOn($job); $this->workingOn($job);
$this->child = Resque::fork(); $this->child = Resque::fork();
@ -202,7 +216,7 @@ class Resque_Worker
if ($this->child === 0 || $this->child === false) { if ($this->child === 0 || $this->child === false) {
$status = 'Processing ' . $job->queue . ' since ' . strftime('%F %T'); $status = 'Processing ' . $job->queue . ' since ' . strftime('%F %T');
$this->updateProcLine($status); $this->updateProcLine($status);
$this->logger->log(Psr\Log\LogLevel::INFO, $status); $this->logger->log(\Psr\Log\LogLevel::INFO, $status);
/** @noinspection PhpParamsInspection */ /** @noinspection PhpParamsInspection */
$this->perform($job); $this->perform($job);
if ($this->child === 0) { if ($this->child === 0) {
@ -214,13 +228,13 @@ class Resque_Worker
// Parent process, sit and wait // Parent process, sit and wait
$status = 'Forked ' . $this->child . ' at ' . strftime('%F %T'); $status = 'Forked ' . $this->child . ' at ' . strftime('%F %T');
$this->updateProcLine($status); $this->updateProcLine($status);
$this->logger->log(Psr\Log\LogLevel::INFO, $status); $this->logger->log(\Psr\Log\LogLevel::INFO, $status);
// Wait until the child process finishes before continuing // Wait until the child process finishes before continuing
pcntl_wait($status); pcntl_wait($status);
$exitStatus = pcntl_wexitstatus($status); $exitStatus = pcntl_wexitstatus($status);
if ($exitStatus !== 0) { if ($exitStatus !== 0) {
$job->fail(new Resque_Job_DirtyExitException( $job->fail(new \Resque\Job\DirtyExitException(
'Job exited with exit code ' . $exitStatus 'Job exited with exit code ' . $exitStatus
)); ));
} }
@ -236,27 +250,27 @@ class Resque_Worker
/** /**
* Process a single job. * Process a single job.
* *
* @param Resque_Job $job The job to be processed. * @param \Resque\Job\Job $job The job to be processed.
*/ */
public function perform(Resque_Job $job) public function perform(\Resque\Job\Job $job)
{ {
try { try {
Resque_Event::trigger('afterFork', $job); Event::trigger('afterFork', $job);
$job->perform(); $job->perform();
} catch (Exception $e) { } catch (\Exception $e) {
$this->logger->log(Psr\Log\LogLevel::CRITICAL, '{job} has failed {stack}', ['job' => $job, 'stack' => $e]); $this->logger->log(\Psr\Log\LogLevel::CRITICAL, '{job} has failed {stack}', ['job' => $job, 'stack' => $e]);
$job->fail($e); $job->fail($e);
return; return;
} }
$job->updateStatus(Resque_Job_Status::STATUS_COMPLETE); $job->updateStatus(\Resque\Job\Status::STATUS_COMPLETE);
$this->logger->log(Psr\Log\LogLevel::NOTICE, '{job} has finished', ['job' => $job]); $this->logger->log(\Psr\Log\LogLevel::NOTICE, '{job} has finished', ['job' => $job]);
} }
/** /**
* @param bool $blocking * @param bool $blocking
* @param int $timeout * @param int $timeout
* @return object|boolean Instance of Resque_Job if a job is found, false if not. * @return object|boolean Instance of \Resque\Job\Job if a job is found, false if not.
*/ */
public function reserve($blocking = false, $timeout = null) public function reserve($blocking = false, $timeout = null)
{ {
@ -266,17 +280,17 @@ class Resque_Worker
} }
if ($blocking === true) { if ($blocking === true) {
$job = Resque_Job::reserveBlocking($queues, $timeout); $job = \Resque\Job\Job::reserveBlocking($queues, $timeout);
if ($job) { if ($job) {
$this->logger->log(Psr\Log\LogLevel::INFO, 'Found job on {queue}', ['queue' => $job->queue]); $this->logger->log(\Psr\Log\LogLevel::INFO, 'Found job on {queue}', ['queue' => $job->queue]);
return $job; return $job;
} }
} else { } else {
foreach ($queues as $queue) { foreach ($queues as $queue) {
$this->logger->log(Psr\Log\LogLevel::INFO, 'Checking {queue} for jobs', ['queue' => $queue]); $this->logger->log(\Psr\Log\LogLevel::INFO, 'Checking {queue} for jobs', ['queue' => $queue]);
$job = Resque_Job::reserve($queue); $job = \Resque\Job\Job::reserve($queue);
if ($job) { if ($job) {
$this->logger->log(Psr\Log\LogLevel::INFO, 'Found job on {queue}', ['queue' => $job->queue]); $this->logger->log(\Psr\Log\LogLevel::INFO, 'Found job on {queue}', ['queue' => $job->queue]);
return $job; return $job;
} }
} }
@ -314,7 +328,7 @@ class Resque_Worker
{ {
$this->registerSigHandlers(); $this->registerSigHandlers();
$this->pruneDeadWorkers(); $this->pruneDeadWorkers();
Resque_Event::trigger('beforeFirstFork', $this); Event::trigger('beforeFirstFork', $this);
$this->registerWorker(); $this->registerWorker();
} }
@ -355,7 +369,7 @@ class Resque_Worker
pcntl_signal(SIGUSR1, [$this, 'killChild']); pcntl_signal(SIGUSR1, [$this, 'killChild']);
pcntl_signal(SIGUSR2, [$this, 'pauseProcessing']); pcntl_signal(SIGUSR2, [$this, 'pauseProcessing']);
pcntl_signal(SIGCONT, [$this, 'unPauseProcessing']); pcntl_signal(SIGCONT, [$this, 'unPauseProcessing']);
$this->logger->log(Psr\Log\LogLevel::DEBUG, 'Registered signals'); $this->logger->log(\Psr\Log\LogLevel::DEBUG, 'Registered signals');
} }
/** /**
@ -363,7 +377,7 @@ class Resque_Worker
*/ */
public function pauseProcessing() public function pauseProcessing()
{ {
$this->logger->log(Psr\Log\LogLevel::NOTICE, 'USR2 received; pausing job processing'); $this->logger->log(\Psr\Log\LogLevel::NOTICE, 'USR2 received; pausing job processing');
$this->paused = true; $this->paused = true;
} }
@ -373,7 +387,7 @@ class Resque_Worker
*/ */
public function unPauseProcessing() public function unPauseProcessing()
{ {
$this->logger->log(Psr\Log\LogLevel::NOTICE, 'CONT received; resuming job processing'); $this->logger->log(\Psr\Log\LogLevel::NOTICE, 'CONT received; resuming job processing');
$this->paused = false; $this->paused = false;
} }
@ -384,7 +398,7 @@ class Resque_Worker
public function shutdown() public function shutdown()
{ {
$this->shutdown = true; $this->shutdown = true;
$this->logger->log(Psr\Log\LogLevel::NOTICE, 'Shutting down'); $this->logger->log(\Psr\Log\LogLevel::NOTICE, 'Shutting down');
} }
/** /**
@ -404,17 +418,21 @@ class Resque_Worker
public function killChild() public function killChild()
{ {
if (!$this->child) { if (!$this->child) {
$this->logger->log(Psr\Log\LogLevel::DEBUG, 'No child to kill.'); $this->logger->log(\Psr\Log\LogLevel::DEBUG, 'No child to kill.');
return; return;
} }
$this->logger->log(Psr\Log\LogLevel::INFO, 'Killing child at {child}', ['child' => $this->child]); $this->logger->log(\Psr\Log\LogLevel::INFO, 'Killing child at {child}', ['child' => $this->child]);
if (exec('ps -o pid,state -p ' . $this->child, $output, $returnCode) && $returnCode != 1) { if (exec('ps -o pid,state -p ' . $this->child, $output, $returnCode) && $returnCode != 1) {
$this->logger->log(Psr\Log\LogLevel::DEBUG, 'Child {child} found, killing.', ['child' => $this->child]); $this->logger->log(\Psr\Log\LogLevel::DEBUG, 'Child {child} found, killing.', ['child' => $this->child]);
posix_kill($this->child, SIGKILL); posix_kill($this->child, SIGKILL);
$this->child = null; $this->child = null;
} else { } else {
$this->logger->log(Psr\Log\LogLevel::INFO, 'Child {child} not found, restarting.', ['child' => $this->child]); $this->logger->log(
\Psr\Log\LogLevel::INFO,
'Child {child} not found, restarting.',
['child' => $this->child],
);
$this->shutdown(); $this->shutdown();
} }
} }
@ -437,7 +455,11 @@ class Resque_Worker
if ($host != $this->hostname || in_array($pid, $workerPids) || $pid == getmypid()) { if ($host != $this->hostname || in_array($pid, $workerPids) || $pid == getmypid()) {
continue; continue;
} }
$this->logger->log(Psr\Log\LogLevel::INFO, 'Pruning dead worker: {worker}', ['worker' => (string)$worker]); $this->logger->log(
\Psr\Log\LogLevel::INFO,
'Pruning dead worker: {worker}',
['worker' => (string)$worker],
);
$worker->unregisterWorker(); $worker->unregisterWorker();
} }
} }
@ -475,28 +497,28 @@ class Resque_Worker
public function unregisterWorker() public function unregisterWorker()
{ {
if (is_object($this->currentJob)) { if (is_object($this->currentJob)) {
$this->currentJob->fail(new Resque_Job_DirtyExitException); $this->currentJob->fail(new \Resque\Job\DirtyExitException());
} }
$id = (string)$this; $id = (string)$this;
Resque::redis()->srem('workers', $id); Resque::redis()->srem('workers', $id);
Resque::redis()->del('worker:' . $id); Resque::redis()->del('worker:' . $id);
Resque::redis()->del('worker:' . $id . ':started'); Resque::redis()->del('worker:' . $id . ':started');
Resque_Stat::clear('processed:' . $id); Stat::clear('processed:' . $id);
Resque_Stat::clear('failed:' . $id); Stat::clear('failed:' . $id);
} }
/** /**
* Tell Redis which job we're currently working on. * Tell Redis which job we're currently working on.
* *
* @param Resque_Job $job Resque_Job instance containing the job we're working on. * @param \Resque\Job\Job $job \Resque\Job\Job instance containing the job we're working on.
* @throws Resque_RedisException * @throws Resque_RedisException
*/ */
public function workingOn(Resque_Job $job) public function workingOn(\Resque\Job\Job $job)
{ {
$job->worker = $this; $job->worker = $this;
$this->currentJob = $job; $this->currentJob = $job;
$job->updateStatus(Resque_Job_Status::STATUS_RUNNING); $job->updateStatus(\Resque\Job\Status::STATUS_RUNNING);
$data = json_encode([ $data = json_encode([
'queue' => $job->queue, 'queue' => $job->queue,
'run_at' => strftime('%a %b %d %H:%M:%S %Z %Y'), 'run_at' => strftime('%a %b %d %H:%M:%S %Z %Y'),
@ -512,8 +534,8 @@ class Resque_Worker
public function doneWorking() public function doneWorking()
{ {
$this->currentJob = null; $this->currentJob = null;
Resque_Stat::incr('processed'); Stat::incr('processed');
Resque_Stat::incr('processed:' . (string)$this); Stat::incr('processed:' . (string)$this);
Resque::redis()->del('worker:' . (string)$this); Resque::redis()->del('worker:' . (string)$this);
} }
@ -546,15 +568,15 @@ class Resque_Worker
*/ */
public function getStat($stat) public function getStat($stat)
{ {
return Resque_Stat::get($stat . ':' . $this); return \Resque\Stat::get($stat . ':' . $this);
} }
/** /**
* Inject the logging object into the worker * Inject the logging object into the worker
* *
* @param Psr\Log\LoggerInterface $logger * @param \Psr\Log\LoggerInterface $logger
*/ */
public function setLogger(Psr\Log\LoggerInterface $logger) public function setLogger(\Psr\Log\LoggerInterface $logger)
{ {
$this->logger = $logger; $this->logger = $logger;
} }

View File

@ -1,109 +0,0 @@
<?php
/**
* Resque_Job_Status tests.
*
* @package Resque/Tests
* @author Chris Boulton <chris@bigcommerce.com>
* @license http://www.opensource.org/licenses/mit-license.php
*/
class Resque_Tests_JobStatusTest extends Resque_Tests_TestCase
{
/**
* @var Resque_Worker
*/
protected $worker;
public function setUp(): void
{
parent::setUp();
// Register a worker to test with
$this->worker = new Resque_Worker('jobs');
$this->worker->setLogger(new Resque_Log());
}
public function testJobStatusCanBeTracked()
{
$token = Resque::enqueue('jobs', 'Test_Job', null, true);
$status = new Resque_Job_Status($token);
$this->assertTrue($status->isTracking());
}
public function testJobStatusIsReturnedViaJobInstance()
{
Resque::enqueue('jobs', 'Test_Job', null, true);
$job = Resque_Job::reserve('jobs');
$this->assertEquals(Resque_Job_Status::STATUS_WAITING, $job->getStatus());
}
public function testQueuedJobReturnsQueuedStatus()
{
$token = Resque::enqueue('jobs', 'Test_Job', null, true);
$status = new Resque_Job_Status($token);
$this->assertEquals(Resque_Job_Status::STATUS_WAITING, $status->get());
}
public function testRunningJobReturnsRunningStatus()
{
$token = Resque::enqueue('jobs', 'Failing_Job', null, true);
$job = $this->worker->reserve();
$this->worker->workingOn($job);
$status = new Resque_Job_Status($token);
$this->assertEquals(Resque_Job_Status::STATUS_RUNNING, $status->get());
}
public function testFailedJobReturnsFailedStatus()
{
$token = Resque::enqueue('jobs', 'Failing_Job', null, true);
$this->worker->work(0);
$status = new Resque_Job_Status($token);
$this->assertEquals(Resque_Job_Status::STATUS_FAILED, $status->get());
}
public function testCompletedJobReturnsCompletedStatus()
{
$token = Resque::enqueue('jobs', 'Test_Job', null, true);
$this->worker->work(0);
$status = new Resque_Job_Status($token);
$this->assertEquals(Resque_Job_Status::STATUS_COMPLETE, $status->get());
}
public function testStatusIsNotTrackedWhenToldNotTo()
{
$token = Resque::enqueue('jobs', 'Test_Job', null, false);
$status = new Resque_Job_Status($token);
$this->assertFalse($status->isTracking());
}
public function testStatusTrackingCanBeStopped()
{
Resque_Job_Status::create('test');
$status = new Resque_Job_Status('test');
$this->assertEquals(Resque_Job_Status::STATUS_WAITING, $status->get());
$status->stop();
$this->assertFalse($status->get());
}
public function testRecreatedJobWithTrackingStillTracksStatus()
{
$originalToken = Resque::enqueue('jobs', 'Test_Job', null, true);
$job = $this->worker->reserve();
// Mark this job as being worked on to ensure that the new status is still
// waiting.
$this->worker->workingOn($job);
// Now recreate it
$newToken = $job->recreate();
// Make sure we've got a new job returned
$this->assertNotEquals($originalToken, $newToken);
// Now check the status of the new job
$newJob = Resque_Job::reserve('jobs');
$this->assertEquals(Resque_Job_Status::STATUS_WAITING, $newJob->getStatus());
}
}

View File

@ -1,421 +0,0 @@
<?php
/**
* Resque_Job tests.
*
* @package Resque/Tests
* @author Chris Boulton <chris@bigcommerce.com>
* @license http://www.opensource.org/licenses/mit-license.php
*/
class Resque_Tests_JobTest extends Resque_Tests_TestCase
{
protected $worker;
public function setUp(): void
{
parent::setUp();
// Register a worker to test with
$this->worker = new Resque_Worker('jobs');
$this->worker->setLogger(new Resque_Log());
$this->worker->registerWorker();
}
public function testJobCanBeQueued()
{
$this->assertTrue((bool)Resque::enqueue('jobs', 'Test_Job'));
}
public function testQeueuedJobCanBeReserved()
{
Resque::enqueue('jobs', 'Test_Job');
$job = Resque_Job::reserve('jobs');
if ($job == false) {
$this->fail('Job could not be reserved.');
}
$this->assertEquals('jobs', $job->queue);
$this->assertEquals('Test_Job', $job->payload['class']);
}
/**
* @expectedException InvalidArgumentException
*/
public function testObjectArgumentsCannotBePassedToJob()
{
$this->expectException(InvalidArgumentException::class);
$args = new stdClass();
$args->test = 'somevalue';
Resque::enqueue('jobs', 'Test_Job', $args);
}
public function testQueuedJobReturnsExactSamePassedInArguments()
{
$args = [
'int' => 123,
'numArray' => [
1,
2,
],
'assocArray' => [
'key1' => 'value1',
'key2' => 'value2'
],
];
Resque::enqueue('jobs', 'Test_Job', $args);
$job = Resque_Job::reserve('jobs');
$this->assertEquals($args, $job->getArguments());
}
public function testAfterJobIsReservedItIsRemoved()
{
Resque::enqueue('jobs', 'Test_Job');
Resque_Job::reserve('jobs');
$this->assertFalse(Resque_Job::reserve('jobs'));
}
public function testRecreatedJobMatchesExistingJob()
{
$args = [
'int' => 123,
'numArray' => [
1,
2,
],
'assocArray' => [
'key1' => 'value1',
'key2' => 'value2'
],
];
Resque::enqueue('jobs', 'Test_Job', $args);
$job = Resque_Job::reserve('jobs');
// Now recreate it
$job->recreate();
$newJob = Resque_Job::reserve('jobs');
$this->assertEquals($job->payload['class'], $newJob->payload['class']);
$this->assertEquals($job->getArguments(), $newJob->getArguments());
}
public function testFailedJobExceptionsAreCaught()
{
$payload = [
'class' => 'Failing_Job',
'args' => null
];
$job = new Resque_Job('jobs', $payload);
$job->worker = $this->worker;
$this->worker->perform($job);
$this->assertEquals(1, Resque_Stat::get('failed'));
$this->assertEquals(1, Resque_Stat::get('failed:' . $this->worker));
}
/**
* @expectedException Resque_Exception
*/
public function testJobWithoutPerformMethodThrowsException()
{
$this->expectException(Resque_Exception::class);
Resque::enqueue('jobs', 'Test_Job_Without_Perform_Method');
$job = $this->worker->reserve();
$job->worker = $this->worker;
$job->perform();
}
/**
* @expectedException Resque_Exception
*/
public function testInvalidJobThrowsException()
{
$this->expectException(Resque_Exception::class);
Resque::enqueue('jobs', 'Invalid_Job');
$job = $this->worker->reserve();
$job->worker = $this->worker;
$job->perform();
}
public function testJobWithSetUpCallbackFiresSetUp()
{
$payload = [
'class' => 'Test_Job_With_SetUp',
'args' => [
'somevar',
'somevar2',
],
];
$job = new Resque_Job('jobs', $payload);
$job->perform();
$this->assertTrue(Test_Job_With_SetUp::$called);
}
public function testJobWithTearDownCallbackFiresTearDown()
{
$payload = [
'class' => 'Test_Job_With_TearDown',
'args' => [
'somevar',
'somevar2',
],
];
$job = new Resque_Job('jobs', $payload);
$job->perform();
$this->assertTrue(Test_Job_With_TearDown::$called);
}
public function testNamespaceNaming()
{
$fixture = [
['test' => 'more:than:one:with:', 'assertValue' => 'more:than:one:with:'],
['test' => 'more:than:one:without', 'assertValue' => 'more:than:one:without:'],
['test' => 'resque', 'assertValue' => 'resque:'],
['test' => 'resque:', 'assertValue' => 'resque:'],
];
foreach ($fixture as $item) {
Resque_Redis::prefix($item['test']);
$this->assertEquals(Resque_Redis::getPrefix(), $item['assertValue']);
}
}
public function testJobWithNamespace()
{
Resque_Redis::prefix('php');
$queue = 'jobs';
$payload = ['another_value'];
Resque::enqueue($queue, 'Test_Job_With_TearDown', $payload);
$this->assertEquals(Resque::queues(), ['jobs']);
$this->assertEquals(Resque::size($queue), 1);
Resque_Redis::prefix('resque');
$this->assertEquals(Resque::size($queue), 0);
}
public function testDequeueAll()
{
$queue = 'jobs';
Resque::enqueue($queue, 'Test_Job_Dequeue');
Resque::enqueue($queue, 'Test_Job_Dequeue');
$this->assertEquals(Resque::size($queue), 2);
$this->assertEquals(Resque::dequeue($queue), 2);
$this->assertEquals(Resque::size($queue), 0);
}
public function testDequeueMakeSureNotDeleteOthers()
{
$queue = 'jobs';
Resque::enqueue($queue, 'Test_Job_Dequeue');
Resque::enqueue($queue, 'Test_Job_Dequeue');
$other_queue = 'other_jobs';
Resque::enqueue($other_queue, 'Test_Job_Dequeue');
Resque::enqueue($other_queue, 'Test_Job_Dequeue');
$this->assertEquals(Resque::size($queue), 2);
$this->assertEquals(Resque::size($other_queue), 2);
$this->assertEquals(Resque::dequeue($queue), 2);
$this->assertEquals(Resque::size($queue), 0);
$this->assertEquals(Resque::size($other_queue), 2);
}
public function testDequeueSpecificItem()
{
$queue = 'jobs';
Resque::enqueue($queue, 'Test_Job_Dequeue1');
Resque::enqueue($queue, 'Test_Job_Dequeue2');
$this->assertEquals(Resque::size($queue), 2);
$test = ['Test_Job_Dequeue2'];
$this->assertEquals(Resque::dequeue($queue, $test), 1);
$this->assertEquals(Resque::size($queue), 1);
}
public function testDequeueSpecificMultipleItems()
{
$queue = 'jobs';
Resque::enqueue($queue, 'Test_Job_Dequeue1');
Resque::enqueue($queue, 'Test_Job_Dequeue2');
Resque::enqueue($queue, 'Test_Job_Dequeue3');
$this->assertEquals(Resque::size($queue), 3);
$test = ['Test_Job_Dequeue2', 'Test_Job_Dequeue3'];
$this->assertEquals(Resque::dequeue($queue, $test), 2);
$this->assertEquals(Resque::size($queue), 1);
}
public function testDequeueNonExistingItem()
{
$queue = 'jobs';
Resque::enqueue($queue, 'Test_Job_Dequeue1');
Resque::enqueue($queue, 'Test_Job_Dequeue2');
Resque::enqueue($queue, 'Test_Job_Dequeue3');
$this->assertEquals(Resque::size($queue), 3);
$test = ['Test_Job_Dequeue4'];
$this->assertEquals(Resque::dequeue($queue, $test), 0);
$this->assertEquals(Resque::size($queue), 3);
}
public function testDequeueNonExistingItem2()
{
$queue = 'jobs';
Resque::enqueue($queue, 'Test_Job_Dequeue1');
Resque::enqueue($queue, 'Test_Job_Dequeue2');
Resque::enqueue($queue, 'Test_Job_Dequeue3');
$this->assertEquals(Resque::size($queue), 3);
$test = ['Test_Job_Dequeue4', 'Test_Job_Dequeue1'];
$this->assertEquals(Resque::dequeue($queue, $test), 1);
$this->assertEquals(Resque::size($queue), 2);
}
public function testDequeueItemID()
{
$queue = 'jobs';
Resque::enqueue($queue, 'Test_Job_Dequeue');
$qid = Resque::enqueue($queue, 'Test_Job_Dequeue');
$this->assertEquals(Resque::size($queue), 2);
$test = ['Test_Job_Dequeue' => $qid];
$this->assertEquals(Resque::dequeue($queue, $test), 1);
$this->assertEquals(Resque::size($queue), 1);
}
public function testDequeueWrongItemID()
{
$queue = 'jobs';
Resque::enqueue($queue, 'Test_Job_Dequeue');
$qid = Resque::enqueue($queue, 'Test_Job_Dequeue');
$this->assertEquals(Resque::size($queue), 2);
#qid right but class name is wrong
$test = ['Test_Job_Dequeue1' => $qid];
$this->assertEquals(Resque::dequeue($queue, $test), 0);
$this->assertEquals(Resque::size($queue), 2);
}
public function testDequeueWrongItemID2()
{
$queue = 'jobs';
Resque::enqueue($queue, 'Test_Job_Dequeue');
Resque::enqueue($queue, 'Test_Job_Dequeue');
$this->assertEquals(Resque::size($queue), 2);
$test = ['Test_Job_Dequeue' => 'r4nD0mH4sh3dId'];
$this->assertEquals(Resque::dequeue($queue, $test), 0);
$this->assertEquals(Resque::size($queue), 2);
}
public function testDequeueItemWithArg()
{
$queue = 'jobs';
$arg = ['foo' => 1, 'bar' => 2];
Resque::enqueue($queue, 'Test_Job_Dequeue9');
Resque::enqueue($queue, 'Test_Job_Dequeue9', $arg);
$this->assertEquals(Resque::size($queue), 2);
$test = ['Test_Job_Dequeue9' => $arg];
$this->assertEquals(Resque::dequeue($queue, $test), 1);
#$this->assertEquals(Resque::size($queue), 1);
}
public function testDequeueSeveralItemsWithArgs()
{
// GIVEN
$queue = 'jobs';
$args = ['foo' => 1, 'bar' => 10];
$removeArgs = ['foo' => 1, 'bar' => 2];
Resque::enqueue($queue, 'Test_Job_Dequeue9', $args);
Resque::enqueue($queue, 'Test_Job_Dequeue9', $removeArgs);
Resque::enqueue($queue, 'Test_Job_Dequeue9', $removeArgs);
$this->assertEquals(Resque::size($queue), 3, "Failed to add 3 items.");
// WHEN
$test = ['Test_Job_Dequeue9' => $removeArgs];
$removedItems = Resque::dequeue($queue, $test);
// THEN
$this->assertEquals($removedItems, 2);
$this->assertEquals(Resque::size($queue), 1);
$item = Resque::pop($queue);
$this->assertIsArray($item['args']);
$this->assertEquals(10, $item['args'][0]['bar'], 'Wrong items were dequeued from queue!');
}
public function testDequeueItemWithUnorderedArg()
{
$queue = 'jobs';
$arg = ['foo' => 1, 'bar' => 2];
$arg2 = ['bar' => 2, 'foo' => 1];
Resque::enqueue($queue, 'Test_Job_Dequeue');
Resque::enqueue($queue, 'Test_Job_Dequeue', $arg);
$this->assertEquals(Resque::size($queue), 2);
$test = ['Test_Job_Dequeue' => $arg2];
$this->assertEquals(Resque::dequeue($queue, $test), 1);
$this->assertEquals(Resque::size($queue), 1);
}
public function testDequeueItemWithiWrongArg()
{
$queue = 'jobs';
$arg = ['foo' => 1, 'bar' => 2];
$arg2 = ['foo' => 2, 'bar' => 3];
Resque::enqueue($queue, 'Test_Job_Dequeue');
Resque::enqueue($queue, 'Test_Job_Dequeue', $arg);
$this->assertEquals(Resque::size($queue), 2);
$test = ['Test_Job_Dequeue' => $arg2];
$this->assertEquals(Resque::dequeue($queue, $test), 0);
$this->assertEquals(Resque::size($queue), 2);
}
public function testUseDefaultFactoryToGetJobInstance()
{
$payload = [
'class' => 'Some_Job_Class',
'args' => null
];
$job = new Resque_Job('jobs', $payload);
$instance = $job->getInstance();
$this->assertInstanceOf('Some_Job_Class', $instance);
}
public function testUseFactoryToGetJobInstance()
{
$payload = [
'class' => 'Some_Job_Class',
'args' => [[]]
];
$job = new Resque_Job('jobs', $payload);
$factory = new Some_Stub_Factory();
$job->setJobFactory($factory);
$instance = $job->getInstance();
$this->assertInstanceOf('Resque_JobInterface', $instance);
}
}
class Some_Job_Class implements Resque_JobInterface
{
/**
* @return bool
*/
public function perform()
{
return true;
}
}
class Some_Stub_Factory implements Resque_Job_FactoryInterface
{
/**
* @param $className
* @param array $args
* @param $queue
* @return Resque_JobInterface
*/
public function create($className, $args, $queue)
{
return new Some_Job_Class();
}
}

View File

@ -1,43 +1,45 @@
<?php <?php
namespace Resque\Test;
/** /**
* Resque_Event tests. * \Resque\Event tests.
* *
* @package Resque/Tests * @package Resque/Tests
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Tests_EventTest extends Resque_Tests_TestCase class EventTest extends TestCase
{ {
private $callbacksHit = []; private $callbacksHit = [];
private $worker; private $worker;
public function setUp(): void public function setUp(): void
{ {
Test_Job::$called = false; TestJob::$called = false;
// Register a worker to test with // Register a worker to test with
$this->worker = new Resque_Worker('jobs'); $this->worker = new \Resque\Worker('jobs');
$this->worker->setLogger(new Resque_Log()); $this->worker->setLogger(new \Resque\Log());
$this->worker->registerWorker(); $this->worker->registerWorker();
} }
public function tearDown(): void public function tearDown(): void
{ {
Resque_Event::clearListeners(); \Resque\Event::clearListeners();
$this->callbacksHit = []; $this->callbacksHit = [];
} }
public function getEventTestJob() public function getEventTestJob()
{ {
$payload = [ $payload = [
'class' => 'Test_Job', 'class' => '\Resque\Test\TestJob',
'args' => [ 'args' => [
['somevar'], ['somevar'],
], ],
]; ];
$job = new Resque_Job('jobs', $payload); $job = new \Resque\Job\Job('jobs', $payload);
$job->worker = $this->worker; $job->worker = $this->worker;
return $job; return $job;
} }
@ -58,7 +60,7 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
*/ */
public function testEventCallbacksFire($event, $callback) public function testEventCallbacksFire($event, $callback)
{ {
Resque_Event::listen($event, [$this, $callback]); \Resque\Event::listen($event, [$this, $callback]);
$job = $this->getEventTestJob(); $job = $this->getEventTestJob();
$this->worker->perform($job); $this->worker->perform($job);
@ -72,8 +74,8 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
$event = 'beforeFork'; $event = 'beforeFork';
$callback = 'beforeForkEventCallback'; $callback = 'beforeForkEventCallback';
Resque_Event::listen($event, [$this, $callback]); \Resque\Event::listen($event, [$this, $callback]);
Resque::enqueue('jobs', 'Test_Job', [ \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', [
'somevar' 'somevar'
]); ]);
$this->getEventTestJob(); $this->getEventTestJob();
@ -86,8 +88,8 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
$event = 'beforeEnqueue'; $event = 'beforeEnqueue';
$callback = 'beforeEnqueueEventCallback'; $callback = 'beforeEnqueueEventCallback';
Resque_Event::listen($event, [$this, $callback]); \Resque\Event::listen($event, [$this, $callback]);
Resque::enqueue('jobs', 'Test_Job', [ \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', [
'somevar' 'somevar'
]); ]);
$this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called'); $this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called');
@ -96,22 +98,22 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
public function testBeforePerformEventCanStopWork() public function testBeforePerformEventCanStopWork()
{ {
$callback = 'beforePerformEventDontPerformCallback'; $callback = 'beforePerformEventDontPerformCallback';
Resque_Event::listen('beforePerform', [$this, $callback]); \Resque\Event::listen('beforePerform', [$this, $callback]);
$job = $this->getEventTestJob(); $job = $this->getEventTestJob();
$this->assertFalse($job->perform()); $this->assertFalse($job->perform());
$this->assertContains($callback, $this->callbacksHit, $callback . ' callback was not called'); $this->assertContains($callback, $this->callbacksHit, $callback . ' callback was not called');
$this->assertFalse(Test_Job::$called, 'Job was still performed though Resque_Job_DontPerform was thrown'); $this->assertFalse(TestJob::$called, 'Job was still performed though Resque_Job_DontPerform was thrown');
} }
public function testBeforeEnqueueEventStopsJobCreation() public function testBeforeEnqueueEventStopsJobCreation()
{ {
$callback = 'beforeEnqueueEventDontCreateCallback'; $callback = 'beforeEnqueueEventDontCreateCallback';
Resque_Event::listen('beforeEnqueue', [$this, $callback]); \Resque\Event::listen('beforeEnqueue', [$this, $callback]);
Resque_Event::listen('afterEnqueue', [$this, 'afterEnqueueEventCallback']); \Resque\Event::listen('afterEnqueue', [$this, 'afterEnqueueEventCallback']);
$result = Resque::enqueue('test_job', 'TestClass'); $result = \Resque\Resque::enqueue('jobs', '\Resque\Test\TestClass');
$this->assertContains($callback, $this->callbacksHit, $callback . ' callback was not called'); $this->assertContains($callback, $this->callbacksHit, $callback . ' callback was not called');
$this->assertNotContains('afterEnqueueEventCallback', $this->callbacksHit, 'afterEnqueue was still called, even though it should not have been'); $this->assertNotContains('afterEnqueueEventCallback', $this->callbacksHit, 'afterEnqueue was still called, even though it should not have been');
$this->assertFalse($result); $this->assertFalse($result);
@ -122,8 +124,8 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
$callback = 'afterEnqueueEventCallback'; $callback = 'afterEnqueueEventCallback';
$event = 'afterEnqueue'; $event = 'afterEnqueue';
Resque_Event::listen($event, [$this, $callback]); \Resque\Event::listen($event, [$this, $callback]);
Resque::enqueue('jobs', 'Test_Job', [ \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', [
'somevar' 'somevar'
]); ]);
$this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called'); $this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called');
@ -134,8 +136,8 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
$callback = 'beforePerformEventCallback'; $callback = 'beforePerformEventCallback';
$event = 'beforePerform'; $event = 'beforePerform';
Resque_Event::listen($event, [$this, $callback]); \Resque\Event::listen($event, [$this, $callback]);
Resque_Event::stopListening($event, [$this, $callback]); \Resque\Event::stopListening($event, [$this, $callback]);
$job = $this->getEventTestJob(); $job = $this->getEventTestJob();
$this->worker->perform($job); $this->worker->perform($job);
@ -149,20 +151,20 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
public function beforePerformEventDontPerformCallback() public function beforePerformEventDontPerformCallback()
{ {
$this->callbacksHit[] = __FUNCTION__; $this->callbacksHit[] = __FUNCTION__;
throw new Resque_Job_DontPerform(); throw new \Resque\Job\DontPerform();
} }
public function beforeEnqueueEventDontCreateCallback() public function beforeEnqueueEventDontCreateCallback()
{ {
$this->callbacksHit[] = __FUNCTION__; $this->callbacksHit[] = __FUNCTION__;
throw new Resque_Job_DontCreate(); throw new \Resque\Job\DontCreate();
} }
public function assertValidEventCallback($function, $job) public function assertValidEventCallback($function, $job)
{ {
$this->callbacksHit[] = $function; $this->callbacksHit[] = $function;
if (!$job instanceof Resque_Job) { if (!$job instanceof \Resque\Job\Job) {
$this->fail('Callback job argument is not an instance of Resque_Job'); $this->fail('Callback job argument is not an instance of \Resque\Job\Job');
} }
$args = $job->getArguments(); $args = $job->getArguments();
$this->assertEquals($args[0], 'somevar'); $this->assertEquals($args[0], 'somevar');
@ -171,7 +173,7 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
public function afterEnqueueEventCallback($class, $args) public function afterEnqueueEventCallback($class, $args)
{ {
$this->callbacksHit[] = __FUNCTION__; $this->callbacksHit[] = __FUNCTION__;
$this->assertEquals('Test_Job', $class); $this->assertEquals('\Resque\Test\TestJob', $class);
$this->assertEquals([ $this->assertEquals([
'somevar', 'somevar',
], $args); ], $args);

View File

@ -0,0 +1,110 @@
<?php
namespace Resque\Test;
/**
* \Resque\Job\Status tests.
*
* @package Resque/Tests
* @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php
*/
class JobStatusTest extends TestCase
{
/**
* @var \Resque\Worker
*/
protected $worker;
public function setUp(): void
{
parent::setUp();
// Register a worker to test with
$this->worker = new \Resque\Worker('jobs');
$this->worker->setLogger(new \Resque\Log());
}
public function testJobStatusCanBeTracked()
{
$token = \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', null, true);
$status = new \Resque\Job\Status($token);
$this->assertTrue($status->isTracking());
}
public function testJobStatusIsReturnedViaJobInstance()
{
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', null, true);
$job = \Resque\Job\Job::reserve('jobs');
$this->assertEquals(\Resque\Job\Status::STATUS_WAITING, $job->getStatus());
}
public function testQueuedJobReturnsQueuedStatus()
{
$token = \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', null, true);
$status = new \Resque\Job\Status($token);
$this->assertEquals(\Resque\Job\Status::STATUS_WAITING, $status->get());
}
public function testRunningJobReturnsRunningStatus()
{
$token = \Resque\Resque::enqueue('jobs', '\Resque\Test\FailingJob', null, true);
$job = $this->worker->reserve();
$this->worker->workingOn($job);
$status = new \Resque\Job\Status($token);
$this->assertEquals(\Resque\Job\Status::STATUS_RUNNING, $status->get());
}
public function testFailedJobReturnsFailedStatus()
{
$token = \Resque\Resque::enqueue('jobs', '\Resque\Test\FailingJob', null, true);
$this->worker->work(0);
$status = new \Resque\Job\Status($token);
$this->assertEquals(\Resque\Job\Status::STATUS_FAILED, $status->get());
}
public function testCompletedJobReturnsCompletedStatus()
{
$token = \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', null, true);
$this->worker->work(0);
$status = new \Resque\Job\Status($token);
$this->assertEquals(\Resque\Job\Status::STATUS_COMPLETE, $status->get());
}
public function testStatusIsNotTrackedWhenToldNotTo()
{
$token = \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', null, false);
$status = new \Resque\Job\Status($token);
$this->assertFalse($status->isTracking());
}
public function testStatusTrackingCanBeStopped()
{
\Resque\Job\Status::create('test');
$status = new \Resque\Job\Status('test');
$this->assertEquals(\Resque\Job\Status::STATUS_WAITING, $status->get());
$status->stop();
$this->assertFalse($status->get());
}
public function testRecreatedJobWithTrackingStillTracksStatus()
{
$originalToken = \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', null, true);
$job = $this->worker->reserve();
// Mark this job as being worked on to ensure that the new status is still
// waiting.
$this->worker->workingOn($job);
// Now recreate it
$newToken = $job->recreate();
// Make sure we've got a new job returned
$this->assertNotEquals($originalToken, $newToken);
// Now check the status of the new job
$newJob = \Resque\Job\Job::reserve('jobs');
$this->assertEquals(\Resque\Job\Status::STATUS_WAITING, $newJob->getStatus());
}
}

View File

@ -0,0 +1,423 @@
<?php
namespace Resque\Test;
/**
* ResqueJob tests.
*
* @package Resque/Tests
* @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php
*/
class JobTest extends TestCase
{
protected $worker;
public function setUp(): void
{
parent::setUp();
// Register a worker to test with
$this->worker = new \Resque\Worker('jobs');
$this->worker->setLogger(new \Resque\Log());
$this->worker->registerWorker();
}
public function testJobCanBeQueued()
{
$this->assertTrue((bool)\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob'));
}
public function testQeueuedJobCanBeReserved()
{
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
$job = \Resque\Job\Job::reserve('jobs');
if ($job == false) {
$this->fail('Job could not be reserved.');
}
$this->assertEquals('jobs', $job->queue);
$this->assertEquals('\Resque\Test\TestJob', $job->payload['class']);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testObjectArgumentsCannotBePassedToJob()
{
$this->expectException(\InvalidArgumentException::class);
$args = new \stdClass();
$args->test = 'somevalue';
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', $args);
}
public function testQueuedJobReturnsExactSamePassedInArguments()
{
$args = [
'int' => 123,
'numArray' => [
1,
2,
],
'assocArray' => [
'key1' => 'value1',
'key2' => 'value2'
],
];
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', $args);
$job = \Resque\Job\Job::reserve('jobs');
$this->assertEquals($args, $job->getArguments());
}
public function testAfterJobIsReservedItIsRemoved()
{
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
\Resque\Job\Job::reserve('jobs');
$this->assertFalse(\Resque\Job\Job::reserve('jobs'));
}
public function testRecreatedJobMatchesExistingJob()
{
$args = [
'int' => 123,
'numArray' => [
1,
2,
],
'assocArray' => [
'key1' => 'value1',
'key2' => 'value2'
],
];
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', $args);
$job = \Resque\Job\Job::reserve('jobs');
// Now recreate it
$job->recreate();
$newJob = \Resque\Job\Job::reserve('jobs');
$this->assertEquals($job->payload['class'], $newJob->payload['class']);
$this->assertEquals($job->getArguments(), $newJob->getArguments());
}
public function testFailedJobExceptionsAreCaught()
{
$payload = [
'class' => '\Resque\Test\FailingJob',
'args' => null
];
$job = new \Resque\Job\Job('jobs', $payload);
$job->worker = $this->worker;
$this->worker->perform($job);
$this->assertEquals(1, \Resque\Stat::get('failed'));
$this->assertEquals(1, \Resque\Stat::get('failed:' . $this->worker));
}
/**
* @expectedException \Resque\Exception
*/
public function testJobWithoutPerformMethodThrowsException()
{
$this->expectException(\Resque\Exception::class);
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob_Without_Perform_Method');
$job = $this->worker->reserve();
$job->worker = $this->worker;
$job->perform();
}
/**
* @expectedException \Resque\Exception
*/
public function testInvalidJobThrowsException()
{
$this->expectException(\Resque\Exception::class);
\Resque\Resque::enqueue('jobs', '\Resque\Test\InvalidJob');
$job = $this->worker->reserve();
$job->worker = $this->worker;
$job->perform();
}
public function testJobWithSetUpCallbackFiresSetUp()
{
$payload = [
'class' => '\Resque\Test\TestJobWithSetUp',
'args' => [
'somevar',
'somevar2',
],
];
$job = new \Resque\Job\Job('jobs', $payload);
$job->perform();
$this->assertTrue(TestJobWithSetUp::$called);
}
public function testJobWithTearDownCallbackFiresTearDown()
{
$payload = [
'class' => '\Resque\Test\TestJobWithTearDown',
'args' => [
'somevar',
'somevar2',
],
];
$job = new \Resque\Job\Job('jobs', $payload);
$job->perform();
$this->assertTrue(TestJobWithTearDown::$called);
}
public function testNamespaceNaming()
{
$fixture = [
['test' => 'more:than:one:with:', 'assertValue' => 'more:than:one:with:'],
['test' => 'more:than:one:without', 'assertValue' => 'more:than:one:without:'],
['test' => 'resque', 'assertValue' => 'resque:'],
['test' => 'resque:', 'assertValue' => 'resque:'],
];
foreach ($fixture as $item) {
\Resque\Redis::prefix($item['test']);
$this->assertEquals(\Resque\Redis::getPrefix(), $item['assertValue']);
}
}
public function testJobWithNamespace()
{
\Resque\Redis::prefix('php');
$queue = 'jobs';
$payload = ['another_value'];
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobWithTearDown', $payload);
$this->assertEquals(\Resque\Resque::queues(), ['jobs']);
$this->assertEquals(\Resque\Resque::size($queue), 1);
\Resque\Redis::prefix('resque');
$this->assertEquals(\Resque\Resque::size($queue), 0);
}
public function testDequeueAll()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue');
$this->assertEquals(\Resque\Resque::size($queue), 2);
$this->assertEquals(\Resque\Resque::dequeue($queue), 2);
$this->assertEquals(\Resque\Resque::size($queue), 0);
}
public function testDequeueMakeSureNotDeleteOthers()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue');
$other_queue = 'other_jobs';
\Resque\Resque::enqueue($other_queue, '\Resque\Test\TestJobDequeue');
\Resque\Resque::enqueue($other_queue, '\Resque\Test\TestJobDequeue');
$this->assertEquals(\Resque\Resque::size($queue), 2);
$this->assertEquals(\Resque\Resque::size($other_queue), 2);
$this->assertEquals(\Resque\Resque::dequeue($queue), 2);
$this->assertEquals(\Resque\Resque::size($queue), 0);
$this->assertEquals(\Resque\Resque::size($other_queue), 2);
}
public function testDequeueSpecificItem()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue1');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue2');
$this->assertEquals(\Resque\Resque::size($queue), 2);
$test = ['\Resque\Test\TestJobDequeue2'];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 1);
$this->assertEquals(\Resque\Resque::size($queue), 1);
}
public function testDequeueSpecificMultipleItems()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue1');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue2');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue3');
$this->assertEquals(\Resque\Resque::size($queue), 3);
$test = ['\Resque\Test\TestJob_Dequeue2', '\Resque\Test\TestJob_Dequeue3'];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 2);
$this->assertEquals(\Resque\Resque::size($queue), 1);
}
public function testDequeueNonExistingItem()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue1');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue2');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue3');
$this->assertEquals(\Resque\Resque::size($queue), 3);
$test = ['\Resque\Test\TestJob_Dequeue4'];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 0);
$this->assertEquals(\Resque\Resque::size($queue), 3);
}
public function testDequeueNonExistingItem2()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue1');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue2');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue3');
$this->assertEquals(\Resque\Resque::size($queue), 3);
$test = ['\Resque\Test\TestJob_Dequeue4', '\Resque\Test\TestJob_Dequeue1'];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 1);
$this->assertEquals(\Resque\Resque::size($queue), 2);
}
public function testDequeueItemID()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue');
$qid = \Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue');
$this->assertEquals(\Resque\Resque::size($queue), 2);
$test = ['\Resque\Test\TestJob_Dequeue' => $qid];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 1);
$this->assertEquals(\Resque\Resque::size($queue), 1);
}
public function testDequeueWrongItemID()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue');
$qid = \Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue');
$this->assertEquals(\Resque\Resque::size($queue), 2);
#qid right but class name is wrong
$test = ['\Resque\Test\TestJob_Dequeue1' => $qid];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 0);
$this->assertEquals(\Resque\Resque::size($queue), 2);
}
public function testDequeueWrongItemID2()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue');
$this->assertEquals(\Resque\Resque::size($queue), 2);
$test = ['\Resque\Test\TestJob_Dequeue' => 'r4nD0mH4sh3dId'];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 0);
$this->assertEquals(\Resque\Resque::size($queue), 2);
}
public function testDequeueItemWithArg()
{
$queue = 'jobs';
$arg = ['foo' => 1, 'bar' => 2];
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue9');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue9', $arg);
$this->assertEquals(\Resque\Resque::size($queue), 2);
$test = ['\Resque\Test\TestJobDequeue9' => $arg];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 1);
#$this->assertEquals(\Resque\Resque::size($queue), 1);
}
public function testDequeueSeveralItemsWithArgs()
{
// GIVEN
$queue = 'jobs';
$args = ['foo' => 1, 'bar' => 10];
$removeArgs = ['foo' => 1, 'bar' => 2];
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue9', $args);
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue9', $removeArgs);
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue9', $removeArgs);
$this->assertEquals(\Resque\Resque::size($queue), 3, "Failed to add 3 items.");
// WHEN
$test = ['\Resque\Test\TestJobDequeue9' => $removeArgs];
$removedItems = \Resque\Resque::dequeue($queue, $test);
// THEN
$this->assertEquals($removedItems, 2);
$this->assertEquals(\Resque\Resque::size($queue), 1);
$item = \Resque\Resque::pop($queue);
$this->assertIsArray($item['args']);
$this->assertEquals(10, $item['args'][0]['bar'], 'Wrong items were dequeued from queue!');
}
public function testDequeueItemWithUnorderedArg()
{
$queue = 'jobs';
$arg = ['foo' => 1, 'bar' => 2];
$arg2 = ['bar' => 2, 'foo' => 1];
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue', $arg);
$this->assertEquals(\Resque\Resque::size($queue), 2);
$test = ['\Resque\Test\TestJobDequeue' => $arg2];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 1);
$this->assertEquals(\Resque\Resque::size($queue), 1);
}
public function testDequeueItemWithiWrongArg()
{
$queue = 'jobs';
$arg = ['foo' => 1, 'bar' => 2];
$arg2 = ['foo' => 2, 'bar' => 3];
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue', $arg);
$this->assertEquals(\Resque\Resque::size($queue), 2);
$test = ['\Resque\Test\TestJobDequeue' => $arg2];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 0);
$this->assertEquals(\Resque\Resque::size($queue), 2);
}
public function testUseDefaultFactoryToGetJobInstance()
{
$payload = [
'class' => '\Resque\Test\SomeJobClass',
'args' => null
];
$job = new \Resque\Job\Job('jobs', $payload);
$instance = $job->getInstance();
$this->assertInstanceOf('\Resque\Test\SomeJobClass', $instance);
}
public function testUseFactoryToGetJobInstance()
{
$payload = [
'class' => 'SomeJobClass',
'args' => [[]]
];
$job = new \Resque\Job\Job('jobs', $payload);
$factory = new Some_Stub_Factory();
$job->setJobFactory($factory);
$instance = $job->getInstance();
$this->assertInstanceOf('\Resque\Job\JobInterface', $instance);
}
}
class SomeJobClass implements \Resque\Job\JobInterface
{
/**
* @return bool
*/
public function perform()
{
return true;
}
}
class Some_Stub_Factory implements \Resque\Job\FactoryInterface
{
/**
* @param $className
* @param array $args
* @param $queue
* @return \Resque\Job\JobInterface
*/
public function create($className, $args, $queue)
{
return new SomeJobClass();
}
}

View File

@ -1,18 +1,20 @@
<?php <?php
namespace Resque\Test;
/** /**
* Resque_Log tests. * \Resque\Log tests.
* *
* @package Resque/Tests * @package Resque/Tests
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Tests_LogTest extends Resque_Tests_TestCase class LogTest extends TestCase
{ {
public function testLogInterpolate() public function testLogInterpolate()
{ {
$logger = new Resque_Log(); $logger = new \Resque\Log();
$actual = $logger->interpolate('string {replace}', ['replace' => 'value']); $actual = $logger->interpolate('string {replace}', ['replace' => 'value']);
$expected = 'string value'; $expected = 'string value';
@ -21,7 +23,7 @@ class Resque_Tests_LogTest extends Resque_Tests_TestCase
public function testLogInterpolateMutiple() public function testLogInterpolateMutiple()
{ {
$logger = new Resque_Log(); $logger = new \Resque\Log();
$actual = $logger->interpolate( $actual = $logger->interpolate(
'string {replace1} {replace2}', 'string {replace1} {replace2}',
['replace1' => 'value1', 'replace2' => 'value2'] ['replace1' => 'value1', 'replace2' => 'value2']

View File

@ -1,14 +1,16 @@
<?php <?php
namespace Resque\Test;
/** /**
* Resque_Event tests. * Resque_Event tests.
* *
* @package Resque/Tests * @package Resque/Tests
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Tests_RedisTest extends Resque_Tests_TestCase class RedisTest extends TestCase
{ {
public function testRedisGetSet() public function testRedisGetSet()
{ {
@ -28,14 +30,14 @@ class Resque_Tests_RedisTest extends Resque_Tests_TestCase
// Input , Expected output // Input , Expected output
['', [ ['', [
'localhost', 'localhost',
Resque_Redis::DEFAULT_PORT, \Resque\Redis::DEFAULT_PORT,
false, false,
false, false, false, false,
[], [],
]], ]],
['localhost', [ ['localhost', [
'localhost', 'localhost',
Resque_Redis::DEFAULT_PORT, \Resque\Redis::DEFAULT_PORT,
false, false,
false, false, false, false,
[], [],
@ -56,14 +58,14 @@ class Resque_Tests_RedisTest extends Resque_Tests_TestCase
]], ]],
['redis://foobar', [ ['redis://foobar', [
'foobar', 'foobar',
Resque_Redis::DEFAULT_PORT, \Resque\Redis::DEFAULT_PORT,
false, false,
false, false, false, false,
[], [],
]], ]],
['redis://foobar/', [ ['redis://foobar/', [
'foobar', 'foobar',
Resque_Redis::DEFAULT_PORT, \Resque\Redis::DEFAULT_PORT,
false, false,
false, false, false, false,
[], [],
@ -175,20 +177,20 @@ class Resque_Tests_RedisTest extends Resque_Tests_TestCase
*/ */
public function testParsingValidDsnString($dsn, $expected) public function testParsingValidDsnString($dsn, $expected)
{ {
$result = Resque_Redis::parseDsn($dsn); $result = \Resque\Redis::parseDsn($dsn);
$this->assertEquals($expected, $result); $this->assertEquals($expected, $result);
} }
/** /**
* @dataProvider bogusDsnStringProvider * @dataProvider bogusDsnStringProvider
* *
* @expectedException InvalidArgumentException * @expectedException \InvalidArgumentException
* *
* @param $dsn * @param $dsn
*/ */
public function testParsingBogusDsnStringThrowsException($dsn) public function testParsingBogusDsnStringThrowsException($dsn)
{ {
$this->expectException(InvalidArgumentException::class); $this->expectException(\InvalidArgumentException::class);
Resque_Redis::parseDsn($dsn); \Resque\Redis::parseDsn($dsn);
} }
} }

View File

@ -1,51 +1,53 @@
<?php <?php
namespace Resque\Test;
/** /**
* Resque_Stat tests. * Resque\Stat tests.
* *
* @package Resque/Tests * @package Resque/Tests
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Tests_StatTest extends Resque_Tests_TestCase class StatTest extends TestCase
{ {
public function testStatCanBeIncremented() public function testStatCanBeIncremented()
{ {
Resque_Stat::incr('test_incr'); \Resque\Stat::incr('test_incr');
Resque_Stat::incr('test_incr'); \Resque\Stat::incr('test_incr');
$this->assertEquals(2, $this->redis->get('resque:stat:test_incr')); $this->assertEquals(2, $this->redis->get('resque:stat:test_incr'));
} }
public function testStatCanBeIncrementedByX() public function testStatCanBeIncrementedByX()
{ {
Resque_Stat::incr('test_incrX', 10); \Resque\Stat::incr('test_incrX', 10);
Resque_Stat::incr('test_incrX', 11); \Resque\Stat::incr('test_incrX', 11);
$this->assertEquals(21, $this->redis->get('resque:stat:test_incrX')); $this->assertEquals(21, $this->redis->get('resque:stat:test_incrX'));
} }
public function testStatCanBeDecremented() public function testStatCanBeDecremented()
{ {
Resque_Stat::incr('test_decr', 22); \Resque\Stat::incr('test_decr', 22);
Resque_Stat::decr('test_decr'); \Resque\Stat::decr('test_decr');
$this->assertEquals(21, $this->redis->get('resque:stat:test_decr')); $this->assertEquals(21, $this->redis->get('resque:stat:test_decr'));
} }
public function testStatCanBeDecrementedByX() public function testStatCanBeDecrementedByX()
{ {
Resque_Stat::incr('test_decrX', 22); \Resque\Stat::incr('test_decrX', 22);
Resque_Stat::decr('test_decrX', 11); \Resque\Stat::decr('test_decrX', 11);
$this->assertEquals(11, $this->redis->get('resque:stat:test_decrX')); $this->assertEquals(11, $this->redis->get('resque:stat:test_decrX'));
} }
public function testGetStatByName() public function testGetStatByName()
{ {
Resque_Stat::incr('test_get', 100); \Resque\Stat::incr('test_get', 100);
$this->assertEquals(100, Resque_Stat::get('test_get')); $this->assertEquals(100, \Resque\Stat::get('test_get'));
} }
public function testGetUnknownStatReturns0() public function testGetUnknownStatReturns0()
{ {
$this->assertEquals(0, Resque_Stat::get('test_get_unknown')); $this->assertEquals(0, \Resque\Stat::get('test_get_unknown'));
} }
} }

View File

@ -1,14 +1,15 @@
<?php <?php
namespace Resque\Test;
/** /**
* Resque test case class. Contains setup and teardown methods. * Resque test case class. Contains setup and teardown methods.
* *
* @package Resque/Tests * @package Resque/Tests
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class TestCase extends \PHPUnit\Framework\TestCase
class Resque_Tests_TestCase extends PHPUnit\Framework\TestCase
{ {
protected $resque; protected $resque;
protected $redis; protected $redis;
@ -23,8 +24,8 @@ class Resque_Tests_TestCase extends PHPUnit\Framework\TestCase
// Setup redis connection for testing. // Setup redis connection for testing.
global $redisTestServer; global $redisTestServer;
$this->redis = new Credis_Client($redisTestServer, '6379'); $this->redis = new \Credis_Client($redisTestServer, '6379');
Resque::setBackend($redisTestServer); \Resque\Resque::setBackend($redisTestServer);
$this->redis->flushAll(); $this->redis->flushAll();
} }
} }

View File

@ -1,19 +1,21 @@
<?php <?php
namespace Resque\Test;
/** /**
* Resque_Worker tests. * \Resque\Worker tests.
* *
* @package Resque/Tests * @package Resque/Tests
* @author Chris Boulton <chris@bigcommerce.com> * @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php * @license http://www.opensource.org/licenses/mit-license.php
*/ */
class Resque_Tests_WorkerTest extends Resque_Tests_TestCase class WorkerTest extends TestCase
{ {
public function testWorkerRegistersInList() public function testWorkerRegistersInList()
{ {
$worker = new Resque_Worker('*'); $worker = new \Resque\Worker('*');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->registerWorker(); $worker->registerWorker();
// Make sure the worker is in the list // Make sure the worker is in the list
@ -25,76 +27,76 @@ class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
$num = 3; $num = 3;
// Register a few workers // Register a few workers
for ($i = 0; $i < $num; ++$i) { for ($i = 0; $i < $num; ++$i) {
$worker = new Resque_Worker('queue_' . $i); $worker = new \Resque\Worker('queue_' . $i);
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->registerWorker(); $worker->registerWorker();
} }
// Now try to get them // Now try to get them
$this->assertEquals($num, count(Resque_Worker::all())); $this->assertEquals($num, count(\Resque\Worker::all()));
} }
public function testGetWorkerById() public function testGetWorkerById()
{ {
$worker = new Resque_Worker('*'); $worker = new \Resque\Worker('*');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->registerWorker(); $worker->registerWorker();
$newWorker = Resque_Worker::find((string)$worker); $newWorker = \Resque\Worker::find((string)$worker);
$this->assertEquals((string)$worker, (string)$newWorker); $this->assertEquals((string)$worker, (string)$newWorker);
} }
public function testInvalidWorkerDoesNotExist() public function testInvalidWorkerDoesNotExist()
{ {
$this->assertFalse(Resque_Worker::exists('blah')); $this->assertFalse(\Resque\Worker::exists('blah'));
} }
public function testWorkerCanUnregister() public function testWorkerCanUnregister()
{ {
$worker = new Resque_Worker('*'); $worker = new \Resque\Worker('*');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->registerWorker(); $worker->registerWorker();
$worker->unregisterWorker(); $worker->unregisterWorker();
$this->assertFalse(Resque_Worker::exists((string)$worker)); $this->assertFalse(\Resque\Worker::exists((string)$worker));
$this->assertEquals([], Resque_Worker::all()); $this->assertEquals([], \Resque\Worker::all());
$this->assertEquals([], $this->redis->smembers('resque:workers')); $this->assertEquals([], $this->redis->smembers('resque:workers'));
} }
public function testPausedWorkerDoesNotPickUpJobs() public function testPausedWorkerDoesNotPickUpJobs()
{ {
$worker = new Resque_Worker('*'); $worker = new \Resque\Worker('*');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->pauseProcessing(); $worker->pauseProcessing();
Resque::enqueue('jobs', 'Test_Job'); \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
$worker->work(0); $worker->work(0);
$worker->work(0); $worker->work(0);
$this->assertEquals(0, Resque_Stat::get('processed')); $this->assertEquals(0, \Resque\Stat::get('processed'));
} }
public function testResumedWorkerPicksUpJobs() public function testResumedWorkerPicksUpJobs()
{ {
$worker = new Resque_Worker('*'); $worker = new \Resque\Worker('*');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->pauseProcessing(); $worker->pauseProcessing();
Resque::enqueue('jobs', 'Test_Job'); \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
$worker->work(0); $worker->work(0);
$this->assertEquals(0, Resque_Stat::get('processed')); $this->assertEquals(0, \Resque\Stat::get('processed'));
$worker->unPauseProcessing(); $worker->unPauseProcessing();
$worker->work(0); $worker->work(0);
$this->assertEquals(1, Resque_Stat::get('processed')); $this->assertEquals(1, \Resque\Stat::get('processed'));
} }
public function testWorkerCanWorkOverMultipleQueues() public function testWorkerCanWorkOverMultipleQueues()
{ {
$worker = new Resque_Worker([ $worker = new \Resque\Worker([
'queue1', 'queue1',
'queue2' 'queue2'
]); ]);
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->registerWorker(); $worker->registerWorker();
Resque::enqueue('queue1', 'Test_Job_1'); \Resque\Resque::enqueue('queue1', '\Resque\Test\TestJob_1');
Resque::enqueue('queue2', 'Test_Job_2'); \Resque\Resque::enqueue('queue2', '\Resque\Test\TestJob_2');
$job = $worker->reserve(); $job = $worker->reserve();
$this->assertEquals('queue1', $job->queue); $this->assertEquals('queue1', $job->queue);
@ -105,18 +107,18 @@ class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
public function testWorkerWorksQueuesInSpecifiedOrder() public function testWorkerWorksQueuesInSpecifiedOrder()
{ {
$worker = new Resque_Worker([ $worker = new \Resque\Worker([
'high', 'high',
'medium', 'medium',
'low' 'low'
]); ]);
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->registerWorker(); $worker->registerWorker();
// Queue the jobs in a different order // Queue the jobs in a different order
Resque::enqueue('low', 'Test_Job_1'); \Resque\Resque::enqueue('low', '\Resque\Test\TestJob_1');
Resque::enqueue('high', 'Test_Job_2'); \Resque\Resque::enqueue('high', '\Resque\Test\TestJob_2');
Resque::enqueue('medium', 'Test_Job_3'); \Resque\Resque::enqueue('medium', '\Resque\Test\TestJob_3');
// Now check we get the jobs back in the right order // Now check we get the jobs back in the right order
$job = $worker->reserve(); $job = $worker->reserve();
@ -131,12 +133,12 @@ class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
public function testWildcardQueueWorkerWorksAllQueues() public function testWildcardQueueWorkerWorksAllQueues()
{ {
$worker = new Resque_Worker('*'); $worker = new \Resque\Worker('*');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->registerWorker(); $worker->registerWorker();
Resque::enqueue('queue1', 'Test_Job_1'); \Resque\Resque::enqueue('queue1', '\Resque\Test\TestJob_1');
Resque::enqueue('queue2', 'Test_Job_2'); \Resque\Resque::enqueue('queue2', '\Resque\Test\TestJob_2');
$job = $worker->reserve(); $job = $worker->reserve();
$this->assertEquals('queue1', $job->queue); $this->assertEquals('queue1', $job->queue);
@ -147,19 +149,19 @@ class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
public function testWorkerDoesNotWorkOnUnknownQueues() public function testWorkerDoesNotWorkOnUnknownQueues()
{ {
$worker = new Resque_Worker('queue1'); $worker = new \Resque\Worker('queue1');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->registerWorker(); $worker->registerWorker();
Resque::enqueue('queue2', 'Test_Job'); \Resque\Resque::enqueue('queue2', '\Resque\Test\TestJob');
$this->assertFalse($worker->reserve()); $this->assertFalse($worker->reserve());
} }
public function testWorkerClearsItsStatusWhenNotWorking() public function testWorkerClearsItsStatusWhenNotWorking()
{ {
Resque::enqueue('jobs', 'Test_Job'); \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
$worker = new Resque_Worker('jobs'); $worker = new \Resque\Worker('jobs');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$job = $worker->reserve(); $job = $worker->reserve();
$worker->workingOn($job); $worker->workingOn($job);
$worker->doneWorking(); $worker->doneWorking();
@ -168,14 +170,14 @@ class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
public function testWorkerRecordsWhatItIsWorkingOn() public function testWorkerRecordsWhatItIsWorkingOn()
{ {
$worker = new Resque_Worker('jobs'); $worker = new \Resque\Worker('jobs');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->registerWorker(); $worker->registerWorker();
$payload = [ $payload = [
'class' => 'Test_Job' 'class' => '\Resque\Test\TestJob'
]; ];
$job = new Resque_Job('jobs', $payload); $job = new \Resque\Job\Job('jobs', $payload);
$worker->workingOn($job); $worker->workingOn($job);
$job = $worker->job(); $job = $worker->job();
@ -188,11 +190,11 @@ class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
public function testWorkerErasesItsStatsWhenShutdown() public function testWorkerErasesItsStatsWhenShutdown()
{ {
Resque::enqueue('jobs', 'Test_Job'); \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
Resque::enqueue('jobs', 'Invalid_Job'); \Resque\Resque::enqueue('jobs', '\Resque\Test\InvalidJob');
$worker = new Resque_Worker('jobs'); $worker = new \Resque\Worker('jobs');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->work(0); $worker->work(0);
$worker->work(0); $worker->work(0);
@ -203,84 +205,84 @@ class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
public function testWorkerCleansUpDeadWorkersOnStartup() public function testWorkerCleansUpDeadWorkersOnStartup()
{ {
// Register a good worker // Register a good worker
$goodWorker = new Resque_Worker('jobs'); $goodWorker = new \Resque\Worker('jobs');
$goodWorker->setLogger(new Resque_Log()); $goodWorker->setLogger(new \Resque\Log());
$goodWorker->registerWorker(); $goodWorker->registerWorker();
$workerId = explode(':', $goodWorker); $workerId = explode(':', $goodWorker);
// Register some bad workers // Register some bad workers
$worker = new Resque_Worker('jobs'); $worker = new \Resque\Worker('jobs');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->setId($workerId[0] . ':1:jobs'); $worker->setId($workerId[0] . ':1:jobs');
$worker->registerWorker(); $worker->registerWorker();
$worker = new Resque_Worker(['high', 'low']); $worker = new \Resque\Worker(['high', 'low']);
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->setId($workerId[0] . ':2:high,low'); $worker->setId($workerId[0] . ':2:high,low');
$worker->registerWorker(); $worker->registerWorker();
$this->assertEquals(3, count(Resque_Worker::all())); $this->assertEquals(3, count(\Resque\Worker::all()));
$goodWorker->pruneDeadWorkers(); $goodWorker->pruneDeadWorkers();
// There should only be $goodWorker left now // There should only be $goodWorker left now
$this->assertEquals(1, count(Resque_Worker::all())); $this->assertEquals(1, count(\Resque\Worker::all()));
} }
public function testDeadWorkerCleanUpDoesNotCleanUnknownWorkers() public function testDeadWorkerCleanUpDoesNotCleanUnknownWorkers()
{ {
// Register a bad worker on this machine // Register a bad worker on this machine
$worker = new Resque_Worker('jobs'); $worker = new \Resque\Worker('jobs');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$workerId = explode(':', $worker); $workerId = explode(':', $worker);
$worker->setId($workerId[0] . ':1:jobs'); $worker->setId($workerId[0] . ':1:jobs');
$worker->registerWorker(); $worker->registerWorker();
// Register some other false workers // Register some other false workers
$worker = new Resque_Worker('jobs'); $worker = new \Resque\Worker('jobs');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->setId('my.other.host:1:jobs'); $worker->setId('my.other.host:1:jobs');
$worker->registerWorker(); $worker->registerWorker();
$this->assertEquals(2, count(Resque_Worker::all())); $this->assertEquals(2, count(\Resque\Worker::all()));
$worker->pruneDeadWorkers(); $worker->pruneDeadWorkers();
// my.other.host should be left // my.other.host should be left
$workers = Resque_Worker::all(); $workers = \Resque\Worker::all();
$this->assertEquals(1, count($workers)); $this->assertEquals(1, count($workers));
$this->assertEquals((string)$worker, (string)$workers[0]); $this->assertEquals((string)$worker, (string)$workers[0]);
} }
public function testWorkerFailsUncompletedJobsOnExit() public function testWorkerFailsUncompletedJobsOnExit()
{ {
$worker = new Resque_Worker('jobs'); $worker = new \Resque\Worker('jobs');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->registerWorker(); $worker->registerWorker();
$payload = [ $payload = [
'class' => 'Test_Job' 'class' => '\Resque\Test\TestJob'
]; ];
$job = new Resque_Job('jobs', $payload); $job = new \Resque\Job\Job('jobs', $payload);
$worker->workingOn($job); $worker->workingOn($job);
$worker->unregisterWorker(); $worker->unregisterWorker();
$this->assertEquals(1, Resque_Stat::get('failed')); $this->assertEquals(1, \Resque\Stat::get('failed'));
} }
public function testBlockingListPop() public function testBlockingListPop()
{ {
$worker = new Resque_Worker('jobs'); $worker = new \Resque\Worker('jobs');
$worker->setLogger(new Resque_Log()); $worker->setLogger(new \Resque\Log());
$worker->registerWorker(); $worker->registerWorker();
Resque::enqueue('jobs', 'Test_Job_1'); \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob_1');
Resque::enqueue('jobs', 'Test_Job_2'); \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob_2');
$i = 1; $i = 1;
while ($job = $worker->reserve(true, 2)) { while ($job = $worker->reserve(true, 2)) {
$this->assertEquals('Test_Job_' . $i, $job->payload['class']); $this->assertEquals('\Resque\Test\TestJob_' . $i, $job->payload['class']);
if ($i == 2) { if ($i == 2) {
break; break;

View File

@ -1,4 +1,7 @@
<?php <?php
namespace Resque\Test;
/** /**
* Resque test bootstrap file - sets up a test environment. * Resque test bootstrap file - sets up a test environment.
* *
@ -8,36 +11,29 @@
*/ */
$loader = require __DIR__ . '/../vendor/autoload.php'; $loader = require __DIR__ . '/../vendor/autoload.php';
$loader->add('Resque_Tests', __DIR__); // $loader->add('Resque_Tests', __DIR__);
# Redis configuration # Redis configuration
global $redisTestServer; global $redisTestServer;
$redisTestServer = getenv("REDIS_SERVER") ?: "redis"; $redisTestServer = getenv("REDIS_SERVER") ?: "redis";
Resque::setBackend($redisTestServer); \Resque\Resque::setBackend($redisTestServer);
# Check Redis is accessable locally # Check Redis is accessable locally
try { try {
$redisTest = new Resque_Redis($redisTestServer); $redisTest = new \Resque\Redis($redisTestServer);
} catch (Exception $e) { } catch (\Exception $e) {
throw new Exception("Unable to connect to redis. Please check there is a redis-server running."); throw new \Exception("Unable to connect to redis. Please check there is a redis-server running.");
} }
$redisTest = null; $redisTest = null;
# Cleanup forked workers cleanly # Cleanup forked workers cleanly
if (function_exists('pcntl_signal')) { if (function_exists('pcntl_signal')) {
function sigint() pcntl_signal(SIGINT, function() { exit; });
{ pcntl_signal(SIGTERM, function() { exit; });
exit;
}
pcntl_signal(SIGINT, 'sigint');
pcntl_signal(SIGTERM, 'sigint');
} }
# Bootstrap it # Bootstrap it
class Test_Job class TestJob
{ {
public static $called = false; public static $called = false;
@ -47,25 +43,25 @@ class Test_Job
} }
} }
class Failing_Job_Exception extends Exception class FailingJobException extends \Exception
{ {
} }
class Failing_Job class FailingJob
{ {
public function perform() public function perform()
{ {
throw new Failing_Job_Exception('Message!'); throw new FailingJobException('Message!');
} }
} }
class Test_Job_Without_Perform_Method class TestJobWithoutPerformMethod
{ {
} }
class Test_Job_With_SetUp class TestJobWithSetUp
{ {
public static $called = false; public static $called = false;
public $args = false; public $args = false;
@ -82,7 +78,7 @@ class Test_Job_With_SetUp
} }
class Test_Job_With_TearDown class TestJobWithTearDown
{ {
public static $called = false; public static $called = false;
public $args = false; public $args = false;