diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..b270598
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,36 @@
+name: CI
+on: [push]
+jobs:
+ Linter:
+ runs-on: ubuntu-latest
+ container: php:8.2
+ steps:
+ - uses: actions/checkout@v3
+ - name: Install composer
+ run: apt-get update -yq && apt-get install git wget procps unzip -y && pecl install -o -f redis && rm -rf /tmp/pear && docker-php-ext-enable redis && wget https://getcomposer.org/composer.phar && php composer.phar install --dev
+ - name: Validate composer.json and composer.lock
+ run: php composer.phar validate --strict
+ - name: Install dependencies
+ run: php composer.phar install --dev --prefer-dist --no-progress
+ - name: Run PHPCS Linter
+ run: php -d memory_limit=256M vendor/bin/phpcs -s --standard=ruleset.xml
+ PHPTest:
+ runs-on: ubuntu-latest
+ container: php:${{ matrix.php_version }}
+ strategy:
+ matrix:
+ php_version: [8.1, 8.2,8.3,8.4]
+ services:
+ redis:
+ image: redis:7.0
+ options: >-
+ --health-cmd "redis-cli ping"
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
+ steps:
+ - uses: actions/checkout@v3
+ - name: Install composer
+ run: apt-get update -yq && apt-get install git wget procps unzip -y && pecl install -o -f redis && rm -rf /tmp/pear && docker-php-ext-enable redis && wget https://getcomposer.org/composer.phar && php composer.phar install --dev
+ - name: Run PHP ${{ matrix.php_version }}} Unit Tests
+ run: php vendor/bin/phpunit --verbose --configuration phpunit.xml
diff --git a/.gitignore b/.gitignore
index a793d95..aa30d8b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,2 @@
vendor/
-*.swp
-phpunit.xml
+.phpunit.result.cache
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..fe02d9b
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,43 @@
+.docker_boostrap: &docker_boostrap |
+ [[ ! -e /.dockerenv ]] && exit 0
+ set -xe
+
+ # Install git (the php image doesn't have it) which is required by composer
+ apt-get update -yq
+ apt-get install git wget procps unzip -y
+
+ # Install pcntl and redis extentions
+ pecl install -o -f redis \
+ && rm -rf /tmp/pear \
+ && docker-php-ext-enable redis
+ docker-php-ext-install pcntl
+
+ # Install Composer
+ wget https://getcomposer.org/composer.phar
+ php composer.phar install --dev
+
+services:
+ - redis:7
+
+# Test PHP
+test:
+ image: php:$PHP_VERSION
+ parallel:
+ matrix:
+ - PHP_VERSION: [ "7.4", "8.0", "8.1", "8.2" ]
+ before_script:
+ - *docker_boostrap
+ script:
+ - php vendor/bin/phpunit --verbose --configuration phpunit.xml
+ tags:
+ - docker
+
+# Codestandards
+lint:
+ image: php:8.2
+ 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
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index b7b7a22..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-language: php
-
-php:
- - 7.0
- - 7.1
- - 7.2
- - hhvm
-
-services:
- - redis-server
-
-before_script:
- - echo "extension = redis.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- - composer install
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 04eb5dd..276f6e3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,97 @@
+# 2.5.3 (2025-06-08)
+- Update typing of Log() to support all psr\log versions
+
+- # 2.5.2 (2025-06-08)
+- Update typing of Log() to support all psr\log versions
+
+# 2.5.1 (2025-06-08)
+- Update psr/log version requirements
+
+# 2.5.0 (2025-06-08)
+- Update packages
+
+# 2.4.0 (2024-12-11)
+- Update packages (psr/log ^3.0.2)
+
+# 2.3.0 (2024-09-04)
+- Update packages
+
+# 2.2.0 (2023-03-20)
+- Update pacakges
+- Bump requirements to PHP >= 8.1
+
+# 2.1.3 (2023-11-15)
+- Resolved issue with SET EX TTL's using unix-timestamps
+
+# 2.1.2 (2023-03-22)
+- Update composer packages
+- Update git information (GitHub)
+
+# 2.1.1 (2023-03-20)
+- Changed setex to set with EX values
+- Added TTLs to missing keys
+
+## 2.1.0 (2023-02-07)
+- Add PHP 8.1 / 8.2 unit tests
+- Updated code to be PHP 8.2 compliant
+
+## 2.0.3 (2022-09-12)
+- Update composer packages
+- Added WoodpeckerCI tests
+- Updated links in composer package
+- Stricter typing
+
+## 2.0.2 (2022-02-15)
+- Replace strftime with strtotime for PHP8.1 support
+- Added processing class into proc line for easier debugging
+
+## 2.0.1 (2022-02-08)
+- Fixed issue with lingering keys causing constant memory growth
+- Add PHP8 support
+- Composer upgrade
+
+## 2.0.0 (2021-02-19)
+- Moved to PSR-4
+- Namespaced codebase
+- Added more comments throughout
+
+## 1.4.7 (2020-04-11)
+- Update PHPUnit to 9
+- Start adding return types
+
+## 1.4.6 (2020-01-10)
+- Switched IF Statement order to prevent excess calls to redis.
+
+## 1.4.5 (2019-08-28)
+- Added 'replaced' composer tag.
+- Formatting changes.
+
+## 1.4.4 (2019-06-02)
+- Updated tests to run on GitLab CI.
+- Can now run tests locally using `gitlab-runner exec docker test:7.0`
+
+## 1.4.3 (2018-07-16)
+- Updated README to include supervisor configuration.
+- Change logfile date format to `%Y-%m-%d %T`.
+- Added return types to more functions.
+
+## 1.4.2 (2018-05-30)
+- Reimplemented credis due to issues with Redis: Connection Closed.
+- Updated Docs.
+
+## 1.4.1 (2018-05-29)
+- Updated travis builds to run on PHP 7.0, 7.1 and 7.2.
+- Added ability to specify multiple log levels. [DEBUG/INFO/NOTICE/WARNING/ERROR/CRITICAL/ALERT/EMERGENCY]
+- Default `LOGLEVEL` is now `WARNING`.
+- Removed VERBOSE / VVERBOSE flags and always output timestamp in logs.
+- Added 48 hour TTL to the worker started timestamp to prevent db pollution on server termination.
+
## 1.4 (2018-05-25)
+- Forked from chrisboulton/php-resque.
+- Replaced credis in favour of phpredis.
+- Reformatted codebase to be PSR2 compliant.
-
-
-## 1.3 (2013) ##
+## 1.3 (2013)
**Note:** This release introduces backwards incompatible changes with all previous versions of php-resque. Please see below for details.
@@ -61,7 +150,7 @@ Changes by iskandar introduce improved support for using DSNs to connect to Redi
* Pass queue name to afterEvent callback
* Only declare RedisException if it doesn't already exist (Matt Heath)
* 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)
* General tidy up of comments and files/folders
diff --git a/HOWITWORKS.md b/HOWITWORKS.md
index ec85fa3..7168926 100644
--- a/HOWITWORKS.md
+++ b/HOWITWORKS.md
@@ -14,9 +14,9 @@ What happens when you call `Resque::enqueue()`?
4. `Resque_Job::create()` pushes the job to the requested queue (first
argument)
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
-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
value, then returns control to `Resque_Job::create()`
7. `Resque_Job::create()` returns control to `Resque::enqueue()`, with the job
@@ -85,15 +85,15 @@ How do the workers process the queues?
* Worker
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
- a `Resque_Job_DirtyExitException` as its only argument.
+ a `Resque\Job\DirtyExitException` as its only argument.
3. `Resque_Job->fail()` triggers an `onFailure` event
4. `Resque_Job->fail()` updates the job status from `RUNNING` to `FAILED`
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
6. `Resque_Failure::create()` creates a new object of whatever type has
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
in the `failed` queue
7. `Resque_Job->fail()` increments two failure counters in Redis: one for
diff --git a/README.md b/README.md
index a8bc8fc..c2d7234 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-php-resque: PHP Resque Worker (and Enqueue) [](https://travis-ci.org/iDanoo/php-resque)
+php-resque: PHP Background (Resque) Worker
===========================================
Resque is a Redis-backed library for creating background jobs, placing
@@ -34,9 +34,15 @@ not exit with a status code as 0
* Has built in support for `setUp` and `tearDown` methods, called
pre and post jobs
+On top of the original fork (chrisboulton/php-resque) I have added:
+
+* Custom log levels
+* PHP7.0+ compatibility
+
+
## Requirements ##
-* PHP 5.6+
+* PHP 8.1+
* phpredis
* Redis 2.2+
@@ -47,19 +53,9 @@ Composer package inside your project.
If you're not familiar with Composer, please see .
-1. Add php-resque to your application's composer.json.
+1. Run `composer require idanoo/php-resque`.
-```json
-{
- "require": {
- "iDanoo/php-resque": "dev-master"
- }
-}
-```
-
-2. Run `composer install`.
-
-3. If you haven't already, add the Composer autoload to your project's
+2. If you haven't already, add the Composer autoload to your project's
initialization file. (example)
```sh
@@ -74,12 +70,11 @@ Jobs are queued as follows:
```php
// Required if redis is located elsewhere
-Resque::setBackend('localhost:6379');
+Resque::setBackend('redis:6379');
-$args = array(
- 'name' => 'TestName'
- );
-Resque::enqueue('default', 'My_Job', $args);
+$args = ['name' => 'TestName'];
+
+Resque::enqueue('default', '\App\MyJobClass', $args);
```
### Defining Jobs ###
@@ -87,7 +82,9 @@ Resque::enqueue('default', 'My_Job', $args);
Each job should be in its own class, and include a `perform` method.
```php
-class My_Job
+namespace \App;
+
+class MyJobClass
{
public function perform()
{
@@ -110,7 +107,9 @@ The `tearDown` method, if defined, will be called after the job finishes.
```php
-class My_Job
+namespace App;
+
+class MyJobClass
{
public function setUp()
{
@@ -134,17 +133,17 @@ class My_Job
This method can be used to conveniently remove a job from a queue.
```php
-// Removes job class 'My_Job' of queue 'default'
-Resque::dequeue('default', ['My_Job']);
+// Removes job class '\App\MyJobClass' of queue 'default'
+Resque::dequeue('default', ['\App\MyJobClass']);
-// Removes job class 'My_Job' with Job ID '087df5819a790ac666c9608e2234b21e' of queue 'default'
-Resque::dequeue('default', ['My_Job' => '087df5819a790ac666c9608e2234b21e']);
+// Removes job class '\App\MyJobClass' with Job ID '087df5819a790ac666c9608e2234b21e' of queue 'default'
+Resque::dequeue('default', ['\App\MyJobClass' => '087df5819a790ac666c9608e2234b21e']);
-// Removes job class 'My_Job' with arguments of queue 'default'
-Resque::dequeue('default', ['My_Job' => array('foo' => 1, 'bar' => 2)]);
+// Removes job class '\App\MyJobClass' with arguments of queue 'default'
+Resque::dequeue('default', ['\App\MyJobClass' => ['foo' => 1, 'bar' => 2]]);
// Removes multiple jobs
-Resque::dequeue('default', ['My_Job', 'My_Job2']);
+Resque::dequeue('default', ['\App\MyJobClass', '\App\MyJobClass2']);
```
If no jobs are given, this method will dequeue all jobs matching the provided queue.
@@ -165,7 +164,7 @@ To track the status of a job, pass `true` as the fourth argument to
returned:
```php
-$token = Resque::enqueue('default', 'My_Job', $args, true);
+$token = Resque::enqueue('default', '\App\MyJobClass', $args, true);
echo $token;
```
@@ -232,12 +231,15 @@ variables are set (`setenv`) before you do.
### Logging ###
The port supports the same environment variables for logging to STDOUT.
-Setting `VERBOSE` will print basic debugging information and `VVERBOSE`
-will print detailed information.
+Setting `LOGLEVEL` will print different logs depending on levels.
+Valid loglevels are listed below with an example.
+Default `LOGLEVEL` is `WARNING`.
+```bash
+[DEBUG/INFO/NOTICE/WARNING/ERROR/CRITICAL/ALERT/EMERGENCY]
+```
```sh
-$ VERBOSE=1 QUEUE=file_serve bin/resque
-$ VVERBOSE=1 QUEUE=file_serve bin/resque
+$ LOGLEVEL=DEBUG QUEUE=file_serve bin/resque
```
### Priorities and Queue Lists ###
@@ -342,7 +344,7 @@ Resque_Event::listen('eventName', [callback]);
* A string with the name of a function
* An array containing an object and method to call
* An array containing an object and a static method to call
-* A closure (PHP 5.3+)
+* A closure
Events may pass arguments (documented below), so your callback should accept
these arguments.
@@ -359,8 +361,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
responsibility to register listeners.
-A sample plugin is included in the `extras` directory.
-
### Events ###
#### beforeFirstFork ####
@@ -430,6 +430,30 @@ Called after a job has been queued using the `Resque::enqueue` method. Arguments
* Queue - string containing the name of the queue the job was added to
* ID - string containing the new token of the enqueued job
+## Supervisor Configuration ##
+
+You may like to run php-resque on a supervisor task to manage the processes.
+The following is a default config that can be modified to suit.
+
+```sh
+[program:resque-dev]
+directory=/var/www # Project root
+command=php vendor/bin/resque
+numprocs=2 # Change this value for more threads
+environment=LOGLEVEL=NOTICE,QUEUE='*',BLOCKING=1,COUNT=1,APP_INCLUDE='includes/autoload.php',REDIS_BACKEND=127.0.0.1,REDIS_BACKEND_DB=0
+redirect_stderr=true # Output stderr to logfile
+stdout_logfile=/var/log/resque.log
+autostart=true
+autorestart=true
+stopsignal=QUIT
+process_name = %(program_name)s_%(process_num)02d
+```
+
+Issues:
+- Restarting worker doesn't always make it use updated code, I find on a dev-environment issuing
+the following command works well to restart everything.
+`sudo /etc/init.d/supervisor force-stop && sleep 1 && sudo /etc/init.d/supervisor restart`
+
## Step-By-Step ##
For a more in-depth look at what php-resque does under the hood (without
@@ -438,7 +462,7 @@ needing to directly examine the code), have a look at `HOWITWORKS.md`.
## Contributors ##
### Current Maintainers ###
-* @iDanoo
+* @idanoo
### Past Maintainer / Forked From ###
diff --git a/bin/resque b/bin/resque
index 1d60485..073f05a 100755
--- a/bin/resque
+++ b/bin/resque
@@ -2,14 +2,13 @@
1) {
+if (!empty($COUNT) && $COUNT > 1) {
$count = $COUNT;
}
+// Determines redis key prefix
$PREFIX = getenv('PREFIX');
-if(!empty($PREFIX)) {
- $logger->log(Psr\Log\LogLevel::INFO, 'Prefix set to {prefix}', array('prefix' => $PREFIX));
- Resque_Redis::prefix($PREFIX);
+if (!empty($PREFIX)) {
+ $logger->log(\Psr\Log\LogLevel::INFO, 'Prefix set to {prefix}', ['prefix' => $PREFIX]);
+ \Resque\Redis::prefix($PREFIX);
}
-if($count > 1) {
- for($i = 0; $i < $count; ++$i) {
- $pid = Resque::fork();
- if($pid === false || $pid === -1) {
- $logger->log(Psr\Log\LogLevel::EMERGENCY, 'Could not fork worker {count}', array('count' => $i));
+if ($count > 1) {
+ for ($i = 0; $i < $count; ++$i) {
+ $pid = \Resque\Resque::fork();
+ if ($pid === false || $pid === -1) {
+ $logger->log(\Psr\Log\LogLevel::EMERGENCY, 'Could not fork worker {count}', ['count' => $i]);
die();
- }
- // Child, start the worker
- else if(!$pid) {
+ } elseif (!$pid) {
+ // Child, start the worker
$queues = explode(',', $QUEUE);
- $worker = new Resque_Worker($queues);
+ $worker = new \Resque\Worker($queues);
$worker->setLogger($logger);
- $logger->log(Psr\Log\LogLevel::NOTICE, 'Starting worker {worker}', array('worker' => $worker));
+ $logger->log(\Psr\Log\LogLevel::NOTICE, 'Starting worker {worker}', ['worker' => $worker]);
$worker->work($interval, $BLOCKING);
break;
}
}
-}
-// Start a single worker
-else {
+} else {
+ // Start a single worker
$queues = explode(',', $QUEUE);
- $worker = new Resque_Worker($queues);
+ $worker = new \Resque\Worker($queues);
$worker->setLogger($logger);
$PIDFILE = getenv('PIDFILE');
if ($PIDFILE) {
file_put_contents($PIDFILE, getmypid()) or
- 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}', array('worker' => $worker));
+ $logger->log(\Psr\Log\LogLevel::NOTICE, 'Starting worker {worker}', ['worker' => $worker]);
$worker->work($interval, $BLOCKING);
}
-?>
diff --git a/build.xml b/build.xml
deleted file mode 100644
index 7289999..0000000
--- a/build.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/composer.json b/composer.json
index 88acec7..15199f0 100644
--- a/composer.json
+++ b/composer.json
@@ -1,9 +1,13 @@
{
"name": "idanoo/php-resque",
"type": "library",
+ "replace": {
+ "chrisboulton/php-resque": "*",
+ "danhunsaker/php-resque": "*"
+ },
"description": "Redis backed library for creating background jobs and processing them later. Based on resque for Ruby. Originally forked from chrisboulton/php-resque.",
- "keywords": ["job", "background", "redis", "resque"],
- "homepage": "http://www.github.com/iDanoo/php-resque/",
+ "keywords": ["job", "background", "redis", "resque", "php"],
+ "homepage": "https://github.com/idanoo/php-resque",
"license": "MIT",
"authors": [
{
@@ -12,23 +16,36 @@
}
],
"require": {
- "php": ">=7.0.0",
- "ext-pcntl": "*",
- "ext-redis": "*",
- "psr/log": "~1.0"
- },
- "suggest": {
- "ext-proctitle": "Allows php-resque to rename the title of UNIX processes to show the status of a worker."
+ "php": ">=8.1",
+ "psr/log": "^1.1 || ^2.0 || ^3.0",
+ "colinmollenhour/credis": "^1.14.0"
},
"require-dev": {
- "phpunit/phpunit": "^6"
+ "phpunit/phpunit": "^9",
+ "squizlabs/php_codesniffer": "3.*",
+ "phpcompatibility/php-compatibility": "^9.3",
+ "dealerdirect/phpcodesniffer-composer-installer": "^1.0"
},
"bin": [
"bin/resque"
],
"autoload": {
- "psr-0": {
- "Resque": "lib"
+ "psr-4": {
+ "Resque\\": "src/Resque"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Resque\\Test\\": "tests/Resque/Tests"
+ }
+ },
+ "support": {
+ "issues": "https://github.com/idanoo/php-resque/issues",
+ "source": "https://github.com/idanoo/php-resque"
+ },
+ "config": {
+ "allow-plugins": {
+ "dealerdirect/phpcodesniffer-composer-installer": true
}
}
}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..bb2aed1
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,2092 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "d8e5313006d5c73b54ee6a410b1ad016",
+ "packages": [
+ {
+ "name": "colinmollenhour/credis",
+ "version": "v1.17.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/colinmollenhour/credis.git",
+ "reference": "f4930b426f6b1238b687a1ffe6ee5af7f835b40a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/f4930b426f6b1238b687a1ffe6ee5af7f835b40a",
+ "reference": "f4930b426f6b1238b687a1ffe6ee5af7f835b40a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.4.0"
+ },
+ "suggest": {
+ "ext-redis": "Improved performance for communicating with redis"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "Client.php",
+ "Cluster.php",
+ "Sentinel.php",
+ "Module.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Colin Mollenhour",
+ "email": "colin@mollenhour.com"
+ }
+ ],
+ "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.",
+ "homepage": "https://github.com/colinmollenhour/credis",
+ "support": {
+ "issues": "https://github.com/colinmollenhour/credis/issues",
+ "source": "https://github.com/colinmollenhour/credis/tree/v1.17.0"
+ },
+ "time": "2025-02-10T18:58:46+00:00"
+ },
+ {
+ "name": "psr/log",
+ "version": "3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/log/tree/3.0.2"
+ },
+ "time": "2024-09-11T13:17:53+00:00"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "dealerdirect/phpcodesniffer-composer-installer",
+ "version": "v1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPCSStandards/composer-installer.git",
+ "reference": "4be43904336affa5c2f70744a348312336afd0da"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da",
+ "reference": "4be43904336affa5c2f70744a348312336afd0da",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0 || ^2.0",
+ "php": ">=5.4",
+ "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0"
+ },
+ "require-dev": {
+ "composer/composer": "*",
+ "ext-json": "*",
+ "ext-zip": "*",
+ "php-parallel-lint/php-parallel-lint": "^1.3.1",
+ "phpcompatibility/php-compatibility": "^9.0",
+ "yoast/phpunit-polyfills": "^1.0"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
+ },
+ "autoload": {
+ "psr-4": {
+ "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Franck Nijhof",
+ "email": "franck.nijhof@dealerdirect.com",
+ "homepage": "http://www.frenck.nl",
+ "role": "Developer / IT Manager"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors"
+ }
+ ],
+ "description": "PHP_CodeSniffer Standards Composer Installer Plugin",
+ "homepage": "http://www.dealerdirect.com",
+ "keywords": [
+ "PHPCodeSniffer",
+ "PHP_CodeSniffer",
+ "code quality",
+ "codesniffer",
+ "composer",
+ "installer",
+ "phpcbf",
+ "phpcs",
+ "plugin",
+ "qa",
+ "quality",
+ "standard",
+ "standards",
+ "style guide",
+ "stylecheck",
+ "tests"
+ ],
+ "support": {
+ "issues": "https://github.com/PHPCSStandards/composer-installer/issues",
+ "source": "https://github.com/PHPCSStandards/composer-installer"
+ },
+ "time": "2023-01-05T11:28:13+00:00"
+ },
+ {
+ "name": "doctrine/instantiator",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
+ "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^11",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpbench/phpbench": "^1.2",
+ "phpstan/phpstan": "^1.9.4",
+ "phpstan/phpstan-phpunit": "^1.3",
+ "phpunit/phpunit": "^9.5.27",
+ "vimeo/psalm": "^5.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "https://ocramius.github.io/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/instantiator/issues",
+ "source": "https://github.com/doctrine/instantiator/tree/2.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-12-30T00:23:10+00:00"
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.13.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c",
+ "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "conflict": {
+ "doctrine/collections": "<1.6.8",
+ "doctrine/common": "<2.13.3 || >=3 <3.2.2"
+ },
+ "require-dev": {
+ "doctrine/collections": "^1.6.8",
+ "doctrine/common": "^2.13.3 || ^3.2.2",
+ "phpspec/prophecy": "^1.10",
+ "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ],
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Create deep copies (clones) of your objects",
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
+ "support": {
+ "issues": "https://github.com/myclabs/DeepCopy/issues",
+ "source": "https://github.com/myclabs/DeepCopy/tree/1.13.1"
+ },
+ "funding": [
+ {
+ "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2025-04-29T12:36:36+00:00"
+ },
+ {
+ "name": "nikic/php-parser",
+ "version": "v5.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "ae59794362fe85e051a58ad36b289443f57be7a9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ae59794362fe85e051a58ad36b289443f57be7a9",
+ "reference": "ae59794362fe85e051a58ad36b289443f57be7a9",
+ "shasum": ""
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-json": "*",
+ "ext-tokenizer": "*",
+ "php": ">=7.4"
+ },
+ "require-dev": {
+ "ircmaxell/php-yacc": "^0.0.7",
+ "phpunit/phpunit": "^9.0"
+ },
+ "bin": [
+ "bin/php-parse"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PhpParser\\": "lib/PhpParser"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Nikita Popov"
+ }
+ ],
+ "description": "A PHP parser written in PHP",
+ "keywords": [
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/nikic/PHP-Parser/issues",
+ "source": "https://github.com/nikic/PHP-Parser/tree/v5.5.0"
+ },
+ "time": "2025-05-31T08:24:38+00:00"
+ },
+ {
+ "name": "phar-io/manifest",
+ "version": "2.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/manifest.git",
+ "reference": "54750ef60c58e43759730615a392c31c80e23176"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
+ "reference": "54750ef60c58e43759730615a392c31c80e23176",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "ext-phar": "*",
+ "ext-xmlwriter": "*",
+ "phar-io/version": "^3.0.1",
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+ "support": {
+ "issues": "https://github.com/phar-io/manifest/issues",
+ "source": "https://github.com/phar-io/manifest/tree/2.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/theseer",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-03T12:33:53+00:00"
+ },
+ {
+ "name": "phar-io/version",
+ "version": "3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/version.git",
+ "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+ "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Library for handling version information and constraints",
+ "support": {
+ "issues": "https://github.com/phar-io/version/issues",
+ "source": "https://github.com/phar-io/version/tree/3.2.1"
+ },
+ "time": "2022-02-21T01:04:05+00:00"
+ },
+ {
+ "name": "phpcompatibility/php-compatibility",
+ "version": "9.3.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPCompatibility/PHPCompatibility.git",
+ "reference": "9fb324479acf6f39452e0655d2429cc0d3914243"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243",
+ "reference": "9fb324479acf6f39452e0655d2429cc0d3914243",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3",
+ "squizlabs/php_codesniffer": "^2.3 || ^3.0.2"
+ },
+ "conflict": {
+ "squizlabs/php_codesniffer": "2.6.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0"
+ },
+ "suggest": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.",
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
+ },
+ "type": "phpcodesniffer-standard",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-3.0-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Wim Godden",
+ "homepage": "https://github.com/wimg",
+ "role": "lead"
+ },
+ {
+ "name": "Juliette Reinders Folmer",
+ "homepage": "https://github.com/jrfnl",
+ "role": "lead"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors"
+ }
+ ],
+ "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.",
+ "homepage": "http://techblog.wimgodden.be/tag/codesniffer/",
+ "keywords": [
+ "compatibility",
+ "phpcs",
+ "standards"
+ ],
+ "support": {
+ "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues",
+ "source": "https://github.com/PHPCompatibility/PHPCompatibility"
+ },
+ "time": "2019-12-27T09:44:58+00:00"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "9.2.32",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5",
+ "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "ext-xmlwriter": "*",
+ "nikic/php-parser": "^4.19.1 || ^5.1.0",
+ "php": ">=7.3",
+ "phpunit/php-file-iterator": "^3.0.6",
+ "phpunit/php-text-template": "^2.0.4",
+ "sebastian/code-unit-reverse-lookup": "^2.0.3",
+ "sebastian/complexity": "^2.0.3",
+ "sebastian/environment": "^5.1.5",
+ "sebastian/lines-of-code": "^1.0.4",
+ "sebastian/version": "^3.0.2",
+ "theseer/tokenizer": "^1.2.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.6"
+ },
+ "suggest": {
+ "ext-pcov": "PHP extension that provides line coverage",
+ "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "9.2.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
+ "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-08-22T04:23:01+00:00"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "3.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+ "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
+ "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2021-12-02T12:48:52+00:00"
+ },
+ {
+ "name": "phpunit/php-invoker",
+ "version": "3.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-invoker.git",
+ "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
+ "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "ext-pcntl": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-pcntl": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Invoke callables with a timeout",
+ "homepage": "https://github.com/sebastianbergmann/php-invoker/",
+ "keywords": [
+ "process"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
+ "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T05:58:55+00:00"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "2.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
+ "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
+ "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T05:33:50+00:00"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "5.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
+ "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-timer/issues",
+ "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:16:10+00:00"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "9.6.23",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "43d2cb18d0675c38bd44982a5d1d88f6d53d8d95"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/43d2cb18d0675c38bd44982a5d1d88f6d53d8d95",
+ "reference": "43d2cb18d0675c38bd44982a5d1d88f6d53d8d95",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.5.0 || ^2",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "ext-xmlwriter": "*",
+ "myclabs/deep-copy": "^1.13.1",
+ "phar-io/manifest": "^2.0.4",
+ "phar-io/version": "^3.2.1",
+ "php": ">=7.3",
+ "phpunit/php-code-coverage": "^9.2.32",
+ "phpunit/php-file-iterator": "^3.0.6",
+ "phpunit/php-invoker": "^3.1.1",
+ "phpunit/php-text-template": "^2.0.4",
+ "phpunit/php-timer": "^5.0.3",
+ "sebastian/cli-parser": "^1.0.2",
+ "sebastian/code-unit": "^1.0.8",
+ "sebastian/comparator": "^4.0.8",
+ "sebastian/diff": "^4.0.6",
+ "sebastian/environment": "^5.1.5",
+ "sebastian/exporter": "^4.0.6",
+ "sebastian/global-state": "^5.0.7",
+ "sebastian/object-enumerator": "^4.0.4",
+ "sebastian/resource-operations": "^3.0.4",
+ "sebastian/type": "^3.2.1",
+ "sebastian/version": "^3.0.2"
+ },
+ "suggest": {
+ "ext-soap": "To be able to generate mocks based on WSDL files",
+ "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "9.6-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/Framework/Assert/Functions.php"
+ ],
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/phpunit/issues",
+ "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.23"
+ },
+ "funding": [
+ {
+ "url": "https://phpunit.de/sponsors.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ },
+ {
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2025-05-02T06:40:34+00:00"
+ },
+ {
+ "name": "sebastian/cli-parser",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/cli-parser.git",
+ "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
+ "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library for parsing CLI options",
+ "homepage": "https://github.com/sebastianbergmann/cli-parser",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
+ "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-02T06:27:43+00:00"
+ },
+ {
+ "name": "sebastian/code-unit",
+ "version": "1.0.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit.git",
+ "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120",
+ "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Collection of value objects that represent the PHP code units",
+ "homepage": "https://github.com/sebastianbergmann/code-unit",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit/issues",
+ "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:08:54+00:00"
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "2.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
+ "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
+ "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T05:30:19+00:00"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "4.0.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "fa0f136dd2334583309d32b62544682ee972b51a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a",
+ "reference": "fa0f136dd2334583309d32b62544682ee972b51a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/diff": "^4.0",
+ "sebastian/exporter": "^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "https://github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/comparator/issues",
+ "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2022-09-14T12:41:17+00:00"
+ },
+ {
+ "name": "sebastian/complexity",
+ "version": "2.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/complexity.git",
+ "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a",
+ "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library for calculating the complexity of PHP code units",
+ "homepage": "https://github.com/sebastianbergmann/complexity",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/complexity/issues",
+ "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-22T06:19:30+00:00"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "4.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc",
+ "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3",
+ "symfony/process": "^4.2 || ^5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff",
+ "udiff",
+ "unidiff",
+ "unified diff"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/diff/issues",
+ "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-02T06:30:58+00:00"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "5.1.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
+ "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-posix": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/environment/issues",
+ "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:03:51+00:00"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "4.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72",
+ "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "https://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/exporter/issues",
+ "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-02T06:33:00+00:00"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "5.0.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9",
+ "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/object-reflector": "^2.0",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "ext-dom": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "keywords": [
+ "global state"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/global-state/issues",
+ "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-02T06:35:11+00:00"
+ },
+ {
+ "name": "sebastian/lines-of-code",
+ "version": "1.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/lines-of-code.git",
+ "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5",
+ "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library for counting the lines of code in PHP source code",
+ "homepage": "https://github.com/sebastianbergmann/lines-of-code",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
+ "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-22T06:20:34+00:00"
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "4.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "5c9eeac41b290a3712d88851518825ad78f45c71"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71",
+ "reference": "5c9eeac41b290a3712d88851518825ad78f45c71",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/object-reflector": "^2.0",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
+ "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:12:34+00:00"
+ },
+ {
+ "name": "sebastian/object-reflector",
+ "version": "2.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-reflector.git",
+ "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
+ "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Allows reflection of object attributes, including inherited and non-public ones",
+ "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
+ "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:14:26+00:00"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "4.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
+ "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "https://github.com/sebastianbergmann/recursion-context",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:07:39+00:00"
+ },
+ {
+ "name": "sebastian/resource-operations",
+ "version": "3.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/resource-operations.git",
+ "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
+ "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "support": {
+ "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-14T16:00:52+00:00"
+ },
+ {
+ "name": "sebastian/type",
+ "version": "3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/type.git",
+ "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
+ "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Collection of value objects that represent the types of the PHP type system",
+ "homepage": "https://github.com/sebastianbergmann/type",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/type/issues",
+ "source": "https://github.com/sebastianbergmann/type/tree/3.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:13:03+00:00"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "c6c1022351a901512170118436c764e473f6de8c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
+ "reference": "c6c1022351a901512170118436c764e473f6de8c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/version/issues",
+ "source": "https://github.com/sebastianbergmann/version/tree/3.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T06:39:44+00:00"
+ },
+ {
+ "name": "squizlabs/php_codesniffer",
+ "version": "3.13.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
+ "reference": "65ff2489553b83b4597e89c3b8b721487011d186"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/65ff2489553b83b4597e89c3b8b721487011d186",
+ "reference": "65ff2489553b83b4597e89c3b8b721487011d186",
+ "shasum": ""
+ },
+ "require": {
+ "ext-simplexml": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4"
+ },
+ "bin": [
+ "bin/phpcbf",
+ "bin/phpcs"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Greg Sherwood",
+ "role": "Former lead"
+ },
+ {
+ "name": "Juliette Reinders Folmer",
+ "role": "Current lead"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors"
+ }
+ ],
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
+ "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
+ "keywords": [
+ "phpcs",
+ "standards",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues",
+ "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy",
+ "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
+ "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/PHPCSStandards",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/jrfnl",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/php_codesniffer",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/phpcsstandards",
+ "type": "thanks_dev"
+ }
+ ],
+ "time": "2025-05-11T03:36:00+00:00"
+ },
+ {
+ "name": "theseer/tokenizer",
+ "version": "1.2.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
+ "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+ "support": {
+ "issues": "https://github.com/theseer/tokenizer/issues",
+ "source": "https://github.com/theseer/tokenizer/tree/1.2.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/theseer",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-03T12:36:25+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": {},
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=8.1"
+ },
+ "platform-dev": {},
+ "plugin-api-version": "2.6.0"
+}
diff --git a/demo/bad_job.php b/demo/bad_job.php
deleted file mode 100644
index cd719cc..0000000
--- a/demo/bad_job.php
+++ /dev/null
@@ -1,8 +0,0 @@
-isTracking()) {
die("Resque is not tracking the status of this job.\n");
}
@@ -20,4 +23,4 @@ echo "Tracking status of " . $argv[1] . ". Press [break] to stop.\n\n";
while (true) {
fwrite(STDOUT, "Status of " . $argv[1] . " is: " . $status->get() . "\n");
sleep(1);
-}
\ No newline at end of file
+}
diff --git a/demo/init.php b/examples/Init.php
similarity index 94%
rename from demo/init.php
rename to examples/Init.php
index 62dff24..11d4833 100644
--- a/demo/init.php
+++ b/examples/Init.php
@@ -1,14 +1,16 @@
time(),
- 'array' => array(
+ 'array' => [
'test' => 'test',
- ),
-);
+ ],
+];
if (empty($argv[2])) {
- $jobId = Resque::enqueue('default', $argv[1], $args, true);
+ $jobId = \Resque\Resque::enqueue('default', $argv[1], $args, true);
} 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";
diff --git a/extras/resque.logrotate b/examples/resque.logrotate
similarity index 82%
rename from extras/resque.logrotate
rename to examples/resque.logrotate
index 822c520..4d70dea 100644
--- a/extras/resque.logrotate
+++ b/examples/resque.logrotate
@@ -5,6 +5,6 @@
compress
compressoptions -4
notifempty
- create 640 root adm
+ create 640 root www-data
copytruncate
}
\ No newline at end of file
diff --git a/extras/resque.monit b/extras/resque.monit
deleted file mode 100644
index b611f8f..0000000
--- a/extras/resque.monit
+++ /dev/null
@@ -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
\ No newline at end of file
diff --git a/lib/Resque/Job/Factory.php b/lib/Resque/Job/Factory.php
deleted file mode 100644
index cf17294..0000000
--- a/lib/Resque/Job/Factory.php
+++ /dev/null
@@ -1,32 +0,0 @@
-args = $args;
- $instance->queue = $queue;
- return $instance;
- }
-}
diff --git a/lib/Resque/Job/FactoryInterface.php b/lib/Resque/Job/FactoryInterface.php
deleted file mode 100644
index a1203e1..0000000
--- a/lib/Resque/Job/FactoryInterface.php
+++ /dev/null
@@ -1,12 +0,0 @@
-
- * @license http://www.opensource.org/licenses/mit-license.php
- */
-
-class Resque_RedisException extends Resque_Exception
-{
-
-}
diff --git a/phpunit.xml.dist b/phpunit.xml
similarity index 58%
rename from phpunit.xml.dist
rename to phpunit.xml
index 61d2d7b..c718913 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml
@@ -1,24 +1,17 @@
- ./test/Resque/
+ ./tests/Resque/
-
-
-
- ./lib/Resque/
-
-
\ No newline at end of file
diff --git a/ruleset.xml b/ruleset.xml
new file mode 100644
index 0000000..6bd9f60
--- /dev/null
+++ b/ruleset.xml
@@ -0,0 +1,29 @@
+
+
+ PHP8.2 Ruleset
+
+ .
+ vendor
+ tests/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/Resque/Event.php b/src/Resque/Event.php
similarity index 88%
rename from lib/Resque/Event.php
rename to src/Resque/Event.php
index 2c8f182..f445375 100644
--- a/lib/Resque/Event.php
+++ b/src/Resque/Event.php
@@ -1,14 +1,16 @@
+ * @author Daniel Mason
* @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.
@@ -20,6 +22,7 @@ class Resque_Event
*
* @param string $event Name of event to be raised.
* @param mixed $data Optional, any data that should be passed to each callback.
+ *
* @return true
*/
public static function trigger($event, $data = null)
@@ -36,7 +39,8 @@ class Resque_Event
if (!is_callable($callback)) {
continue;
}
- call_user_func_array($callback, $data);
+
+ call_user_func_array($callback, array_values($data));
}
return true;
@@ -46,7 +50,8 @@ class Resque_Event
* Listen in on a given event to have a specified callback fired.
*
* @param string $event Name of event to listen on.
- * @param mixed $callback Any callback callable by call_user_func_array.
+ * @param mixed $callback Any callback callable by call_user_func_array
+ *
* @return true
*/
public static function listen($event, $callback)
@@ -64,6 +69,7 @@ class Resque_Event
*
* @param string $event Name of event.
* @param mixed $callback The callback as defined when listen() was called.
+ *
* @return true
*/
public static function stopListening($event, $callback)
@@ -82,8 +88,10 @@ class Resque_Event
/**
* Call all registered listeners.
+ *
+ * @return void
*/
- public static function clearListeners()
+ public static function clearListeners(): void
{
self::$events = [];
}
diff --git a/lib/Resque/Exception.php b/src/Resque/Exception.php
similarity index 58%
rename from lib/Resque/Exception.php
rename to src/Resque/Exception.php
index fe510ca..7e8b7ae 100644
--- a/lib/Resque/Exception.php
+++ b/src/Resque/Exception.php
@@ -1,13 +1,15 @@
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
-class Resque_Exception extends Exception
+class Exception extends \Exception
{
}
diff --git a/lib/Resque/Failure.php b/src/Resque/Failure/Failure.php
similarity index 67%
rename from lib/Resque/Failure.php
rename to src/Resque/Failure/Failure.php
index adf02a3..1a0b17f 100644
--- a/lib/Resque/Failure.php
+++ b/src/Resque/Failure/Failure.php
@@ -1,14 +1,16 @@
+ * @author Daniel Mason
* @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.
@@ -18,13 +20,17 @@ class Resque_Failure
/**
* Create a new failed job on the backend.
*
- * @param object $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 \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.
*/
- 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();
new $backend($payload, $exception, $worker, $queue);
}
@@ -32,12 +38,12 @@ class Resque_Failure
/**
* Return an instance of the backend for saving job failures.
*
- * @return object Instance of backend object.
+ * @return string
*/
public static function getBackend()
{
- if (self::$backend === null) {
- self::$backend = 'Resque_Failure_Redis';
+ if (is_null(self::$backend)) {
+ self::$backend = '\\Resque\\Failure\\ResqueFailureRedis';
}
return self::$backend;
@@ -49,9 +55,11 @@ class Resque_Failure
* It is your responsibility to have the backend class loaded (or autoloaded)
*
* @param string $backend The class name of the backend to pipe failures to.
+ *
+ * @return void
*/
- public static function setBackend($backend)
+ public static function setBackend(string $backend): void
{
self::$backend = $backend;
}
-}
\ No newline at end of file
+}
diff --git a/lib/Resque/Failure/Interface.php b/src/Resque/Failure/ResqueFailureInterface.php
similarity index 81%
rename from lib/Resque/Failure/Interface.php
rename to src/Resque/Failure/ResqueFailureInterface.php
index d6da0e2..980e656 100644
--- a/lib/Resque/Failure/Interface.php
+++ b/src/Resque/Failure/ResqueFailureInterface.php
@@ -1,13 +1,15 @@
+ * @package Resque\Failure
+ * @author Daniel Mason
* @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).
diff --git a/lib/Resque/Failure/Redis.php b/src/Resque/Failure/ResqueFailureRedis.php
similarity index 73%
rename from lib/Resque/Failure/Redis.php
rename to src/Resque/Failure/ResqueFailureRedis.php
index caff0d5..33a9cc1 100644
--- a/lib/Resque/Failure/Redis.php
+++ b/src/Resque/Failure/ResqueFailureRedis.php
@@ -1,13 +1,16 @@
+ * @package Resque\Failure
+ * @author Daniel Mason
* @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).
@@ -16,11 +19,12 @@ class Resque_Failure_Redis implements Resque_Failure_Interface
* @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 string $queue The name of the queue the job was fetched from.
+ * @throws \Resque\RedisException
*/
public function __construct($payload, $exception, $worker, $queue)
{
- $data = new stdClass;
- $data->failed_at = strftime('%a %b %d %H:%M:%S %Z %Y');
+ $data = new \stdClass();
+ $data->failed_at = date('D M d H:i:s T Y');
$data->payload = $payload;
$data->exception = get_class($exception);
$data->error = $exception->getMessage();
@@ -28,6 +32,6 @@ class Resque_Failure_Redis implements Resque_Failure_Interface
$data->worker = (string)$worker;
$data->queue = $queue;
$data = json_encode($data);
- Resque::redis()->rpush('failed', $data);
+ \Resque\Resque::redis()->rpush('failed', $data);
}
}
diff --git a/lib/Resque/Job/DirtyExitException.php b/src/Resque/Job/DirtyExitException.php
similarity index 61%
rename from lib/Resque/Job/DirtyExitException.php
rename to src/Resque/Job/DirtyExitException.php
index 7b1f88b..ba002bc 100644
--- a/lib/Resque/Job/DirtyExitException.php
+++ b/src/Resque/Job/DirtyExitException.php
@@ -1,13 +1,14 @@
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
-class Resque_Job_DirtyExitException extends RuntimeException
+class DirtyExitException extends \RuntimeException
{
-
}
diff --git a/lib/Resque/Job/DontCreate.php b/src/Resque/Job/DontCreate.php
similarity index 65%
rename from lib/Resque/Job/DontCreate.php
rename to src/Resque/Job/DontCreate.php
index 931ae91..21f4f4d 100644
--- a/lib/Resque/Job/DontCreate.php
+++ b/src/Resque/Job/DontCreate.php
@@ -1,13 +1,14 @@
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
-class Resque_Job_DontCreate extends Exception
+class DontCreate extends \Exception
{
-
}
diff --git a/lib/Resque/Job/DontPerform.php b/src/Resque/Job/DontPerform.php
similarity index 63%
rename from lib/Resque/Job/DontPerform.php
rename to src/Resque/Job/DontPerform.php
index 69075f4..cc1c029 100644
--- a/lib/Resque/Job/DontPerform.php
+++ b/src/Resque/Job/DontPerform.php
@@ -1,14 +1,14 @@
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
-
-class Resque_Job_DontPerform extends Exception
+class DontPerform extends \Exception
{
-
}
diff --git a/src/Resque/Job/Factory.php b/src/Resque/Job/Factory.php
new file mode 100644
index 0000000..9ee0b74
--- /dev/null
+++ b/src/Resque/Job/Factory.php
@@ -0,0 +1,50 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php
+ */
+
+class Factory implements FactoryInterface
+{
+ public ?Job $job;
+ public string $queue;
+ public array $args;
+
+ /**
+ * Create job factory
+ *
+ * @param $className
+ * @param array $args
+ * @param $queue
+ *
+ * @return \Resque\Job\JobInterface
+ *
+ * @throws \Resque\Exception
+ */
+ public function create($className, $args, $queue)
+ {
+ if (!class_exists($className)) {
+ throw new \Resque\Exception(
+ 'Could not find job class ' . $className . '.'
+ );
+ }
+
+ if (!method_exists($className, 'perform')) {
+ throw new \Resque\Exception(
+ 'Job class ' . $className . ' does not contain a perform() method.'
+ );
+ }
+
+ $instance = new $className();
+ $instance->args = $args;
+ $instance->queue = $queue;
+
+ return $instance;
+ }
+}
diff --git a/src/Resque/Job/FactoryInterface.php b/src/Resque/Job/FactoryInterface.php
new file mode 100644
index 0000000..a44d6ac
--- /dev/null
+++ b/src/Resque/Job/FactoryInterface.php
@@ -0,0 +1,22 @@
+
+ * @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);
+}
diff --git a/lib/Resque/Job.php b/src/Resque/Job/Job.php
similarity index 65%
rename from lib/Resque/Job.php
rename to src/Resque/Job/Job.php
index b47b515..8249559 100755
--- a/lib/Resque/Job.php
+++ b/src/Resque/Job/Job.php
@@ -1,14 +1,16 @@
+ * @author Daniel Mason
* @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.
@@ -16,7 +18,7 @@ class Resque_Job
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;
@@ -26,12 +28,12 @@ class Resque_Job
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;
/**
- * @var Resque_Job_FactoryInterface
+ * @var \Resque\Job\FactoryInterface
*/
private $jobFactory;
@@ -57,28 +59,29 @@ class Resque_Job
* @param string $id Unique identifier for tracking the job. Generated if not supplied.
*
* @return string
+ *
* @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): string
{
if (is_null($id)) {
- $id = Resque::generateJobId();
+ $id = \Resque\Resque::generateJobId();
}
if ($args !== null && !is_array($args)) {
- throw new InvalidArgumentException(
+ throw new \InvalidArgumentException(
'Supplied $args must be an array.'
);
}
- Resque::push($queue, array(
+ \Resque\Resque::push($queue, [
'class' => $class,
- 'args' => array($args),
+ 'args' => [$args],
'id' => $id,
'queue_time' => microtime(true),
- ));
+ ]);
if ($monitor) {
- Resque_Job_Status::create($id);
+ Status::create($id);
}
return $id;
@@ -86,62 +89,67 @@ class Resque_Job
/**
* 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.
- * @return false|object Null when there aren't any waiting jobs, instance of Resque_Job when a job was found.
+ *
+ * @return Job|null 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): ?Job
{
- $payload = Resque::pop($queue);
+ $payload = \Resque\Resque::pop($queue);
if (!is_array($payload)) {
- return false;
+ return null;
}
- return new Resque_Job($queue, $payload);
+ return new Job($queue, $payload);
}
/**
* 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 int $timeout
- * @return false|object Null when there aren't any waiting jobs, instance of Resque_Job when a job was found.
+ *
+ * @return Job|null 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): ?Job
{
- $item = Resque::blpop($queues, $timeout);
+ $item = \Resque\Resque::blpop($queues, $timeout);
if (!is_array($item)) {
- return false;
+ return null;
}
- return new Resque_Job($item['queue'], $item['payload']);
+ return new Job($item['queue'], $item['payload']);
}
/**
* 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.
+ *
+ * @return bool
*/
- public function updateStatus($status)
+ public function updateStatus($status): bool
{
if (empty($this->payload['id'])) {
- return;
+ return false;
}
- $statusInstance = new Resque_Job_Status($this->payload['id']);
+ $statusInstance = new Status($this->payload['id']);
$statusInstance->update($status);
+ return true;
}
/**
* 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()
{
- $status = new Resque_Job_Status($this->payload['id']);
+ $status = new Status($this->payload['id']);
return $status->get();
}
@@ -153,7 +161,7 @@ class Resque_Job
public function getArguments()
{
if (!isset($this->payload['args'])) {
- return array();
+ return [];
}
return $this->payload['args'][0];
@@ -161,12 +169,12 @@ class Resque_Job
/**
* Get the instantiated object for this job that will be performing work.
- * @return Resque_JobInterface Instance of the object that this job belongs to.
- * @throws Resque_Exception
+ *
+ * @return \Resque\Job\JobInterface Instance of the object that this job belongs to.
*/
public function getInstance()
{
- if (!is_null($this->instance)) {
+ if (isset($this->instance) && !is_null($this->instance)) {
return $this->instance;
}
@@ -180,12 +188,13 @@ class Resque_Job
* associated with the job with the supplied arguments.
*
* @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()
{
try {
- Resque_Event::trigger('beforePerform', $this);
+ \Resque\Event::trigger('beforePerform', $this);
$instance = $this->getInstance();
if (method_exists($instance, 'setUp')) {
@@ -198,9 +207,9 @@ class Resque_Job
$instance->tearDown();
}
- Resque_Event::trigger('afterPerform', $this);
- } // beforePerform/setUp have said don't perform this job. Return.
- catch (Resque_Job_DontPerform $e) {
+ \Resque\Event::trigger('afterPerform', $this);
+ } catch (DontPerform $e) {
+ /** @noinspection PhpRedundantCatchClauseInspection */
return false;
}
@@ -214,29 +223,30 @@ class Resque_Job
*/
public function fail($exception)
{
- Resque_Event::trigger('onFailure', array(
+ \Resque\Event::trigger('onFailure', [
'exception' => $exception,
'job' => $this,
- ));
+ ]);
- $this->updateStatus(Resque_Job_Status::STATUS_FAILED);
- Resque_Failure::create(
+ $this->updateStatus(Status::STATUS_FAILED);
+ \Resque\Failure\Failure::create(
$this->payload,
$exception,
$this->worker,
$this->queue
);
- Resque_Stat::incr('failed');
- Resque_Stat::incr('failed:' . $this->worker);
+ \Resque\Stat::incr('failed');
+ \Resque\Stat::incr('failed:' . $this->worker);
}
/**
* Re-queue the current job.
+ *
* @return string
*/
public function recreate()
{
- $status = new Resque_Job_Status($this->payload['id']);
+ $status = new Status($this->payload['id']);
$monitor = false;
if ($status->isTracking()) {
$monitor = true;
@@ -252,9 +262,9 @@ class Resque_Job
*/
public function __toString()
{
- $name = array(
+ $name = [
'Job{' . $this->queue . '}'
- );
+ ];
if (!empty($this->payload['id'])) {
$name[] = 'ID: ' . $this->payload['id'];
}
@@ -266,10 +276,11 @@ class Resque_Job
}
/**
- * @param Resque_Job_FactoryInterface $jobFactory
- * @return Resque_Job
+ * @param FactoryInterface $jobFactory
+ *
+ * @return Job
*/
- public function setJobFactory(Resque_Job_FactoryInterface $jobFactory)
+ public function setJobFactory(FactoryInterface $jobFactory)
{
$this->jobFactory = $jobFactory;
@@ -277,13 +288,14 @@ class Resque_Job
}
/**
- * @return Resque_Job_FactoryInterface
+ * @return FactoryInterface
*/
public function getJobFactory()
{
- if ($this->jobFactory === null) {
- $this->jobFactory = new Resque_Job_Factory();
+ if (is_null($this->jobFactory)) {
+ $this->jobFactory = new Factory();
}
+
return $this->jobFactory;
}
}
diff --git a/lib/Resque/JobInterface.php b/src/Resque/Job/JobInterface.php
similarity index 62%
rename from lib/Resque/JobInterface.php
rename to src/Resque/Job/JobInterface.php
index f31281d..ed8b53c 100644
--- a/lib/Resque/JobInterface.php
+++ b/src/Resque/Job/JobInterface.php
@@ -1,6 +1,8 @@
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
-class Resque_Job_Status
+class Status
{
- const STATUS_WAITING = 1;
- const STATUS_RUNNING = 2;
- const STATUS_FAILED = 3;
- const STATUS_COMPLETE = 4;
+ public const STATUS_WAITING = 1;
+ public const STATUS_RUNNING = 2;
+ public const STATUS_FAILED = 3;
+ public const STATUS_COMPLETE = 4;
/**
* @var string The ID of the job this status class refers back to.
@@ -29,10 +31,10 @@ class Resque_Job_Status
/**
* @var array Array of statuses that are considered final/complete.
*/
- private static $completeStatuses = array(
+ private static $completeStatuses = [
self::STATUS_FAILED,
self::STATUS_COMPLETE
- );
+ ];
/**
* Setup a new instance of the job monitor class for the supplied job ID.
@@ -52,12 +54,16 @@ class Resque_Job_Status
*/
public static function create($id)
{
- $statusPacket = array(
+ $statusPacket = [
'status' => self::STATUS_WAITING,
'updated' => time(),
'started' => time(),
+ ];
+ \Resque\Resque::redis()->set(
+ 'job:' . $id . ':status',
+ json_encode($statusPacket),
+ ['ex' => \Resque\Redis::DEFAULT_REDIS_TTL],
);
- Resque::redis()->set('job:' . $id . ':status', json_encode($statusPacket));
}
/**
@@ -66,13 +72,13 @@ class Resque_Job_Status
*
* @return boolean True if the status is being monitored, false if not.
*/
- public function isTracking()
+ public function isTracking(): bool
{
if ($this->isTracking === false) {
return false;
}
- if (!Resque::redis()->exists((string)$this)) {
+ if (!\Resque\Resque::redis()->exists((string)$this)) {
$this->isTracking = false;
return false;
}
@@ -84,7 +90,7 @@ class Resque_Job_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)
{
@@ -96,19 +102,19 @@ class Resque_Job_Status
'status' => $status,
'updated' => time(),
];
- Resque::redis()->set((string)$this, json_encode($statusPacket));
- // Expire the status for completed jobs after 24 hours
- if (in_array($status, self::$completeStatuses)) {
- Resque::redis()->expire((string)$this, 86400);
- }
+ \Resque\Resque::redis()->set(
+ (string)$this,
+ json_encode($statusPacket),
+ ['ex' => \Resque\Redis::DEFAULT_REDIS_TTL],
+ );
}
/**
* Fetch the status for the job being monitored.
*
* @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()
{
@@ -116,7 +122,7 @@ class Resque_Job_Status
return false;
}
- $statusPacket = json_decode(Resque::redis()->get((string)$this), true);
+ $statusPacket = json_decode(\Resque\Resque::redis()->get((string)$this), true);
if (!$statusPacket) {
return false;
}
@@ -126,10 +132,12 @@ class Resque_Job_Status
/**
* Stop tracking the status of a job.
+ *
+ * @return void
*/
- public function stop()
+ public function stop(): void
{
- Resque::redis()->del((string)$this);
+ \Resque\Resque::redis()->del((string)$this);
}
/**
@@ -137,7 +145,7 @@ class Resque_Job_Status
*
* @return string String representation of the current job status class.
*/
- public function __toString()
+ public function __toString(): string
{
return 'job:' . $this->id . ':status';
}
diff --git a/lib/Resque/Log.php b/src/Resque/Log.php
similarity index 50%
rename from lib/Resque/Log.php
rename to src/Resque/Log.php
index fd7d5f5..2608d87 100644
--- a/lib/Resque/Log.php
+++ b/src/Resque/Log.php
@@ -1,20 +1,22 @@
+ * @package Resque
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
-class Resque_Log extends Psr\Log\AbstractLogger
+class Log extends \Psr\Log\AbstractLogger
{
- public $verbose;
+ public $logLevel;
- public function __construct($verbose = false)
+ public function __construct($logLevel = 'warning')
{
- $this->verbose = $verbose;
+ $this->logLevel = strtolower($logLevel);
}
/**
@@ -23,24 +25,34 @@ class Resque_Log extends Psr\Log\AbstractLogger
* @param mixed $level PSR-3 log level constant, or equivalent string
* @param string $message Message to log, may contain a { placeholder }
* @param array $context Variables to replace { placeholder }
+ *
* @return null
*/
- public function log($level, $message, array $context = array())
+ public function log($level, $message, array $context = []): void
{
- if ($this->verbose) {
- fwrite(
- STDOUT,
- '[' . $level . '] [' . strftime('%T %Y-%m-%d') . '] ' . $this->interpolate($message, $context) . PHP_EOL
- );
- return;
- }
+ $logLevels = [
+ 'emergency',
+ 'alert',
+ 'critical',
+ 'error',
+ 'warning',
+ 'notice',
+ 'info',
+ 'debug',
+ ];
- if (!($level === Psr\Log\LogLevel::INFO || $level === Psr\Log\LogLevel::DEBUG)) {
+ /**
+ * Only log things with a higher level than the current log level.
+ * e.g If set as 'alert' will only alert for 'emergency' and 'alert' logs.
+ */
+ if (array_search($level, $logLevels) <= array_search($this->logLevel, $logLevels)) {
fwrite(
STDOUT,
- '[' . $level . '] ' . $this->interpolate($message, $context) . PHP_EOL
+ '[' . $level . '][' . date('Y-m-d H:i:s') . '] ' .
+ $this->interpolate($message, $context) . PHP_EOL
);
}
+ return;
}
/**
@@ -51,10 +63,10 @@ class Resque_Log extends Psr\Log\AbstractLogger
* @param array $context Array of variables to use in message
* @return string
*/
- public function interpolate($message, array $context = array())
+ public function interpolate($message, array $context = [])
{
// build a replacement array with braces around the context keys
- $replace = array();
+ $replace = [];
foreach ($context as $key => $val) {
$replace['{' . $key . '}'] = $val;
}
diff --git a/lib/Resque/Redis.php b/src/Resque/Redis.php
similarity index 75%
rename from lib/Resque/Redis.php
rename to src/Resque/Redis.php
index b68f4f3..5537b55 100644
--- a/lib/Resque/Redis.php
+++ b/src/Resque/Redis.php
@@ -1,17 +1,27 @@
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
-class Resque_Redis
+class Redis
{
+ /**
+ * Redis Client
+ *
+ * @var \Credis_Client
+ */
+ private $driver;
+
/**
* Redis namespace
+ *
* @var string
*/
private static $defaultNamespace = 'resque:';
@@ -19,17 +29,22 @@ class Resque_Redis
/**
* A default host to connect to
*/
- const DEFAULT_HOST = 'localhost';
+ public const DEFAULT_HOST = 'localhost';
/**
* The default Redis port
*/
- const DEFAULT_PORT = 6379;
+ public const DEFAULT_PORT = 6379;
/**
* The default Redis Database number
*/
- const DEFAULT_DATABASE = 0;
+ public const DEFAULT_DATABASE = 0;
+
+ /**
+ * Default Redis TTL (2 days)
+ */
+ public const DEFAULT_REDIS_TTL = 172800;
/**
* @var array List of all commands in Redis that supply a key as their
@@ -82,27 +97,20 @@ class Resque_Redis
'rename',
'rpoplpush'
];
- // sinterstore
- // sunion
- // sunionstore
- // sdiff
- // sdiffstore
- // sinter
- // smove
- // mget
- // msetnx
- // mset
- // renamenx
/**
* Set Redis namespace (prefix) default: resque
+ *
* @param string $namespace
+ *
+ * @return void
*/
- public static function prefix($namespace)
+ public static function prefix(string $namespace): void
{
if (substr($namespace, -1) !== ':' && $namespace != '') {
$namespace .= ':';
}
+
self::$defaultNamespace = $namespace;
}
@@ -110,41 +118,38 @@ class Resque_Redis
* @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
* DSN-supplied value will be used instead and this parameter is ignored.
- * @param object $client Optional Credis_Cluster or Credis_Client instance instantiated by you
- * @throws Resque_RedisException
+ * @param object $client Optional \Credis_Client instance instantiated by you
+ *
+ * @throws \Resque\RedisException
*/
public function __construct($server, $database = null, $client = null)
{
try {
if (is_object($client)) {
- $this->redisConnection = $client;
+ $this->driver = $client;
} else {
+ /** @noinspection PhpUnusedLocalVariableInspection */
list($host, $port, $dsnDatabase, $user, $password, $options) = self::parseDsn($server);
// $user is not used, only $password
$timeout = isset($options['timeout']) ? intval($options['timeout']) : null;
-
- $this->redisConnection = new Redis();
-
- if (!$this->redisConnection->connect($host, $port, $timeout)) {
- throw new RedisException("Connection Failed to Redis!");
- };
-
+ $persistent = isset($options['persistent']) ? $options['persistent'] : '';
+ $maxRetries = isset($options['max_connect_retries']) ? $options['max_connect_retries'] : 0;
+ $this->driver = new \Credis_Client($host, $port, $timeout, $persistent);
+ $this->driver->setMaxConnectRetries($maxRetries);
if ($password) {
- $this->redisConnection->auth($password);
+ $this->driver->auth($password);
}
-
// If we have found a database in our DSN, use it instead of the `$database`
// value passed into the constructor.
if ($dsnDatabase !== false) {
$database = $dsnDatabase;
}
-
- if ($database) {
- $this->redisConnection->select($database);
- }
}
- } catch (RedisException $e) {
- throw new Resque_RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e);
+ if ($database !== null) {
+ $this->driver->select($database);
+ }
+ } catch (\Exception $e) {
+ throw new RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e);
}
}
@@ -159,10 +164,11 @@ class Resque_Redis
* Note: the 'user' part of the DSN is not used.
*
* @param string $dsn A DSN string
+ *
* @return array An array of DSN compotnents, with 'false' values for any unknown components. e.g.
* [host, port, db, user, pass, options]
*/
- public static function parseDsn($dsn)
+ public static function parseDsn($dsn): array
{
if ($dsn == '') {
// Use a sensible default for an empty DNS string
@@ -181,7 +187,7 @@ class Resque_Redis
$parts = parse_url($dsn);
// Check the URI scheme
- $validSchemes = array('redis', 'tcp');
+ $validSchemes = ['redis', 'tcp'];
if (isset($parts['scheme']) && !in_array($parts['scheme'], $validSchemes)) {
throw new \InvalidArgumentException("Invalid DSN. Supported schemes are " . implode(', ', $validSchemes));
}
@@ -207,20 +213,20 @@ class Resque_Redis
$pass = isset($parts['pass']) ? $parts['pass'] : false;
// Convert the query string into an associative array
- $options = array();
+ $options = [];
if (isset($parts['query'])) {
// Parse the query string into an array
parse_str($parts['query'], $options);
}
- return array(
+ return [
$parts['host'],
$port,
$database,
$user,
$pass,
$options,
- );
+ ];
}
/**
@@ -229,14 +235,16 @@ class Resque_Redis
*
* @param string $name The name of the method called.
* @param array $args Array of supplied arguments to the method.
+ *
* @return mixed Return value from Resident::call() based on the command.
+ *
* @throws Resque_RedisException
*/
public function __call($name, $args)
{
if (in_array($name, $this->keyCommands)) {
if (is_array($args[0])) {
- foreach ($args[0] AS $i => $v) {
+ foreach ($args[0] as $i => $v) {
$args[0][$i] = self::$defaultNamespace . $v;
}
} else {
@@ -244,24 +252,19 @@ class Resque_Redis
}
}
try {
- return call_user_func_array(array($this->redisConnection, $name), $args);
- } catch (Exception $e) {
- throw new Resque_RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e);
+ return $this->driver->__call($name, $args);
+ } catch (\Exception $e) {
+ throw new RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e);
}
}
- public static function getPrefix()
+ /**
+ * Returns redis prefix
+ *
+ * @return string
+ */
+ public static function getPrefix(): string
{
return self::$defaultNamespace;
}
-
- public static function removePrefix($string)
- {
- $prefix = self::getPrefix();
-
- if (substr($string, 0, strlen($prefix)) == $prefix) {
- $string = substr($string, strlen($prefix), strlen($string));
- }
- return $string;
- }
}
diff --git a/src/Resque/RedisException.php b/src/Resque/RedisException.php
new file mode 100644
index 0000000..c875887
--- /dev/null
+++ b/src/Resque/RedisException.php
@@ -0,0 +1,15 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php
+ */
+
+class RedisException extends \Exception
+{
+}
diff --git a/lib/Resque.php b/src/Resque/Resque.php
similarity index 83%
rename from lib/Resque.php
rename to src/Resque/Resque.php
index c5d176b..f193e18 100644
--- a/lib/Resque.php
+++ b/src/Resque/Resque.php
@@ -1,18 +1,20 @@
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
class Resque
{
- const VERSION = '1.4';
+ public const VERSION = '2.5.3';
- const DEFAULT_INTERVAL = 5;
+ public const DEFAULT_INTERVAL = 5;
/**
* @var Resque_Redis Instance of Resque_Redis that talks to redis.
@@ -50,18 +52,20 @@ class 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
*/
public static function redis()
{
- if (self::$redis !== null) {
+ if (!is_null(self::$redis)) {
return self::$redis;
}
if (is_callable(self::$redisServer)) {
self::$redis = call_user_func(self::$redisServer, self::$redisDatabase);
} else {
- self::$redis = new Resque_Redis(self::$redisServer, self::$redisDatabase);
+ self::$redis = new \Resque\Redis(self::$redisServer, self::$redisDatabase);
}
return self::$redis;
@@ -88,7 +92,7 @@ class Resque
$pid = pcntl_fork();
if ($pid === -1) {
- throw new RuntimeException('Unable to fork child worker.');
+ throw new \RuntimeException('Unable to fork child worker.');
}
return $pid;
@@ -100,19 +104,23 @@ class Resque
*
* @param string $queue The name of the queue to add the job to.
* @param array $item Job description as an array to be JSON encoded.
+ *
* @return bool
*/
- public static function push($queue, $item)
+ public static function push($queue, $item): bool
{
$encodedItem = json_encode($item);
if ($encodedItem === false) {
return false;
}
+
self::redis()->sadd('queues', $queue);
+
$length = self::redis()->rpush('queue:' . $queue, $encodedItem);
if ($length < 1) {
return false;
}
+
return true;
}
@@ -121,6 +129,7 @@ class Resque
* return it.
*
* @param string $queue The name of the queue to fetch an item from.
+ *
* @return mixed Decoded item from the queue.
*/
public static function pop($queue)
@@ -141,7 +150,7 @@ class Resque
* @param array $items
* @return integer number of deleted items
*/
- public static function dequeue($queue, $items = Array())
+ public static function dequeue($queue, $items = [])
{
if (count($items) > 0) {
return self::removeItems($queue, $items);
@@ -154,13 +163,14 @@ class Resque
* Remove specified queue
*
* @param string $queue The name of the queue to remove.
- * @return integer Number of deleted items
+ *
+ * @return int Number of deleted items
*/
- public static function removeQueue($queue)
+ public static function removeQueue($queue): int
{
$num = self::removeList($queue);
self::redis()->srem('queues', $queue);
- return $num;
+ return intval($num);
}
/**
@@ -169,19 +179,20 @@ class Resque
*
* @param array $queues
* @param int $timeout
- * @return null|array Decoded item from the queue.
+ *
+ * @return array|null|void
*/
public static function blpop(array $queues, $timeout)
{
- $list = array();
- foreach ($queues AS $queue) {
+ $list = [];
+ foreach ($queues as $queue) {
$list[] = 'queue:' . $queue;
}
$item = self::redis()->blpop($list, (int)$timeout);
if (!$item) {
- return;
+ return false;
}
/**
@@ -191,10 +202,10 @@ class Resque
*/
$queue = substr($item[0], strlen(self::redis()->getPrefix() . 'queue:'));
- return array(
+ return [
'queue' => $queue,
'payload' => json_decode($item[1], true)
- );
+ ];
}
/**
@@ -204,9 +215,9 @@ class Resque
*
* @return int The size of the queue.
*/
- public static function size($queue)
+ public static function size($queue): int
{
- return self::redis()->llen('queue:' . $queue);
+ return intval(self::redis()->llen('queue:' . $queue));
}
/**
@@ -222,20 +233,20 @@ class Resque
public static function enqueue($queue, $class, $args = null, $trackStatus = false)
{
$id = Resque::generateJobId();
- $hookParams = array(
+ $hookParams = [
'class' => $class,
'args' => $args,
'queue' => $queue,
'id' => $id,
- );
+ ];
try {
- Resque_Event::trigger('beforeEnqueue', $hookParams);
- } catch (Resque_Job_DontCreate $e) {
+ \Resque\Event::trigger('beforeEnqueue', $hookParams);
+ } catch (\Resque\Job\DontCreate $e) {
return false;
}
- Resque_Job::create($queue, $class, $args, $trackStatus, $id);
- Resque_Event::trigger('afterEnqueue', $hookParams);
+ \Resque\Job\Job::create($queue, $class, $args, $trackStatus, $id);
+ \Resque\Event::trigger('afterEnqueue', $hookParams);
return $id;
}
@@ -244,11 +255,12 @@ class Resque
* Reserve and return the next available job in the specified queue.
*
* @param string $queue Queue to fetch next available job from.
- * @return Resque_Job Instance of Resque_Job to be processed, false if none or error.
+ *
+ * @return \Resque\Job\Job|null
*/
- public static function reserve($queue)
+ public static function reserve($queue): ?\Resque\Job\Job
{
- return Resque_Job::reserve($queue);
+ return \Resque\Job\Job::reserve($queue);
}
/**
@@ -256,13 +268,10 @@ class Resque
*
* @return array Array of queues.
*/
- public static function queues()
+ public static function queues(): array
{
$queues = self::redis()->smembers('queues');
- if (!is_array($queues)) {
- $queues = array();
- }
- return $queues;
+ return is_array($queues) ? $queues : [];
}
/**
@@ -275,9 +284,10 @@ class Resque
*
* @param string $queue The name of the queue
* @param array $items
- * @return integer number of deleted items
+ *
+ * @return int number of deleted items
*/
- private static function removeItems($queue, $items = Array())
+ private static function removeItems($queue, $items = []): int
{
$counter = 0;
$originalQueue = 'queue:' . $queue;
@@ -325,7 +335,9 @@ class Resque
* @params string $string redis result in json
* @params $items
*
- * @return (bool)
+ * @param $string
+ * @param $items
+ * @return bool (bool)
*/
private static function matchItem($string, $items)
{
@@ -340,8 +352,11 @@ class Resque
# class name with args , example: item[0] = ['class' => {'foo' => 1, 'bar' => 2}]
} elseif (is_array($val)) {
$decodedArgs = (array)$decoded['args'][0];
- if ($decoded['class'] == $key &&
- count($decodedArgs) > 0 && count(array_diff($decodedArgs, $val)) == 0) {
+ if (
+ $decoded['class'] == $key
+ && count($decodedArgs) > 0
+ && count(array_diff($decodedArgs, $val)) == 0
+ ) {
return true;
}
# class name with ID, example: item[0] = ['class' => 'id']
@@ -360,7 +375,9 @@ class Resque
* @private
*
* @params string $queue the name of the queue
+ * @param $queue
* @return integer number of deleted items belongs to this list
+ * @throws \Resque\RedisException
*/
private static function removeList($queue)
{
diff --git a/lib/Resque/Stat.php b/src/Resque/Stat.php
similarity index 55%
rename from lib/Resque/Stat.php
rename to src/Resque/Stat.php
index 9855638..6cfa6c1 100644
--- a/lib/Resque/Stat.php
+++ b/src/Resque/Stat.php
@@ -1,22 +1,25 @@
+ * @package Resque
+ * @author Daniel Mason
* @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.
*
* @param string $stat The name of the statistic to get the stats for.
- * @return mixed Value of the statistic.
+ *
+ * @return int Value of the statistic.
*/
- public static function get($stat)
+ public static function get(string $stat): int
{
return (int)Resque::redis()->get('stat:' . $stat);
}
@@ -26,11 +29,24 @@ class Resque_Stat
*
* @param string $stat The name of the statistic to increment.
* @param int $by The amount to increment the statistic by.
- * @return boolean True if successful, false if not.
+ *
+ * @return bool True if successful, false if not.
*/
- public static function incr($stat, $by = 1)
+ public static function incr(string $stat, int $by = 1): bool
{
- return (bool)Resque::redis()->incrby('stat:' . $stat, $by);
+ // Make sure we set a TTL by default
+ $set = Resque::redis()->set(
+ 'stat:' . $stat,
+ $by,
+ ['ex' => Redis::DEFAULT_REDIS_TTL, 'nx'],
+ );
+
+ // If it already exists, return the incrby value
+ if (!$set) {
+ return (bool)Resque::redis()->incrby('stat:' . $stat, $by);
+ }
+
+ return true;
}
/**
@@ -38,9 +54,10 @@ class Resque_Stat
*
* @param string $stat The name of the statistic to decrement.
* @param int $by The amount to decrement the statistic by.
- * @return boolean True if successful, false if not.
+ *
+ * @return bool True if successful, false if not.
*/
- public static function decr($stat, $by = 1)
+ public static function decr(string $stat, int $by = 1): bool
{
return (bool)Resque::redis()->decrby('stat:' . $stat, $by);
}
@@ -49,10 +66,11 @@ class Resque_Stat
* Delete a statistic with the given name.
*
* @param string $stat The name of the statistic to delete.
- * @return boolean True if successful, false if not.
+ *
+ * @return bool True if successful, false if not.
*/
- public static function clear($stat)
+ public static function clear(string $stat): bool
{
return (bool)Resque::redis()->del('stat:' . $stat);
}
-}
\ No newline at end of file
+}
diff --git a/lib/Resque/Worker.php b/src/Resque/Worker.php
similarity index 58%
rename from lib/Resque/Worker.php
rename to src/Resque/Worker.php
index 37f0fad..fc08303 100644
--- a/lib/Resque/Worker.php
+++ b/src/Resque/Worker.php
@@ -1,17 +1,20 @@
+ * @package Resque
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
-class Resque_Worker
+class Worker
{
/**
* @var LoggerInterface Logging object that impliments the PSR-3 LoggerInterface
@@ -21,7 +24,7 @@ class Resque_Worker
/**
* @var array Array of all associated queues for this worker.
*/
- private $queues = array();
+ private $queues = [];
/**
* @var string The hostname of this worker.
@@ -44,7 +47,7 @@ class Resque_Worker
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;
@@ -66,10 +69,10 @@ class Resque_Worker
*/
public function __construct($queues)
{
- $this->logger = new Resque_Log();
+ $this->logger = new Log();
if (!is_array($queues)) {
- $queues = array($queues);
+ $queues = [$queues];
}
$this->queues = $queues;
@@ -80,29 +83,34 @@ class Resque_Worker
/**
* Return all workers known to Resque as instantiated instances.
+ *
* @return array
*/
- public static function all()
+ public static function all(): array
{
$workers = Resque::redis()->smembers('workers');
if (!is_array($workers)) {
- $workers = array();
+ $workers = [];
}
- $instances = array();
+ $instances = [];
foreach ($workers as $workerId) {
$instances[] = self::find($workerId);
}
+
return $instances;
}
/**
* Given a worker ID, check if it is registered/valid.
*
- * @param string $workerId ID of the worker.
- * @return boolean True if the worker exists, false if not.
+ * @param string $workerId ID of the worker
+ *
+ * @return boolean True if the worker exists, false if not
+ *
+ * @throws Resque_RedisException
*/
- public static function exists($workerId)
+ public static function exists($workerId): bool
{
return (bool)Resque::redis()->sismember('workers', $workerId);
}
@@ -110,19 +118,24 @@ class Resque_Worker
/**
* Given a worker ID, find it and return an instantiated worker class for it.
*
- * @param string $workerId The ID of the worker.
- * @return Resque_Worker Instance of the worker. False if the worker does not exist.
+ * @param string $workerId The ID of the worker
+ *
+ * @return Resque_Worker|bool
+ *
+ * @throws Resque_RedisException
*/
public static function find($workerId)
{
- if (!self::exists($workerId) || false === strpos($workerId, ":")) {
+ if (false === strpos($workerId, ":") || !self::exists($workerId)) {
return false;
}
+ /** @noinspection PhpUnusedLocalVariableInspection */
list($hostname, $pid, $queues) = explode(':', $workerId, 3);
$queues = explode(',', $queues);
$worker = new self($queues);
$worker->setId($workerId);
+
return $worker;
}
@@ -130,8 +143,10 @@ class Resque_Worker
* Set the ID of this worker to a given ID string.
*
* @param string $workerId ID for the worker.
+ *
+ * @return void
*/
- public function setId($workerId)
+ public function setId($workerId): void
{
$this->id = $workerId;
}
@@ -143,8 +158,13 @@ class Resque_Worker
* Queues are checked every $interval (seconds) for new jobs.
*
* @param int $interval How often to check for new jobs across the queues.
+ * @param bool $blocking
+ *
+ * @return void
+ *
+ * @throws Resque_RedisException
*/
- public function work($interval = Resque::DEFAULT_INTERVAL, $blocking = false)
+ public function work($interval = Resque::DEFAULT_INTERVAL, $blocking = false): void
{
$this->updateProcLine('Starting');
$this->startup();
@@ -158,8 +178,14 @@ class Resque_Worker
$job = false;
if (!$this->paused) {
if ($blocking === true) {
- $this->logger->log(Psr\Log\LogLevel::INFO, 'Starting blocking with timeout of {interval}', array('interval' => $interval));
- $this->updateProcLine('Waiting for ' . implode(',', $this->queues) . ' with blocking timeout ' . $interval);
+ $this->logger->log(
+ \Psr\Log\LogLevel::INFO,
+ 'Starting blocking with timeout of {interval}',
+ ['interval' => $interval],
+ );
+ $this->updateProcLine(
+ 'Waiting for ' . implode(',', $this->queues) . ' with blocking timeout ' . $interval
+ );
} else {
$this->updateProcLine('Waiting for ' . implode(',', $this->queues) . ' with interval ' . $interval);
}
@@ -175,7 +201,12 @@ class Resque_Worker
if ($blocking === false) {
// If no job was found, we sleep for $interval before continuing and checking again
- $this->logger->log(Psr\Log\LogLevel::INFO, 'Sleeping for {interval}', array('interval' => $interval));
+ $this->logger->log(
+ \Psr\Log\LogLevel::INFO,
+ 'Sleeping for {interval}',
+ ['interval' => $interval],
+ );
+
if ($this->paused) {
$this->updateProcLine('Paused');
} else {
@@ -188,17 +219,20 @@ class Resque_Worker
continue;
}
- $this->logger->log(Psr\Log\LogLevel::NOTICE, 'Starting work on {job}', array('job' => $job));
- Resque_Event::trigger('beforeFork', $job);
+ $this->logger->log(\Psr\Log\LogLevel::NOTICE, 'Starting work on {job}', ['job' => $job]);
+ Event::trigger('beforeFork', $job);
$this->workingOn($job);
$this->child = Resque::fork();
// Forked and we're the child. Run the job.
if ($this->child === 0 || $this->child === false) {
- $status = 'Processing ' . $job->queue . ' since ' . strftime('%F %T');
+ $status = 'Processing ' . $job->queue
+ . ' (' . ($job->payload['class'] ?? '') . ') since '
+ . date('Y-m-d H:i:s');
$this->updateProcLine($status);
- $this->logger->log(Psr\Log\LogLevel::INFO, $status);
+ $this->logger->log(\Psr\Log\LogLevel::INFO, $status);
+ /** @noinspection PhpParamsInspection */
$this->perform($job);
if ($this->child === 0) {
exit(0);
@@ -207,15 +241,15 @@ class Resque_Worker
if ($this->child > 0) {
// Parent process, sit and wait
- $status = 'Forked ' . $this->child . ' at ' . strftime('%F %T');
+ $status = 'Forked ' . $this->child . ' at ' . date('Y-m-d H:i:s');
$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
pcntl_wait($status);
$exitStatus = pcntl_wexitstatus($status);
if ($exitStatus !== 0) {
- $job->fail(new Resque_Job_DirtyExitException(
+ $job->fail(new \Resque\Job\DirtyExitException(
'Job exited with exit code ' . $exitStatus
));
}
@@ -229,49 +263,52 @@ 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
+ *
+ * @return void
*/
- public function perform(Resque_Job $job)
+ public function perform(\Resque\Job\Job $job): void
{
try {
- Resque_Event::trigger('afterFork', $job);
+ Event::trigger('afterFork', $job);
$job->perform();
- } catch (Exception $e) {
- $this->logger->log(Psr\Log\LogLevel::CRITICAL, '{job} has failed {stack}', array('job' => $job, 'stack' => $e));
+ } catch (\Exception $e) {
+ $this->logger->log(\Psr\Log\LogLevel::CRITICAL, '{job} has failed {stack}', ['job' => $job, 'stack' => $e]);
$job->fail($e);
return;
}
- $job->updateStatus(Resque_Job_Status::STATUS_COMPLETE);
- $this->logger->log(Psr\Log\LogLevel::NOTICE, '{job} has finished', array('job' => $job));
+ $job->updateStatus(\Resque\Job\Status::STATUS_COMPLETE);
+ $this->logger->log(\Psr\Log\LogLevel::NOTICE, '{job} has finished', ['job' => $job]);
}
/**
- * @param bool $blocking
- * @param int $timeout
- * @return object|boolean Instance of Resque_Job if a job is found, false if not.
+ * @param bool $blocking
+ * @param int $timeout
+ *
+ * @return object|boolean - Instance of \Resque\Job\Job if a job is found, false if not
*/
public function reserve($blocking = false, $timeout = null)
{
$queues = $this->queues();
if (!is_array($queues)) {
- return;
+ return false;
}
if ($blocking === true) {
- $job = Resque_Job::reserveBlocking($queues, $timeout);
- if ($job) {
- $this->logger->log(Psr\Log\LogLevel::INFO, 'Found job on {queue}', array('queue' => $job->queue));
+ $job = \Resque\Job\Job::reserveBlocking($queues, $timeout);
+ if (!is_null($job)) {
+ $this->logger->log(\Psr\Log\LogLevel::INFO, 'Found job on {queue}', ['queue' => $job->queue]);
return $job;
}
} else {
foreach ($queues as $queue) {
- $this->logger->log(Psr\Log\LogLevel::INFO, 'Checking {queue} for jobs', array('queue' => $queue));
- $job = Resque_Job::reserve($queue);
- if ($job) {
- $this->logger->log(Psr\Log\LogLevel::INFO, 'Found job on {queue}', array('queue' => $job->queue));
+ $this->logger->log(\Psr\Log\LogLevel::INFO, 'Checking {queue} for jobs', ['queue' => $queue]);
+ $job = \Resque\Job\Job::reserve($queue);
+ if (!is_null($job)) {
+ $this->logger->log(\Psr\Log\LogLevel::INFO, 'Found job on {queue}', ['queue' => $job->queue]);
return $job;
}
}
@@ -282,16 +319,17 @@ class Resque_Worker
/**
* Return an array containing all of the queues that this worker should use
- * when searching for jobs.
+ * when searching for jobs
*
* If * is found in the list of queues, every queue will be searched in
- * alphabetic order. (@see $fetch)
+ * alphabetic order. (@param boolean $fetch If true, and the queue is set to *, will fetch
+ * all queue names from redis
*
- * @param boolean $fetch If true, and the queue is set to *, will fetch
- * all queue names from redis.
- * @return array Array of associated queues.
+ * @param boolean $fetch
+ *
+ * @return array Array of associated queues
*/
- public function queues($fetch = true)
+ public function queues(bool $fetch = true): array
{
if (!in_array('*', $this->queues) || $fetch == false) {
return $this->queues;
@@ -299,17 +337,20 @@ class Resque_Worker
$queues = Resque::queues();
sort($queues);
+
return $queues;
}
/**
- * Perform necessary actions to start a worker.
+ * Perform necessary actions to start a worker
+ *
+ * @return void
*/
- private function startup()
+ private function startup(): void
{
$this->registerSigHandlers();
$this->pruneDeadWorkers();
- Resque_Event::trigger('beforeFirstFork', $this);
+ Event::trigger('beforeFirstFork', $this);
$this->registerWorker();
}
@@ -318,14 +359,16 @@ class Resque_Worker
* the name of the currently running process to indicate the current state
* of a worker.
*
- * @param string $status The updated process title.
+ * @param string $status The updated process title
+ *
+ * @return void
*/
- private function updateProcLine($status)
+ private function updateProcLine($status): void
{
$processTitle = 'resque-' . Resque::VERSION . ': ' . $status;
if (function_exists('cli_set_process_title') && PHP_OS !== 'Darwin') {
cli_set_process_title($processTitle);
- } else if (function_exists('setproctitle')) {
+ } elseif (function_exists('setproctitle')) {
setproctitle($processTitle);
}
}
@@ -337,56 +380,66 @@ class Resque_Worker
* INT: Shutdown immediately and stop processing jobs.
* QUIT: Shutdown after the current job finishes processing.
* USR1: Kill the forked child immediately and continue processing jobs.
+ *
+ * @return void
*/
- private function registerSigHandlers()
+ private function registerSigHandlers(): void
{
if (!function_exists('pcntl_signal')) {
return;
}
- pcntl_signal(SIGTERM, array($this, 'shutDownNow'));
- pcntl_signal(SIGINT, array($this, 'shutDownNow'));
- pcntl_signal(SIGQUIT, array($this, 'shutdown'));
- pcntl_signal(SIGUSR1, array($this, 'killChild'));
- pcntl_signal(SIGUSR2, array($this, 'pauseProcessing'));
- pcntl_signal(SIGCONT, array($this, 'unPauseProcessing'));
- $this->logger->log(Psr\Log\LogLevel::DEBUG, 'Registered signals');
+ pcntl_signal(SIGTERM, [$this, 'shutDownNow']);
+ pcntl_signal(SIGINT, [$this, 'shutDownNow']);
+ pcntl_signal(SIGQUIT, [$this, 'shutdown']);
+ pcntl_signal(SIGUSR1, [$this, 'killChild']);
+ pcntl_signal(SIGUSR2, [$this, 'pauseProcessing']);
+ pcntl_signal(SIGCONT, [$this, 'unPauseProcessing']);
+ $this->logger->log(\Psr\Log\LogLevel::DEBUG, 'Registered signals');
}
/**
- * Signal handler callback for USR2, pauses processing of new jobs.
+ * Signal handler callback for USR2, pauses processing of new jobs
+ *
+ * @return void
*/
- public function pauseProcessing()
+ public function pauseProcessing(): void
{
- $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;
}
/**
* Signal handler callback for CONT, resumes worker allowing it to pick
* up new jobs.
+ *
+ * @return void
*/
- public function unPauseProcessing()
+ public function unPauseProcessing(): void
{
- $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;
}
/**
* Schedule a worker for shutdown. Will finish processing the current job
* and when the timeout interval is reached, the worker will shut down.
+ *
+ * @return void
*/
- public function shutdown()
+ public function shutdown(): void
{
$this->shutdown = true;
- $this->logger->log(Psr\Log\LogLevel::NOTICE, 'Shutting down');
+ $this->logger->log(\Psr\Log\LogLevel::NOTICE, 'Shutting down');
}
/**
* Force an immediate shutdown of the worker, killing any child jobs
* currently running.
+ *
+ * @return void
*/
- public function shutdownNow()
+ public function shutdownNow(): void
{
$this->shutdown();
$this->killChild();
@@ -395,21 +448,27 @@ class Resque_Worker
/**
* Kill a forked child job immediately. The job it is processing will not
* be completed.
+ *
+ * @return void
*/
- public function killChild()
+ public function killChild(): void
{
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;
}
- $this->logger->log(Psr\Log\LogLevel::INFO, 'Killing child at {child}', array('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) {
- $this->logger->log(Psr\Log\LogLevel::DEBUG, 'Child {child} found, killing.', array('child' => $this->child));
+ $this->logger->log(\Psr\Log\LogLevel::DEBUG, 'Child {child} found, killing.', ['child' => $this->child]);
posix_kill($this->child, SIGKILL);
$this->child = null;
} else {
- $this->logger->log(Psr\Log\LogLevel::INFO, 'Child {child} not found, restarting.', array('child' => $this->child));
+ $this->logger->log(
+ \Psr\Log\LogLevel::INFO,
+ 'Child {child} not found, restarting.',
+ ['child' => $this->child],
+ );
$this->shutdown();
}
}
@@ -421,8 +480,10 @@ class Resque_Worker
* This is a form of garbage collection to handle cases where the
* server may have been killed and the Resque workers did not die gracefully
* and therefore leave state information in Redis.
+ *
+ * @return void
*/
- public function pruneDeadWorkers()
+ public function pruneDeadWorkers(): void
{
$workerPids = $this->workerPids();
$workers = self::all();
@@ -432,7 +493,11 @@ class Resque_Worker
if ($host != $this->hostname || in_array($pid, $workerPids) || $pid == getmypid()) {
continue;
}
- $this->logger->log(Psr\Log\LogLevel::INFO, 'Pruning dead worker: {worker}', array('worker' => (string)$worker));
+ $this->logger->log(
+ \Psr\Log\LogLevel::INFO,
+ 'Pruning dead worker: {worker}',
+ ['worker' => (string)$worker],
+ );
$worker->unregisterWorker();
}
}
@@ -444,9 +509,9 @@ class Resque_Worker
*
* @return array Array of Resque worker process IDs.
*/
- public function workerPids()
+ public function workerPids(): array
{
- $pids = array();
+ $pids = [];
exec('ps -A -o pid,command | grep [r]esque', $cmdOutput);
foreach ($cmdOutput as $line) {
list($pids[],) = explode(' ', trim($line), 2);
@@ -456,102 +521,122 @@ class Resque_Worker
/**
* Register this worker in Redis.
+ * 48 hour TTL so we don't pollute the redis db on server termination.
+ *
+ * @return void
*/
- public function registerWorker()
+ public function registerWorker(): void
{
Resque::redis()->sadd('workers', (string)$this);
- Resque::redis()->set('worker:' . (string)$this . ':started', strftime('%a %b %d %H:%M:%S %Z %Y'));
+ Resque::redis()->set(
+ 'worker:' . (string)$this . ':started',
+ date('D M d H:i:s T Y'),
+ ['ex' => Redis::DEFAULT_REDIS_TTL],
+ );
}
/**
* Unregister this worker in Redis. (shutdown etc)
+ *
+ * @return void
*/
- public function unregisterWorker()
+ public function unregisterWorker(): void
{
if (is_object($this->currentJob)) {
- $this->currentJob->fail(new Resque_Job_DirtyExitException);
+ $this->currentJob->fail(new \Resque\Job\DirtyExitException());
}
$id = (string)$this;
Resque::redis()->srem('workers', $id);
Resque::redis()->del('worker:' . $id);
Resque::redis()->del('worker:' . $id . ':started');
- Resque_Stat::clear('processed:' . $id);
- Resque_Stat::clear('failed:' . $id);
+ Stat::clear('processed:' . $id);
+ Stat::clear('failed:' . $id);
}
/**
- * Tell Redis which job we're currently working on.
+ * Tell Redis which job we're currently working on
*
- * @param object $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
+ *
+ * @return void
+ *
+ * @throws Resque_RedisException
*/
- public function workingOn(Resque_Job $job)
+ public function workingOn(\Resque\Job\Job $job): void
{
$job->worker = $this;
$this->currentJob = $job;
- $job->updateStatus(Resque_Job_Status::STATUS_RUNNING);
- $data = json_encode(array(
+ $job->updateStatus(\Resque\Job\Status::STATUS_RUNNING);
+ $data = json_encode([
'queue' => $job->queue,
- 'run_at' => strftime('%a %b %d %H:%M:%S %Z %Y'),
+ 'run_at' => date('D M d H:i:s T Y'),
'payload' => $job->payload
- ));
- Resque::redis()->set('worker:' . $job->worker, $data);
+ ]);
+
+ Resque::redis()->set(
+ 'worker:' . $job->worker,
+ $data,
+ ['ex' => Redis::DEFAULT_REDIS_TTL],
+ );
}
/**
* Notify Redis that we've finished working on a job, clearing the working
- * state and incrementing the job stats.
+ * state and incrementing the job stats
+ *
+ * @return void
*/
- public function doneWorking()
+ public function doneWorking(): void
{
$this->currentJob = null;
- Resque_Stat::incr('processed');
- Resque_Stat::incr('processed:' . (string)$this);
+ Stat::incr('processed');
+ Stat::incr('processed:' . (string)$this);
Resque::redis()->del('worker:' . (string)$this);
}
/**
- * Generate a string representation of this worker.
+ * Generate a string representation of this worker
*
- * @return string String identifier for this worker instance.
+ * @return string String identifier for this worker instance
*/
- public function __toString()
+ public function __toString(): string
{
- return $this->id;
+ return (string) $this->id;
}
/**
- * Return an object describing the job this worker is currently working on.
+ * Return an object describing the job this worker is currently working on
*
- * @return object Object with details of current job.
+ * @return array Array with details of current job
*/
- public function job()
+ public function job(): array
{
$job = Resque::redis()->get('worker:' . $this);
- if (!$job) {
- return array();
- } else {
- return json_decode($job, true);
- }
+
+ return $job ? json_decode($job, true) : [];
}
/**
- * Get a statistic belonging to this worker.
+ * Get a statistic belonging to this worker
*
* @param string $stat Statistic to fetch.
+ *
* @return int Statistic value.
*/
- public function getStat($stat)
+ public function getStat(string $stat): int
{
- return Resque_Stat::get($stat . ':' . $this);
+ return \Resque\Stat::get($stat . ':' . $this);
}
/**
* Inject the logging object into the worker
*
- * @param Psr\Log\LoggerInterface $logger
+ * @param \Psr\Log\LoggerInterface $logger
+ *
+ * @return void
*/
- public function setLogger(Psr\Log\LoggerInterface $logger)
+ public function setLogger(\Psr\Log\LoggerInterface $logger): void
{
$this->logger = $logger;
}
diff --git a/test/Resque/Tests/JobStatusTest.php b/test/Resque/Tests/JobStatusTest.php
deleted file mode 100644
index 36729dd..0000000
--- a/test/Resque/Tests/JobStatusTest.php
+++ /dev/null
@@ -1,109 +0,0 @@
-
- * @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()
- {
- 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()
- {
- $token = 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());
- }
-}
\ No newline at end of file
diff --git a/test/Resque/Tests/JobTest.php b/test/Resque/Tests/JobTest.php
deleted file mode 100644
index 18d9674..0000000
--- a/test/Resque/Tests/JobTest.php
+++ /dev/null
@@ -1,417 +0,0 @@
-
- * @license http://www.opensource.org/licenses/mit-license.php
- */
-
-class Resque_Tests_JobTest extends Resque_Tests_TestCase
-{
- protected $worker;
-
- public function setUp()
- {
- 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()
- {
- $args = new stdClass;
- $args->test = 'somevalue';
- Resque::enqueue('jobs', 'Test_Job', $args);
- }
-
- public function testQueuedJobReturnsExactSamePassedInArguments()
- {
- $args = array(
- 'int' => 123,
- 'numArray' => array(
- 1,
- 2,
- ),
- 'assocArray' => array(
- '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 = array(
- 'int' => 123,
- 'numArray' => array(
- 1,
- 2,
- ),
- 'assocArray' => array(
- '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 = array(
- '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()
- {
- Resque::enqueue('jobs', 'Test_Job_Without_Perform_Method');
- $job = $this->worker->reserve();
- $job->worker = $this->worker;
- $job->perform();
- }
-
- /**
- * @expectedException Resque_Exception
- */
- public function testInvalidJobThrowsException()
- {
- Resque::enqueue('jobs', 'Invalid_Job');
- $job = $this->worker->reserve();
- $job->worker = $this->worker;
- $job->perform();
- }
-
- public function testJobWithSetUpCallbackFiresSetUp()
- {
- $payload = array(
- 'class' => 'Test_Job_With_SetUp',
- 'args' => array(
- 'somevar',
- 'somevar2',
- ),
- );
- $job = new Resque_Job('jobs', $payload);
- $job->perform();
-
- $this->assertTrue(Test_Job_With_SetUp::$called);
- }
-
- public function testJobWithTearDownCallbackFiresTearDown()
- {
- $payload = array(
- 'class' => 'Test_Job_With_TearDown',
- 'args' => array(
- 'somevar',
- 'somevar2',
- ),
- );
- $job = new Resque_Job('jobs', $payload);
- $job->perform();
-
- $this->assertTrue(Test_Job_With_TearDown::$called);
- }
-
- public function testNamespaceNaming()
- {
- $fixture = array(
- array('test' => 'more:than:one:with:', 'assertValue' => 'more:than:one:with:'),
- array('test' => 'more:than:one:without', 'assertValue' => 'more:than:one:without:'),
- array('test' => 'resque', 'assertValue' => 'resque:'),
- array('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 = array('another_value');
- Resque::enqueue($queue, 'Test_Job_With_TearDown', $payload);
-
- $this->assertEquals(Resque::queues(), array('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 = array('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 = array('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 = array('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 = array('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 = array('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 = array('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');
- $qid = Resque::enqueue($queue, 'Test_Job_Dequeue');
- $this->assertEquals(Resque::size($queue), 2);
- $test = array('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, "Dequeue one failed!");
-
- // THEN
- $this->assertEquals($removedItems, 2);
- $this->assertEquals(Resque::size($queue), 1);
- $item = Resque::pop($queue);
- $this->assertInternalType('array', $item['args']);
- $this->assertEquals(10, $item['args'][0]['bar'], 'Wrong items were dequeued from queue!');
- }
-
- public function testDequeueItemWithUnorderedArg()
- {
- $queue = 'jobs';
- $arg = array('foo' => 1, 'bar' => 2);
- $arg2 = array('bar' => 2, 'foo' => 1);
- Resque::enqueue($queue, 'Test_Job_Dequeue');
- Resque::enqueue($queue, 'Test_Job_Dequeue', $arg);
- $this->assertEquals(Resque::size($queue), 2);
- $test = array('Test_Job_Dequeue' => $arg2);
- $this->assertEquals(Resque::dequeue($queue, $test), 1);
- $this->assertEquals(Resque::size($queue), 1);
- }
-
- public function testDequeueItemWithiWrongArg()
- {
- $queue = 'jobs';
- $arg = array('foo' => 1, 'bar' => 2);
- $arg2 = array('foo' => 2, 'bar' => 3);
- Resque::enqueue($queue, 'Test_Job_Dequeue');
- Resque::enqueue($queue, 'Test_Job_Dequeue', $arg);
- $this->assertEquals(Resque::size($queue), 2);
- $test = array('Test_Job_Dequeue' => $arg2);
- $this->assertEquals(Resque::dequeue($queue, $test), 0);
- $this->assertEquals(Resque::size($queue), 2);
- }
-
- public function testUseDefaultFactoryToGetJobInstance()
- {
- $payload = array(
- '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 = array(
- 'class' => 'Some_Job_Class',
- 'args' => array(array())
- );
- $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();
- }
-}
diff --git a/test/Resque/Tests/TestCase.php b/test/Resque/Tests/TestCase.php
deleted file mode 100644
index 478a27c..0000000
--- a/test/Resque/Tests/TestCase.php
+++ /dev/null
@@ -1,30 +0,0 @@
-
- * @license http://www.opensource.org/licenses/mit-license.php
- */
-
-class Resque_Tests_TestCase extends PHPUnit\Framework\TestCase
-{
- protected $resque;
- protected $redis;
-
- public static function setUpBeforeClass()
- {
- date_default_timezone_set('UTC');
- }
-
- public function setUp()
- {
- // Setup redis connection on DB 9 for testing.
- $this->redis = new Redis();
- $this->redis->connect('localhost');
-
- Resque::setBackend('localhost');
- $this->redis->flushAll();
- }
-}
diff --git a/test/bootstrap.php b/test/bootstrap.php
deleted file mode 100644
index a92611c..0000000
--- a/test/bootstrap.php
+++ /dev/null
@@ -1,150 +0,0 @@
-
- * @license http://www.opensource.org/licenses/mit-license.php
- */
-
-$loader = require __DIR__ . '/../vendor/autoload.php';
-$loader->add('Resque_Tests', __DIR__);
-
-define('TEST_MISC', realpath(__DIR__ . '/misc/'));
-define('REDIS_CONF', TEST_MISC . '/redis.conf');
-
-// Attempt to start our own redis instance for tesitng.
-exec('which redis-server', $output, $returnVar);
-if ($returnVar != 0) {
- echo "Cannot find redis-server in path. Please make sure redis is installed.\n";
- exit(1);
-}
-
-exec('cd ' . TEST_MISC . '; redis-server ' . REDIS_CONF, $output, $returnVar);
-usleep(500000);
-if ($returnVar != 0) {
- echo "Cannot start redis-server.\n";
- exit(1);
-
-}
-
-// Get redis port from conf
-$config = file_get_contents(REDIS_CONF);
-if (!preg_match('#^\s*port\s+([0-9]+)#m', $config, $matches)) {
- echo "Could not determine redis port from redis.conf";
- exit(1);
-}
-
-Resque::setBackend('localhost:' . $matches[1]);
-
-// Shutdown
-function killRedis($pid)
-{
- if (getmypid() !== $pid) {
- return; // don't kill from a forked worker
- }
- $config = file_get_contents(REDIS_CONF);
- if (!preg_match('#^\s*pidfile\s+([^\s]+)#m', $config, $matches)) {
- return;
- }
-
- $pidFile = TEST_MISC . '/' . $matches[1];
- if (file_exists($pidFile)) {
- $pid = trim(file_get_contents($pidFile));
- posix_kill((int)$pid, 9);
-
- if (is_file($pidFile)) {
- unlink($pidFile);
- }
- }
-
- // Remove the redis database
- if (!preg_match('#^\s*dir\s+([^\s]+)#m', $config, $matches)) {
- return;
- }
- $dir = $matches[1];
-
- if (!preg_match('#^\s*dbfilename\s+([^\s]+)#m', $config, $matches)) {
- return;
- }
-
- $filename = TEST_MISC . '/' . $dir . '/' . $matches[1];
- if (is_file($filename)) {
- unlink($filename);
- }
-}
-
-register_shutdown_function('killRedis', getmypid());
-
-if (function_exists('pcntl_signal')) {
- // Override INT and TERM signals, so they do a clean shutdown and also
- // clean up redis-server as well.
- function sigint()
- {
- exit;
- }
-
- pcntl_signal(SIGINT, 'sigint');
- pcntl_signal(SIGTERM, 'sigint');
-}
-
-class Test_Job
-{
- public static $called = false;
-
- public function perform()
- {
- self::$called = true;
- }
-}
-
-class Failing_Job_Exception extends Exception
-{
-
-}
-
-class Failing_Job
-{
- public function perform()
- {
- throw new Failing_Job_Exception('Message!');
- }
-}
-
-class Test_Job_Without_Perform_Method
-{
-
-}
-
-class Test_Job_With_SetUp
-{
- public static $called = false;
- public $args = false;
-
- public function setUp()
- {
- self::$called = true;
- }
-
- public function perform()
- {
-
- }
-}
-
-
-class Test_Job_With_TearDown
-{
- public static $called = false;
- public $args = false;
-
- public function perform()
- {
-
- }
-
- public function tearDown()
- {
- self::$called = true;
- }
-}
\ No newline at end of file
diff --git a/test/misc/redis.conf b/test/misc/redis.conf
deleted file mode 100644
index 971f66e..0000000
--- a/test/misc/redis.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-daemonize yes
-pidfile ./redis.pid
-port 6379
-bind 127.0.0.1
-timeout 300
-dbfilename dump.rdb
-dir ./
-loglevel debug
\ No newline at end of file
diff --git a/test/Resque/Tests/EventTest.php b/tests/Resque/Tests/EventTest.php
similarity index 63%
rename from test/Resque/Tests/EventTest.php
rename to tests/Resque/Tests/EventTest.php
index 941cfbd..9e9346f 100644
--- a/test/Resque/Tests/EventTest.php
+++ b/tests/Resque/Tests/EventTest.php
@@ -1,62 +1,66 @@
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
-class Resque_Tests_EventTest extends Resque_Tests_TestCase
+class EventTest extends TestCase
{
- private $callbacksHit = array();
+ private $callbacksHit = [];
private $worker;
- public function setUp()
+ public function setUp(): void
{
- Test_Job::$called = false;
+ TestJob::$called = false;
// Register a worker to test with
- $this->worker = new Resque_Worker('jobs');
- $this->worker->setLogger(new Resque_Log());
+ $this->worker = new \Resque\Worker('jobs');
+ $this->worker->setLogger(new \Resque\Log());
$this->worker->registerWorker();
}
- public function tearDown()
+ public function tearDown(): void
{
- Resque_Event::clearListeners();
- $this->callbacksHit = array();
+ \Resque\Event::clearListeners();
+ $this->callbacksHit = [];
}
public function getEventTestJob()
{
- $payload = array(
- 'class' => 'Test_Job',
- 'args' => array(
- array('somevar'),
- ),
- );
- $job = new Resque_Job('jobs', $payload);
+ $payload = [
+ 'class' => '\Resque\Test\TestJob',
+ 'args' => [
+ ['somevar'],
+ ],
+ ];
+ $job = new \Resque\Job\Job('jobs', $payload);
$job->worker = $this->worker;
return $job;
}
public function eventCallbackProvider()
{
- return array(
- array('beforePerform', 'beforePerformEventCallback'),
- array('afterPerform', 'afterPerformEventCallback'),
- array('afterFork', 'afterForkEventCallback'),
- );
+ return [
+ ['beforePerform', 'beforePerformEventCallback'],
+ ['afterPerform', 'afterPerformEventCallback'],
+ ['afterFork', 'afterForkEventCallback'],
+ ];
}
/**
* @dataProvider eventCallbackProvider
+ * @param $event
+ * @param $callback
*/
public function testEventCallbacksFire($event, $callback)
{
- Resque_Event::listen($event, array($this, $callback));
+ \Resque\Event::listen($event, [$this, $callback]);
$job = $this->getEventTestJob();
$this->worker->perform($job);
@@ -70,11 +74,11 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
$event = 'beforeFork';
$callback = 'beforeForkEventCallback';
- Resque_Event::listen($event, array($this, $callback));
- Resque::enqueue('jobs', 'Test_Job', array(
+ \Resque\Event::listen($event, [$this, $callback]);
+ \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', [
'somevar'
- ));
- $job = $this->getEventTestJob();
+ ]);
+ $this->getEventTestJob();
$this->worker->work(0);
$this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called');
}
@@ -84,32 +88,32 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
$event = 'beforeEnqueue';
$callback = 'beforeEnqueueEventCallback';
- Resque_Event::listen($event, array($this, $callback));
- Resque::enqueue('jobs', 'Test_Job', array(
+ \Resque\Event::listen($event, [$this, $callback]);
+ \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', [
'somevar'
- ));
+ ]);
$this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called');
}
public function testBeforePerformEventCanStopWork()
{
$callback = 'beforePerformEventDontPerformCallback';
- Resque_Event::listen('beforePerform', array($this, $callback));
+ \Resque\Event::listen('beforePerform', [$this, $callback]);
$job = $this->getEventTestJob();
$this->assertFalse($job->perform());
$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()
{
$callback = 'beforeEnqueueEventDontCreateCallback';
- Resque_Event::listen('beforeEnqueue', array($this, $callback));
- Resque_Event::listen('afterEnqueue', array($this, 'afterEnqueueEventCallback'));
+ \Resque\Event::listen('beforeEnqueue', [$this, $callback]);
+ \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->assertNotContains('afterEnqueueEventCallback', $this->callbacksHit, 'afterEnqueue was still called, even though it should not have been');
$this->assertFalse($result);
@@ -120,10 +124,10 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
$callback = 'afterEnqueueEventCallback';
$event = 'afterEnqueue';
- Resque_Event::listen($event, array($this, $callback));
- Resque::enqueue('jobs', 'Test_Job', array(
+ \Resque\Event::listen($event, [$this, $callback]);
+ \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', [
'somevar'
- ));
+ ]);
$this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called');
}
@@ -132,8 +136,8 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
$callback = 'beforePerformEventCallback';
$event = 'beforePerform';
- Resque_Event::listen($event, array($this, $callback));
- Resque_Event::stopListening($event, array($this, $callback));
+ \Resque\Event::listen($event, [$this, $callback]);
+ \Resque\Event::stopListening($event, [$this, $callback]);
$job = $this->getEventTestJob();
$this->worker->perform($job);
@@ -144,23 +148,23 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
);
}
- public function beforePerformEventDontPerformCallback($instance)
+ public function beforePerformEventDontPerformCallback()
{
$this->callbacksHit[] = __FUNCTION__;
- throw new Resque_Job_DontPerform();
+ throw new \Resque\Job\DontPerform();
}
- public function beforeEnqueueEventDontCreateCallback($queue, $class, $args, $track = false)
+ public function beforeEnqueueEventDontCreateCallback()
{
$this->callbacksHit[] = __FUNCTION__;
- throw new Resque_Job_DontCreate();
+ throw new \Resque\Job\DontCreate();
}
public function assertValidEventCallback($function, $job)
{
$this->callbacksHit[] = $function;
- if (!$job instanceof Resque_Job) {
- $this->fail('Callback job argument is not an instance of Resque_Job');
+ if (!$job instanceof \Resque\Job\Job) {
+ $this->fail('Callback job argument is not an instance of \Resque\Job\Job');
}
$args = $job->getArguments();
$this->assertEquals($args[0], 'somevar');
@@ -169,10 +173,10 @@ class Resque_Tests_EventTest extends Resque_Tests_TestCase
public function afterEnqueueEventCallback($class, $args)
{
$this->callbacksHit[] = __FUNCTION__;
- $this->assertEquals('Test_Job', $class);
- $this->assertEquals(array(
+ $this->assertEquals('\Resque\Test\TestJob', $class);
+ $this->assertEquals([
'somevar',
- ), $args);
+ ], $args);
}
public function beforeEnqueueEventCallback($job)
diff --git a/tests/Resque/Tests/JobStatusTest.php b/tests/Resque/Tests/JobStatusTest.php
new file mode 100644
index 0000000..a7185cc
--- /dev/null
+++ b/tests/Resque/Tests/JobStatusTest.php
@@ -0,0 +1,110 @@
+
+ * @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());
+ }
+}
\ No newline at end of file
diff --git a/tests/Resque/Tests/JobTest.php b/tests/Resque/Tests/JobTest.php
new file mode 100644
index 0000000..f6c261f
--- /dev/null
+++ b/tests/Resque/Tests/JobTest.php
@@ -0,0 +1,431 @@
+
+ * @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 (is_null($job)) {
+ $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->assertNull(\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
+{
+ public static $called = false;
+ public $args = false;
+ public $queue;
+ public $job;
+
+ /**
+ * @return bool
+ */
+ public function perform()
+ {
+ return true;
+ }
+}
+
+class Some_Stub_Factory implements \Resque\Job\FactoryInterface
+{
+ public static $called = false;
+ public $args = false;
+ public $queue;
+ public $job;
+
+ /**
+ * @param $className
+ * @param array $args
+ * @param $queue
+ * @return \Resque\Job\JobInterface
+ */
+ public function create($className, $args, $queue)
+ {
+ return new SomeJobClass();
+ }
+}
diff --git a/test/Resque/Tests/LogTest.php b/tests/Resque/Tests/LogTest.php
similarity index 58%
rename from test/Resque/Tests/LogTest.php
rename to tests/Resque/Tests/LogTest.php
index 05310eb..18109b9 100644
--- a/test/Resque/Tests/LogTest.php
+++ b/tests/Resque/Tests/LogTest.php
@@ -1,19 +1,21 @@
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
-class Resque_Tests_LogTest extends Resque_Tests_TestCase
+class LogTest extends TestCase
{
public function testLogInterpolate()
{
- $logger = new Resque_Log();
- $actual = $logger->interpolate('string {replace}', array('replace' => 'value'));
+ $logger = new \Resque\Log();
+ $actual = $logger->interpolate('string {replace}', ['replace' => 'value']);
$expected = 'string value';
$this->assertEquals($expected, $actual);
@@ -21,10 +23,10 @@ class Resque_Tests_LogTest extends Resque_Tests_TestCase
public function testLogInterpolateMutiple()
{
- $logger = new Resque_Log();
+ $logger = new \Resque\Log();
$actual = $logger->interpolate(
'string {replace1} {replace2}',
- array('replace1' => 'value1', 'replace2' => 'value2')
+ ['replace1' => 'value1', 'replace2' => 'value2']
);
$expected = 'string value1 value2';
diff --git a/test/Resque/Tests/RedisTest.php b/tests/Resque/Tests/RedisTest.php
similarity index 86%
rename from test/Resque/Tests/RedisTest.php
rename to tests/Resque/Tests/RedisTest.php
index 2caffc2..b834f93 100644
--- a/test/Resque/Tests/RedisTest.php
+++ b/tests/Resque/Tests/RedisTest.php
@@ -1,21 +1,25 @@
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
-class Resque_Tests_RedisTest extends Resque_Tests_TestCase
+class RedisTest extends TestCase
{
- /**
- * @expectedException Test basic redis functionality.
- */
public function testRedisGetSet()
{
- $this->redis->set("testKey", 24);
+ $this->redis->set(
+ 'testKey',
+ 24,
+ ['ex' => \Resque\Redis::DEFAULT_REDIS_TTL],
+ );
+
$val = $this->redis->get("testKey");
$this->assertEquals(24, $val);
}
@@ -31,14 +35,14 @@ class Resque_Tests_RedisTest extends Resque_Tests_TestCase
// Input , Expected output
['', [
'localhost',
- Resque_Redis::DEFAULT_PORT,
+ \Resque\Redis::DEFAULT_PORT,
false,
false, false,
[],
]],
['localhost', [
'localhost',
- Resque_Redis::DEFAULT_PORT,
+ \Resque\Redis::DEFAULT_PORT,
false,
false, false,
[],
@@ -59,14 +63,14 @@ class Resque_Tests_RedisTest extends Resque_Tests_TestCase
]],
['redis://foobar', [
'foobar',
- Resque_Redis::DEFAULT_PORT,
+ \Resque\Redis::DEFAULT_PORT,
false,
false, false,
[],
]],
['redis://foobar/', [
'foobar',
- Resque_Redis::DEFAULT_PORT,
+ \Resque\Redis::DEFAULT_PORT,
false,
false, false,
[],
@@ -173,20 +177,25 @@ class Resque_Tests_RedisTest extends Resque_Tests_TestCase
/**
* @dataProvider validDsnStringProvider
+ * @param $dsn
+ * @param $expected
*/
public function testParsingValidDsnString($dsn, $expected)
{
- $result = Resque_Redis::parseDsn($dsn);
+ $result = \Resque\Redis::parseDsn($dsn);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider bogusDsnStringProvider
- * @expectedException InvalidArgumentException
+ *
+ * @expectedException \InvalidArgumentException
+ *
+ * @param $dsn
*/
public function testParsingBogusDsnStringThrowsException($dsn)
{
- // The next line should throw an InvalidArgumentException
- Resque_Redis::parseDsn($dsn);
+ $this->expectException(\InvalidArgumentException::class);
+ \Resque\Redis::parseDsn($dsn);
}
}
\ No newline at end of file
diff --git a/test/Resque/Tests/StatTest.php b/tests/Resque/Tests/StatTest.php
similarity index 54%
rename from test/Resque/Tests/StatTest.php
rename to tests/Resque/Tests/StatTest.php
index 121aaff..3b04c3d 100644
--- a/test/Resque/Tests/StatTest.php
+++ b/tests/Resque/Tests/StatTest.php
@@ -1,51 +1,53 @@
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
-class Resque_Tests_StatTest extends Resque_Tests_TestCase
+class StatTest extends TestCase
{
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'));
}
public function testStatCanBeIncrementedByX()
{
- Resque_Stat::incr('test_incrX', 10);
- Resque_Stat::incr('test_incrX', 11);
+ \Resque\Stat::incr('test_incrX', 10);
+ \Resque\Stat::incr('test_incrX', 11);
$this->assertEquals(21, $this->redis->get('resque:stat:test_incrX'));
}
public function testStatCanBeDecremented()
{
- Resque_Stat::incr('test_decr', 22);
- Resque_Stat::decr('test_decr');
+ \Resque\Stat::incr('test_decr', 22);
+ \Resque\Stat::decr('test_decr');
$this->assertEquals(21, $this->redis->get('resque:stat:test_decr'));
}
public function testStatCanBeDecrementedByX()
{
- Resque_Stat::incr('test_decrX', 22);
- Resque_Stat::decr('test_decrX', 11);
+ \Resque\Stat::incr('test_decrX', 22);
+ \Resque\Stat::decr('test_decrX', 11);
$this->assertEquals(11, $this->redis->get('resque:stat:test_decrX'));
}
public function testGetStatByName()
{
- Resque_Stat::incr('test_get', 100);
- $this->assertEquals(100, Resque_Stat::get('test_get'));
+ \Resque\Stat::incr('test_get', 100);
+ $this->assertEquals(100, \Resque\Stat::get('test_get'));
}
public function testGetUnknownStatReturns0()
{
- $this->assertEquals(0, Resque_Stat::get('test_get_unknown'));
+ $this->assertEquals(0, \Resque\Stat::get('test_get_unknown'));
}
}
\ No newline at end of file
diff --git a/tests/Resque/Tests/TestCase.php b/tests/Resque/Tests/TestCase.php
new file mode 100644
index 0000000..d184010
--- /dev/null
+++ b/tests/Resque/Tests/TestCase.php
@@ -0,0 +1,31 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php
+ */
+class TestCase extends \PHPUnit\Framework\TestCase
+{
+ protected $resque;
+ protected $redis;
+
+ public static function setUpBeforeClass(): void
+ {
+ date_default_timezone_set('UTC');
+ }
+
+ public function setUp(): void
+ {
+ // Setup redis connection for testing.
+ global $redisTestServer;
+
+ $this->redis = new \Credis_Client($redisTestServer, '6379');
+ \Resque\Resque::setBackend($redisTestServer);
+ $this->redis->flushAll();
+ }
+}
diff --git a/test/Resque/Tests/WorkerTest.php b/tests/Resque/Tests/WorkerTest.php
similarity index 53%
rename from test/Resque/Tests/WorkerTest.php
rename to tests/Resque/Tests/WorkerTest.php
index 3dc4e2f..e1b22e4 100644
--- a/test/Resque/Tests/WorkerTest.php
+++ b/tests/Resque/Tests/WorkerTest.php
@@ -1,19 +1,21 @@
+ * @author Daniel Mason
* @license http://www.opensource.org/licenses/mit-license.php
*/
-class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
+class WorkerTest extends TestCase
{
public function testWorkerRegistersInList()
{
- $worker = new Resque_Worker('*');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('*');
+ $worker->setLogger(new \Resque\Log());
$worker->registerWorker();
// Make sure the worker is in the list
@@ -25,76 +27,76 @@ class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
$num = 3;
// Register a few workers
for ($i = 0; $i < $num; ++$i) {
- $worker = new Resque_Worker('queue_' . $i);
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('queue_' . $i);
+ $worker->setLogger(new \Resque\Log());
$worker->registerWorker();
}
// Now try to get them
- $this->assertEquals($num, count(Resque_Worker::all()));
+ $this->assertEquals($num, count(\Resque\Worker::all()));
}
public function testGetWorkerById()
{
- $worker = new Resque_Worker('*');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('*');
+ $worker->setLogger(new \Resque\Log());
$worker->registerWorker();
- $newWorker = Resque_Worker::find((string)$worker);
+ $newWorker = \Resque\Worker::find((string)$worker);
$this->assertEquals((string)$worker, (string)$newWorker);
}
public function testInvalidWorkerDoesNotExist()
{
- $this->assertFalse(Resque_Worker::exists('blah'));
+ $this->assertFalse(\Resque\Worker::exists('blah'));
}
public function testWorkerCanUnregister()
{
- $worker = new Resque_Worker('*');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('*');
+ $worker->setLogger(new \Resque\Log());
$worker->registerWorker();
$worker->unregisterWorker();
- $this->assertFalse(Resque_Worker::exists((string)$worker));
- $this->assertEquals(array(), Resque_Worker::all());
- $this->assertEquals(array(), $this->redis->smembers('resque:workers'));
+ $this->assertFalse(\Resque\Worker::exists((string)$worker));
+ $this->assertEquals([], \Resque\Worker::all());
+ $this->assertEquals([], $this->redis->smembers('resque:workers'));
}
public function testPausedWorkerDoesNotPickUpJobs()
{
- $worker = new Resque_Worker('*');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('*');
+ $worker->setLogger(new \Resque\Log());
$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'));
}
public function testResumedWorkerPicksUpJobs()
{
- $worker = new Resque_Worker('*');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('*');
+ $worker->setLogger(new \Resque\Log());
$worker->pauseProcessing();
- Resque::enqueue('jobs', 'Test_Job');
+ \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
$worker->work(0);
- $this->assertEquals(0, Resque_Stat::get('processed'));
+ $this->assertEquals(0, \Resque\Stat::get('processed'));
$worker->unPauseProcessing();
$worker->work(0);
- $this->assertEquals(1, Resque_Stat::get('processed'));
+ $this->assertEquals(1, \Resque\Stat::get('processed'));
}
public function testWorkerCanWorkOverMultipleQueues()
{
- $worker = new Resque_Worker(array(
+ $worker = new \Resque\Worker([
'queue1',
'queue2'
- ));
- $worker->setLogger(new Resque_Log());
+ ]);
+ $worker->setLogger(new \Resque\Log());
$worker->registerWorker();
- Resque::enqueue('queue1', 'Test_Job_1');
- Resque::enqueue('queue2', 'Test_Job_2');
+ \Resque\Resque::enqueue('queue1', '\Resque\Test\TestJob_1');
+ \Resque\Resque::enqueue('queue2', '\Resque\Test\TestJob_2');
$job = $worker->reserve();
$this->assertEquals('queue1', $job->queue);
@@ -105,18 +107,18 @@ class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
public function testWorkerWorksQueuesInSpecifiedOrder()
{
- $worker = new Resque_Worker(array(
+ $worker = new \Resque\Worker([
'high',
'medium',
'low'
- ));
- $worker->setLogger(new Resque_Log());
+ ]);
+ $worker->setLogger(new \Resque\Log());
$worker->registerWorker();
// Queue the jobs in a different order
- Resque::enqueue('low', 'Test_Job_1');
- Resque::enqueue('high', 'Test_Job_2');
- Resque::enqueue('medium', 'Test_Job_3');
+ \Resque\Resque::enqueue('low', '\Resque\Test\TestJob_1');
+ \Resque\Resque::enqueue('high', '\Resque\Test\TestJob_2');
+ \Resque\Resque::enqueue('medium', '\Resque\Test\TestJob_3');
// Now check we get the jobs back in the right order
$job = $worker->reserve();
@@ -131,12 +133,12 @@ class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
public function testWildcardQueueWorkerWorksAllQueues()
{
- $worker = new Resque_Worker('*');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('*');
+ $worker->setLogger(new \Resque\Log());
$worker->registerWorker();
- Resque::enqueue('queue1', 'Test_Job_1');
- Resque::enqueue('queue2', 'Test_Job_2');
+ \Resque\Resque::enqueue('queue1', '\Resque\Test\TestJob_1');
+ \Resque\Resque::enqueue('queue2', '\Resque\Test\TestJob_2');
$job = $worker->reserve();
$this->assertEquals('queue1', $job->queue);
@@ -147,35 +149,35 @@ class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
public function testWorkerDoesNotWorkOnUnknownQueues()
{
- $worker = new Resque_Worker('queue1');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('queue1');
+ $worker->setLogger(new \Resque\Log());
$worker->registerWorker();
- Resque::enqueue('queue2', 'Test_Job');
+ \Resque\Resque::enqueue('queue2', '\Resque\Test\TestJob');
$this->assertFalse($worker->reserve());
}
public function testWorkerClearsItsStatusWhenNotWorking()
{
- Resque::enqueue('jobs', 'Test_Job');
- $worker = new Resque_Worker('jobs');
- $worker->setLogger(new Resque_Log());
+ \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
+ $worker = new \Resque\Worker('jobs');
+ $worker->setLogger(new \Resque\Log());
$job = $worker->reserve();
$worker->workingOn($job);
$worker->doneWorking();
- $this->assertEquals(array(), $worker->job());
+ $this->assertEquals([], $worker->job());
}
public function testWorkerRecordsWhatItIsWorkingOn()
{
- $worker = new Resque_Worker('jobs');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('jobs');
+ $worker->setLogger(new \Resque\Log());
$worker->registerWorker();
- $payload = array(
- 'class' => 'Test_Job'
- );
- $job = new Resque_Job('jobs', $payload);
+ $payload = [
+ 'class' => '\Resque\Test\TestJob'
+ ];
+ $job = new \Resque\Job\Job('jobs', $payload);
$worker->workingOn($job);
$job = $worker->job();
@@ -188,14 +190,17 @@ class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
public function testWorkerErasesItsStatsWhenShutdown()
{
- Resque::enqueue('jobs', 'Test_Job');
- Resque::enqueue('jobs', 'Invalid_Job');
+ \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
+ \Resque\Resque::enqueue('jobs', '\Resque\Test\InvalidJob');
- $worker = new Resque_Worker('jobs');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('jobs');
+ $worker->setLogger(new \Resque\Log());
$worker->work(0);
$worker->work(0);
+ // Allow time for async unlink to work
+ sleep(2);
+
$this->assertEquals(0, $worker->getStat('processed'));
$this->assertEquals(0, $worker->getStat('failed'));
}
@@ -203,87 +208,84 @@ class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
public function testWorkerCleansUpDeadWorkersOnStartup()
{
// Register a good worker
- $goodWorker = new Resque_Worker('jobs');
- $goodWorker->setLogger(new Resque_Log());
+ $goodWorker = new \Resque\Worker('jobs');
+ $goodWorker->setLogger(new \Resque\Log());
$goodWorker->registerWorker();
$workerId = explode(':', $goodWorker);
// Register some bad workers
- $worker = new Resque_Worker('jobs');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('jobs');
+ $worker->setLogger(new \Resque\Log());
$worker->setId($workerId[0] . ':1:jobs');
$worker->registerWorker();
- $worker = new Resque_Worker(array('high', 'low'));
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker(['high', 'low']);
+ $worker->setLogger(new \Resque\Log());
$worker->setId($workerId[0] . ':2:high,low');
$worker->registerWorker();
- $this->assertEquals(3, count(Resque_Worker::all()));
+ $this->assertEquals(3, count(\Resque\Worker::all()));
$goodWorker->pruneDeadWorkers();
// There should only be $goodWorker left now
- $this->assertEquals(1, count(Resque_Worker::all()));
+ $this->assertEquals(1, count(\Resque\Worker::all()));
}
public function testDeadWorkerCleanUpDoesNotCleanUnknownWorkers()
{
// Register a bad worker on this machine
- $worker = new Resque_Worker('jobs');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('jobs');
+ $worker->setLogger(new \Resque\Log());
$workerId = explode(':', $worker);
$worker->setId($workerId[0] . ':1:jobs');
$worker->registerWorker();
// Register some other false workers
- $worker = new Resque_Worker('jobs');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('jobs');
+ $worker->setLogger(new \Resque\Log());
$worker->setId('my.other.host:1:jobs');
$worker->registerWorker();
- $this->assertEquals(2, count(Resque_Worker::all()));
+ $this->assertEquals(2, count(\Resque\Worker::all()));
$worker->pruneDeadWorkers();
// my.other.host should be left
- $workers = Resque_Worker::all();
+ $workers = \Resque\Worker::all();
$this->assertEquals(1, count($workers));
$this->assertEquals((string)$worker, (string)$workers[0]);
}
public function testWorkerFailsUncompletedJobsOnExit()
{
- $worker = new Resque_Worker('jobs');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('jobs');
+ $worker->setLogger(new \Resque\Log());
$worker->registerWorker();
- $payload = array(
- 'class' => 'Test_Job'
- );
- $job = new Resque_Job('jobs', $payload);
+ $payload = [
+ 'class' => '\Resque\Test\TestJob'
+ ];
+ $job = new \Resque\Job\Job('jobs', $payload);
$worker->workingOn($job);
$worker->unregisterWorker();
- $this->assertEquals(1, Resque_Stat::get('failed'));
+ $this->assertEquals(1, \Resque\Stat::get('failed'));
}
public function testBlockingListPop()
{
- $this->markTestSkipped("Skip temporarily");
- return;
-
- $worker = new Resque_Worker('jobs');
- $worker->setLogger(new Resque_Log());
+ $worker = new \Resque\Worker('jobs');
+ $worker->setLogger(new \Resque\Log());
$worker->registerWorker();
- Resque::enqueue('jobs', 'Test_Job_1');
- Resque::enqueue('jobs', 'Test_Job_2');
+ \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob_1');
+ \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob_2');
$i = 1;
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) {
break;
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
new file mode 100644
index 0000000..cf26e96
--- /dev/null
+++ b/tests/bootstrap.php
@@ -0,0 +1,102 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php
+ */
+
+$loader = require __DIR__ . '/../vendor/autoload.php';
+
+# Redis configuration
+global $redisTestServer;
+$redisTestServer = getenv("REDIS_SERVER") ?: "redis";
+\Resque\Resque::setBackend($redisTestServer);
+
+# Check Redis is accessable locally
+try {
+ $redisTest = new \Resque\Redis($redisTestServer);
+} catch (\Exception $e) {
+ throw new \Exception("Unable to connect to redis. Please check there is a redis-server running.");
+}
+$redisTest = null;
+
+# Cleanup forked workers cleanly
+if (function_exists('pcntl_signal')) {
+ pcntl_signal(SIGINT, function() { exit; });
+ pcntl_signal(SIGTERM, function() { exit; });
+}
+
+# Bootstrap it
+class TestJob
+{
+ public static $called = false;
+ public $args = false;
+ public $queue;
+ public $job;
+
+ public function perform()
+ {
+ self::$called = true;
+ }
+}
+
+class FailingJobException extends \Exception
+{
+}
+
+class FailingJob
+{
+ public static $called = false;
+ public $args = false;
+ public $queue;
+ public $job;
+
+ public function perform()
+ {
+ throw new FailingJobException('Message!');
+ }
+}
+
+class TestJobWithoutPerformMethod
+{
+}
+
+class TestJobWithSetUp
+{
+ public static $called = false;
+ public $args = false;
+ public $queue;
+ public $job;
+
+ public function setUp()
+ {
+ self::$called = true;
+ }
+
+ public function perform()
+ {
+ }
+}
+
+
+class TestJobWithTearDown
+{
+ public static $called = false;
+ public $args = false;
+ public $queue;
+ public $job;
+
+ public function perform()
+ {
+ }
+
+ public function tearDown()
+ {
+ self::$called = true;
+ }
+}
\ No newline at end of file