diff --git a/CHANGELOG.md b/CHANGELOG.md index d3ceb19..04eb5dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ -## 1.3 (2013-??-??) - Current Master ## +## 1.4 (2018-05-25) + + + +## 1.3 (2013) ## **Note:** This release introduces backwards incompatible changes with all previous versions of php-resque. Please see below for details. diff --git a/composer.json b/composer.json index e33f4a4..1c83325 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ } ], "require": { - "php": ">=5.3.0", + "php": ">=7.0.0", "ext-pcntl": "*", "psr/log": "~1.0" }, @@ -21,7 +21,7 @@ "ext-redis": "Native PHP extension for Redis connectivity. Credis will automatically utilize when available." }, "require-dev": { - "phpunit/phpunit": "3.7.*" + "phpunit/phpunit": "^7" }, "bin": [ "bin/resque" diff --git a/composer.lock b/composer.lock index 0f431b9..f8e0da9 100644 --- a/composer.lock +++ b/composer.lock @@ -1,69 +1,37 @@ { "_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#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "hash": "41124ffd15a15b52947e430b92b8f10f", - "content-hash": "11906622d4e017ff6807c6dff51f208d", + "content-hash": "521368fc4c8e3659f7d20f13ce59115b", "packages": [ - { - "name": "colinmollenhour/credis", - "version": "1.7", - "source": { - "type": "git", - "url": "https://github.com/colinmollenhour/credis.git", - "reference": "74b2b703da5c58dc07fb97e8954bc63280b469bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/74b2b703da5c58dc07fb97e8954bc63280b469bf", - "reference": "74b2b703da5c58dc07fb97e8954bc63280b469bf", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "Client.php", - "Cluster.php", - "Sentinel.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", - "time": "2016-03-24 15:50:52" - }, { "name": "psr/log", - "version": "1.0.0", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", "shasum": "" }, + "require": { + "php": ">=5.3.0" + }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, "autoload": { - "psr-0": { - "Psr\\Log\\": "" + "psr-4": { + "Psr\\Log\\": "Psr/Log/" } }, "notification-url": "https://packagist.org/downloads/", @@ -77,41 +45,39 @@ } ], "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ "log", "psr", "psr-3" ], - "time": "2012-12-21 11:40:51" + "time": "2016-10-10T12:19:37+00:00" } ], "packages-dev": [ { - "name": "phpunit/php-code-coverage", - "version": "1.2.18", + "name": "doctrine/instantiator", + "version": "1.1.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "fe2466802556d3fe4e4d1d58ffd3ccfd0a19be0b" + "url": "https://github.com/doctrine/instantiator.git", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/fe2466802556d3fe4e4d1d58ffd3ccfd0a19be0b", - "reference": "fe2466802556d3fe4e4d1d58ffd3ccfd0a19be0b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", "shasum": "" }, "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": ">=1.3.0@stable", - "phpunit/php-text-template": ">=1.2.0@stable", - "phpunit/php-token-stream": ">=1.1.3,<1.3.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "3.7.*@dev" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.0.5" + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "^6.2.3", + "squizlabs/php_codesniffer": "^3.0.2" }, "type": "library", "extra": { @@ -120,21 +86,442 @@ } }, "autoload": { - "classmap": [ - "PHP/" + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2017-07-22T11:58:36+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" + "license": [ + "MIT" ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2017-10-19T19:58:43+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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)", + "time": "2017-03-05T18:14:27+00:00" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.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", + "time": "2017-03-05T17:38:23+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2017-11-30T07:14:17+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.7.6", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2018-04-18T13:57:24+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "6.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "52187754b0eed0b8159f62a6fa30073327e8c2ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/52187754b0eed0b8159f62a6fa30073327e8c2ca", + "reference": "52187754b0eed0b8159f62a6fa30073327e8c2ca", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.1", + "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.1", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-xdebug": "^2.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -145,20 +532,20 @@ "testing", "xunit" ], - "time": "2014-09-02 10:13:14" + "time": "2018-04-29T14:59:09+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.1", + "version": "1.4.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", "shasum": "" }, "require": { @@ -192,7 +579,7 @@ "filesystem", "iterator" ], - "time": "2015-06-21 13:08:43" + "time": "2017-11-27T13:52:08+00:00" }, { "name": "phpunit/php-text-template", @@ -233,27 +620,824 @@ "keywords": [ "template" ], - "time": "2015-06-21 13:50:34" + "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", - "version": "1.0.8", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", - "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "~4|~5" + "phpunit/phpunit": "^7.0" + }, + "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": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2018-02-01T13:07:23+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "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" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2018-02-01T13:16:43+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "7.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "ca64dba53b88aba6af32aebc6b388068db95c435" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ca64dba53b88aba6af32aebc6b388068db95c435", + "reference": "ca64dba53b88aba6af32aebc6b388068db95c435", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.6.1", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.1", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^6.0.1", + "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.0", + "phpunit/phpunit-mock-objects": "^6.1.1", + "sebastian/comparator": "^3.0", + "sebastian/diff": "^3.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.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": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2018-04-29T15:09:19+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "6.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "70c740bde8fd9ea9ea295be1cd875dd7b267e157" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/70c740bde8fd9ea9ea295be1cd875dd7b267e157", + "reference": "70c740bde8fd9ea9ea295be1cd875dd7b267e157", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.5", + "php": "^7.1", + "phpunit/php-text-template": "^1.2.1", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.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": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2018-04-11T04:50:36+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-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/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/ed5fd2281113729f1ebcc64d101ad66028aeb3d5", + "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5", + "shasum": "" + }, + "require": { + "php": "^7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "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": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-04-18T13:33:00+00:00" + }, + { + "name": "sebastian/diff", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/e09160918c66281713f1c324c1f4c4c3037ba1e8", + "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "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": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "time": "2018-02-01T13:45:15+00:00" + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-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" + ], + "time": "2017-07-01T08:51:00+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2017-04-03T13:19:02+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "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": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-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/", + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-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/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-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", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "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": "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", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" }, "type": "library", "autoload": { @@ -267,220 +1451,45 @@ ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2016-05-12 18:03:57" + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" }, { - "name": "phpunit/php-token-stream", - "version": "1.2.2", + "name": "webmozart/assert", + "version": "1.3.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32" + "url": "https://github.com/webmozart/assert.git", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32", - "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2014-03-03 05:10:30" - }, - { - "name": "phpunit/phpunit", - "version": "3.7.38", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "38709dc22d519a3d1be46849868aa2ddf822bcf6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/38709dc22d519a3d1be46849868aa2ddf822bcf6", - "reference": "38709dc22d519a3d1be46849868aa2ddf822bcf6", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpunit/php-code-coverage": "~1.2", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.1", - "phpunit/php-timer": "~1.0", - "phpunit/phpunit-mock-objects": "~1.2", - "symfony/yaml": "~2.0" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "pear-pear.php.net/pear": "1.9.4" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "composer/bin/phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.7.x-dev" - } - }, - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "", - "../../symfony/yaml/" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2014-10-17 09:04:17" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "1.2.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/5794e3c5c5ba0fb037b11d8151add2a07fa82875", - "reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-text-template": ">=1.1.1@stable" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2013-01-13 10:24:48" - }, - { - "name": "symfony/yaml", - "version": "v2.8.12", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "e7540734bad981fe59f8ef14b6fc194ae9df8d9c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e7540734bad981fe59f8ef14b6fc194ae9df8d9c", - "reference": "e7540734bad981fe59f8ef14b6fc194ae9df8d9c", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "1.3-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Webmozart\\Assert\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -488,17 +1497,17 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "time": "2016-09-02 01:57:56" + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2018-01-29T19:49:41+00:00" } ], "aliases": [], @@ -507,7 +1516,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.3.0", + "php": ">=7.0.0", "ext-pcntl": "*" }, "platform-dev": [] diff --git a/lib/Resque.php b/lib/Resque.php index d03b2ec..b01c898 100644 --- a/lib/Resque.php +++ b/lib/Resque.php @@ -1,379 +1,380 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque { - const VERSION = '1.2'; + const VERSION = '1.4'; const DEFAULT_INTERVAL = 5; - /** - * @var Resque_Redis Instance of Resque_Redis that talks to redis. - */ - public static $redis = null; + /** + * @var Resque_Redis Instance of Resque_Redis that talks to redis. + */ + public static $redis = null; - /** - * @var mixed Host/port conbination separated by a colon, or a nested - * array of server swith host/port pairs - */ - protected static $redisServer = null; + /** + * @var mixed Host/port conbination separated by a colon, or a nested + * array of server swith host/port pairs + */ + protected static $redisServer = null; - /** - * @var int ID of Redis database to select. - */ - protected static $redisDatabase = 0; + /** + * @var int ID of Redis database to select. + */ + protected static $redisDatabase = 0; - /** - * Given a host/port combination separated by a colon, set it as - * the redis server that Resque will talk to. - * - * @param mixed $server Host/port combination separated by a colon, DSN-formatted URI, or - * a callable that receives the configured database ID - * and returns a Resque_Redis instance, or - * a nested array of servers with host/port pairs. - * @param int $database - */ - public static function setBackend($server, $database = 0) - { - self::$redisServer = $server; - self::$redisDatabase = $database; - self::$redis = null; - } + /** + * Given a host/port combination separated by a colon, set it as + * the redis server that Resque will talk to. + * + * @param mixed $server Host/port combination separated by a colon, DSN-formatted URI, or + * a callable that receives the configured database ID + * and returns a Resque_Redis instance, or + * a nested array of servers with host/port pairs. + * @param int $database + */ + public static function setBackend($server, $database = 0) + { + self::$redisServer = $server; + self::$redisDatabase = $database; + self::$redis = null; + } - /** - * Return an instance of the Resque_Redis class instantiated for Resque. - * - * @return Resque_Redis Instance of Resque_Redis. - */ - public static function redis() - { - if (self::$redis !== null) { - return self::$redis; - } + /** + * Return an instance of the Resque_Redis class instantiated for Resque. + * + * @return Resque_Redis Instance of Resque_Redis. + */ + public static function redis() + { + if (self::$redis !== null) { + 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); - } + if (is_callable(self::$redisServer)) { + self::$redis = call_user_func(self::$redisServer, self::$redisDatabase); + } else { + self::$redis = new Resque_Redis(self::$redisServer, self::$redisDatabase); + } - return self::$redis; - } + return self::$redis; + } - /** - * fork() helper method for php-resque that handles issues PHP socket - * and phpredis have with passing around sockets between child/parent - * processes. - * - * Will close connection to Redis before forking. - * - * @return int Return vars as per pcntl_fork(). False if pcntl_fork is unavailable - */ - public static function fork() - { - if(!function_exists('pcntl_fork')) { - return false; - } + /** + * fork() helper method for php-resque that handles issues PHP socket + * and phpredis have with passing around sockets between child/parent + * processes. + * + * Will close connection to Redis before forking. + * + * @return int Return vars as per pcntl_fork(). False if pcntl_fork is unavailable + */ + public static function fork() + { + if (!function_exists('pcntl_fork')) { + return false; + } - // Close the connection to Redis before forking. - // This is a workaround for issues phpredis has. - self::$redis = null; + // Close the connection to Redis before forking. + // This is a workaround for issues phpredis has. + self::$redis = null; - $pid = pcntl_fork(); - if($pid === -1) { - throw new RuntimeException('Unable to fork child worker.'); - } + $pid = pcntl_fork(); + if ($pid === -1) { + throw new RuntimeException('Unable to fork child worker.'); + } - return $pid; - } + return $pid; + } - /** - * Push a job to the end of a specific queue. If the queue does not - * exist, then create it as well. - * - * @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. - */ - public static function push($queue, $item) - { - $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; - } + /** + * Push a job to the end of a specific queue. If the queue does not + * exist, then create it as well. + * + * @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. + */ + public static function push($queue, $item) + { + $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; + } - /** - * Pop an item off the end of the specified queue, decode it and - * return it. - * - * @param string $queue The name of the queue to fetch an item from. - * @return array Decoded item from the queue. - */ - public static function pop($queue) - { + /** + * Pop an item off the end of the specified queue, decode it and + * return it. + * + * @param string $queue The name of the queue to fetch an item from. + * @return array Decoded item from the queue. + */ + public static function pop($queue) + { $item = self::redis()->lpop('queue:' . $queue); - if(!$item) { - return; - } + if (!$item) { + return; + } - return json_decode($item, true); - } + return json_decode($item, true); + } - /** - * Remove items of the specified queue - * - * @param string $queue The name of the queue to fetch an item from. - * @param array $items - * @return integer number of deleted items - */ - public static function dequeue($queue, $items = Array()) - { - if(count($items) > 0) { - return self::removeItems($queue, $items); - } else { - return self::removeList($queue); - } - } + /** + * Remove items of the specified queue + * + * @param string $queue The name of the queue to fetch an item from. + * @param array $items + * @return integer number of deleted items + */ + public static function dequeue($queue, $items = Array()) + { + if (count($items) > 0) { + return self::removeItems($queue, $items); + } else { + return self::removeList($queue); + } + } - /** - * Remove specified queue - * - * @param string $queue The name of the queue to remove. - * @return integer Number of deleted items - */ - public static function removeQueue($queue) - { - $num = self::removeList($queue); - self::redis()->srem('queues', $queue); - return $num; - } + /** + * Remove specified queue + * + * @param string $queue The name of the queue to remove. + * @return integer Number of deleted items + */ + public static function removeQueue($queue) + { + $num = self::removeList($queue); + self::redis()->srem('queues', $queue); + return $num; + } - /** - * Pop an item off the end of the specified queues, using blocking list pop, - * decode it and return it. - * - * @param array $queues - * @param int $timeout - * @return null|array Decoded item from the queue. - */ - public static function blpop(array $queues, $timeout) - { - $list = array(); - foreach($queues AS $queue) { - $list[] = 'queue:' . $queue; - } + /** + * Pop an item off the end of the specified queues, using blocking list pop, + * decode it and return it. + * + * @param array $queues + * @param int $timeout + * @return null|array Decoded item from the queue. + */ + public static function blpop(array $queues, $timeout) + { + $list = array(); + foreach ($queues AS $queue) { + $list[] = 'queue:' . $queue; + } - $item = self::redis()->blpop($list, (int)$timeout); + $item = self::redis()->blpop($list, (int)$timeout); - if(!$item) { - return; - } + if (!$item) { + return; + } - /** - * Normally the Resque_Redis class returns queue names without the prefix - * But the blpop is a bit different. It returns the name as prefix:queue:name - * So we need to strip off the prefix:queue: part - */ - $queue = substr($item[0], strlen(self::redis()->getPrefix() . 'queue:')); + /** + * Normally the Resque_Redis class returns queue names without the prefix + * But the blpop is a bit different. It returns the name as prefix:queue:name + * So we need to strip off the prefix:queue: part + */ + $queue = substr($item[0], strlen(self::redis()->getPrefix() . 'queue:')); - return array( - 'queue' => $queue, - 'payload' => json_decode($item[1], true) - ); - } + return array( + 'queue' => $queue, + 'payload' => json_decode($item[1], true) + ); + } - /** - * Return the size (number of pending jobs) of the specified queue. - * - * @param string $queue name of the queue to be checked for pending jobs - * - * @return int The size of the queue. - */ - public static function size($queue) - { - return self::redis()->llen('queue:' . $queue); - } + /** + * Return the size (number of pending jobs) of the specified queue. + * + * @param string $queue name of the queue to be checked for pending jobs + * + * @return int The size of the queue. + */ + public static function size($queue) + { + return self::redis()->llen('queue:' . $queue); + } - /** - * Create a new job and save it to the specified queue. - * - * @param string $queue The name of the queue to place the job in. - * @param string $class The name of the class that contains the code to execute the job. - * @param array $args Any optional arguments that should be passed when the job is executed. - * @param boolean $trackStatus Set to true to be able to monitor the status of a job. - * - * @return string|boolean Job ID when the job was created, false if creation was cancelled due to beforeEnqueue - */ - public static function enqueue($queue, $class, $args = null, $trackStatus = false) - { - $id = Resque::generateJobId(); - $hookParams = array( - 'class' => $class, - 'args' => $args, - 'queue' => $queue, - 'id' => $id, - ); - try { - Resque_Event::trigger('beforeEnqueue', $hookParams); - } - catch(Resque_Job_DontCreate $e) { - return false; - } + /** + * Create a new job and save it to the specified queue. + * + * @param string $queue The name of the queue to place the job in. + * @param string $class The name of the class that contains the code to execute the job. + * @param array $args Any optional arguments that should be passed when the job is executed. + * @param boolean $trackStatus Set to true to be able to monitor the status of a job. + * + * @return string|boolean Job ID when the job was created, false if creation was cancelled due to beforeEnqueue + */ + public static function enqueue($queue, $class, $args = null, $trackStatus = false) + { + $id = Resque::generateJobId(); + $hookParams = array( + 'class' => $class, + 'args' => $args, + 'queue' => $queue, + 'id' => $id, + ); + try { + 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::create($queue, $class, $args, $trackStatus, $id); + Resque_Event::trigger('afterEnqueue', $hookParams); - return $id; - } + return $id; + } - /** - * 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. - */ - public static function reserve($queue) - { - return Resque_Job::reserve($queue); - } + /** + * 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. + */ + public static function reserve($queue) + { + return Resque_Job::reserve($queue); + } - /** - * Get an array of all known queues. - * - * @return array Array of queues. - */ - public static function queues() - { - $queues = self::redis()->smembers('queues'); - if(!is_array($queues)) { - $queues = array(); - } - return $queues; - } + /** + * Get an array of all known queues. + * + * @return array Array of queues. + */ + public static function queues() + { + $queues = self::redis()->smembers('queues'); + if (!is_array($queues)) { + $queues = array(); + } + return $queues; + } - /** - * Remove Items from the queue - * Safely moving each item to a temporary queue before processing it - * If the Job matches, counts otherwise puts it in a requeue_queue - * which at the end eventually be copied back into the original queue - * - * @private - * - * @param string $queue The name of the queue - * @param array $items - * @return integer number of deleted items - */ - private static function removeItems($queue, $items = Array()) - { - $counter = 0; - $originalQueue = 'queue:'. $queue; - $tempQueue = $originalQueue. ':temp:'. time(); - $requeueQueue = $tempQueue. ':requeue'; + /** + * Remove Items from the queue + * Safely moving each item to a temporary queue before processing it + * If the Job matches, counts otherwise puts it in a requeue_queue + * which at the end eventually be copied back into the original queue + * + * @private + * + * @param string $queue The name of the queue + * @param array $items + * @return integer number of deleted items + */ + private static function removeItems($queue, $items = Array()) + { + $counter = 0; + $originalQueue = 'queue:' . $queue; + $tempQueue = $originalQueue . ':temp:' . time(); + $requeueQueue = $tempQueue . ':requeue'; - // move each item from original queue to temp queue and process it - $finished = false; - while (!$finished) { - $string = self::redis()->rpoplpush($originalQueue, self::redis()->getPrefix() . $tempQueue); + // move each item from original queue to temp queue and process it + $finished = false; + while (!$finished) { + $string = self::redis()->rpoplpush($originalQueue, self::redis()->getPrefix() . $tempQueue); - if (!empty($string)) { - if(self::matchItem($string, $items)) { - self::redis()->rpop($tempQueue); - $counter++; - } else { - self::redis()->rpoplpush($tempQueue, self::redis()->getPrefix() . $requeueQueue); - } - } else { - $finished = true; - } - } + if (!empty($string)) { + if (self::matchItem($string, $items)) { + self::redis()->rpop($tempQueue); + $counter++; + } else { + self::redis()->rpoplpush($tempQueue, self::redis()->getPrefix() . $requeueQueue); + } + } else { + $finished = true; + } + } - // move back from temp queue to original queue - $finished = false; - while (!$finished) { - $string = self::redis()->rpoplpush($requeueQueue, self::redis()->getPrefix() .$originalQueue); - if (empty($string)) { - $finished = true; - } - } + // move back from temp queue to original queue + $finished = false; + while (!$finished) { + $string = self::redis()->rpoplpush($requeueQueue, self::redis()->getPrefix() . $originalQueue); + if (empty($string)) { + $finished = true; + } + } - // remove temp queue and requeue queue - self::redis()->del($requeueQueue); - self::redis()->del($tempQueue); + // remove temp queue and requeue queue + self::redis()->del($requeueQueue); + self::redis()->del($tempQueue); - return $counter; - } + return $counter; + } - /** - * matching item - * item can be ['class'] or ['class' => 'id'] or ['class' => {:foo => 1, :bar => 2}] - * @private - * - * @params string $string redis result in json - * @params $items - * - * @return (bool) - */ - private static function matchItem($string, $items) - { - $decoded = json_decode($string, true); + /** + * matching item + * item can be ['class'] or ['class' => 'id'] or ['class' => {:foo => 1, :bar => 2}] + * @private + * + * @params string $string redis result in json + * @params $items + * + * @return (bool) + */ + private static function matchItem($string, $items) + { + $decoded = json_decode($string, true); - foreach($items as $key => $val) { - # class name only ex: item[0] = ['class'] - if (is_numeric($key)) { - if($decoded['class'] == $val) { - return true; - } - # 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) { - return true; - } - # class name with ID, example: item[0] = ['class' => 'id'] - } else { - if ($decoded['class'] == $key && $decoded['id'] == $val) { - return true; - } - } - } - return false; - } + foreach ($items as $key => $val) { + # class name only ex: item[0] = ['class'] + if (is_numeric($key)) { + if ($decoded['class'] == $val) { + return true; + } + # 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) { + return true; + } + # class name with ID, example: item[0] = ['class' => 'id'] + } else { + if ($decoded['class'] == $key && $decoded['id'] == $val) { + return true; + } + } + } + return false; + } - /** - * Remove List - * - * @private - * - * @params string $queue the name of the queue - * @return integer number of deleted items belongs to this list - */ - private static function removeList($queue) - { - $counter = self::size($queue); - $result = self::redis()->del('queue:' . $queue); - return ($result == 1) ? $counter : 0; - } + /** + * Remove List + * + * @private + * + * @params string $queue the name of the queue + * @return integer number of deleted items belongs to this list + */ + private static function removeList($queue) + { + $counter = self::size($queue); + $result = self::redis()->del('queue:' . $queue); + return ($result == 1) ? $counter : 0; + } - /* - * Generate an identifier to attach to a job for status tracking. - * - * @return string - */ - public static function generateJobId() - { - return md5(uniqid('', true)); - } + /* + * Generate an identifier to attach to a job for status tracking. + * + * @return string + */ + public static function generateJobId() + { + return md5(uniqid('', true)); + } } diff --git a/lib/Resque/Event.php b/lib/Resque/Event.php index 20072ff..2c8f182 100644 --- a/lib/Resque/Event.php +++ b/lib/Resque/Event.php @@ -1,88 +1,90 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Event + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Event { - /** - * @var array Array containing all registered callbacks, indexked by event name. - */ - private static $events = array(); + /** + * @var array Array containing all registered callbacks, indexked by event name. + */ + private static $events = []; - /** - * Raise a given event with the supplied data. - * - * @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) - { - if (!is_array($data)) { - $data = array($data); - } + /** + * Raise a given event with the supplied data. + * + * @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) + { + if (!is_array($data)) { + $data = [$data]; + } - if (empty(self::$events[$event])) { - return true; - } - - foreach (self::$events[$event] as $callback) { - if (!is_callable($callback)) { - continue; - } - call_user_func_array($callback, $data); - } - - return true; - } - - /** - * 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. - * @return true - */ - public static function listen($event, $callback) - { - if (!isset(self::$events[$event])) { - self::$events[$event] = array(); - } - - self::$events[$event][] = $callback; - return true; - } - - /** - * Stop a given callback from listening on a specific 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) - { - if (!isset(self::$events[$event])) { - return true; - } - - $key = array_search($callback, self::$events[$event]); - if ($key !== false) { - unset(self::$events[$event][$key]); - } - - return true; - } - - /** - * Call all registered listeners. - */ - public static function clearListeners() - { - self::$events = array(); - } + if (empty(self::$events[$event])) { + return true; + } + + foreach (self::$events[$event] as $callback) { + if (!is_callable($callback)) { + continue; + } + call_user_func_array($callback, $data); + } + + return true; + } + + /** + * 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. + * @return true + */ + public static function listen($event, $callback) + { + if (!isset(self::$events[$event])) { + self::$events[$event] = []; + } + + self::$events[$event][] = $callback; + return true; + } + + /** + * Stop a given callback from listening on a specific 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) + { + if (!isset(self::$events[$event])) { + return true; + } + + $key = array_search($callback, self::$events[$event]); + if ($key !== false) { + unset(self::$events[$event][$key]); + } + + return true; + } + + /** + * Call all registered listeners. + */ + public static function clearListeners() + { + self::$events = []; + } } diff --git a/lib/Resque/Exception.php b/lib/Resque/Exception.php index 01217c3..fe510ca 100644 --- a/lib/Resque/Exception.php +++ b/lib/Resque/Exception.php @@ -1,11 +1,13 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Exception extends Exception { } diff --git a/lib/Resque/Failure.php b/lib/Resque/Failure.php index deb678f..adf02a3 100644 --- a/lib/Resque/Failure.php +++ b/lib/Resque/Failure.php @@ -3,54 +3,55 @@ /** * Failed Resque job. * - * @package Resque/Failure - * @author Chris Boulton - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Failure + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Failure { - /** - * @var string Class name representing the backend to pass failed jobs off to. - */ - private static $backend; + /** + * @var string Class name representing the backend to pass failed jobs off to. + */ + private static $backend; - /** - * Create a new failed job on the backend. - * - * @param object $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 string $queue The name of the queue that this job was fetched from. - */ - public static function create($payload, Exception $exception, Resque_Worker $worker, $queue) - { - $backend = self::getBackend(); - new $backend($payload, $exception, $worker, $queue); - } + /** + * Create a new failed job on the backend. + * + * @param object $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 string $queue The name of the queue that this job was fetched from. + */ + public static function create($payload, Exception $exception, Resque_Worker $worker, $queue) + { + $backend = self::getBackend(); + new $backend($payload, $exception, $worker, $queue); + } - /** - * Return an instance of the backend for saving job failures. - * - * @return object Instance of backend object. - */ - public static function getBackend() - { - if(self::$backend === null) { - self::$backend = 'Resque_Failure_Redis'; - } + /** + * Return an instance of the backend for saving job failures. + * + * @return object Instance of backend object. + */ + public static function getBackend() + { + if (self::$backend === null) { + self::$backend = 'Resque_Failure_Redis'; + } - return self::$backend; - } + return self::$backend; + } - /** - * Set the backend to use for raised job failures. The supplied backend - * should be the name of a class to be instantiated when a job fails. - * 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. - */ - public static function setBackend($backend) - { - self::$backend = $backend; - } + /** + * Set the backend to use for raised job failures. The supplied backend + * should be the name of a class to be instantiated when a job fails. + * 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. + */ + public static function setBackend($backend) + { + self::$backend = $backend; + } } \ No newline at end of file diff --git a/lib/Resque/Failure/Interface.php b/lib/Resque/Failure/Interface.php index 74de9e7..d6da0e2 100644 --- a/lib/Resque/Failure/Interface.php +++ b/lib/Resque/Failure/Interface.php @@ -1,20 +1,21 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Failure + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ interface Resque_Failure_Interface { - /** - * Initialize a failed job class and save it (where appropriate). - * - * @param object $payload Object containing details of the failed job. - * @param object $exception Instance of the exception that was thrown by the failed job. - * @param object $worker Instance of Resque_Worker that received the job. - * @param string $queue The name of the queue the job was fetched from. - */ - public function __construct($payload, $exception, $worker, $queue); + /** + * Initialize a failed job class and save it (where appropriate). + * + * @param object $payload Object containing details of the failed job. + * @param object $exception Instance of the exception that was thrown by the failed job. + * @param object $worker Instance of Resque_Worker that received the job. + * @param string $queue The name of the queue the job was fetched from. + */ + public function __construct($payload, $exception, $worker, $queue); } diff --git a/lib/Resque/Failure/Redis.php b/lib/Resque/Failure/Redis.php index 69d6872..caff0d5 100644 --- a/lib/Resque/Failure/Redis.php +++ b/lib/Resque/Failure/Redis.php @@ -2,32 +2,32 @@ /** * Redis backend for storing failed Resque jobs. * - * @package Resque/Failure - * @author Chris Boulton - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Failure + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ class Resque_Failure_Redis implements Resque_Failure_Interface { - /** - * Initialize a failed job class and save it (where appropriate). - * - * @param object $payload Object containing details of the failed job. - * @param object $exception Instance of the exception that was thrown by the failed job. - * @param object $worker Instance of Resque_Worker that received the job. - * @param string $queue The name of the queue the job was fetched from. - */ - public function __construct($payload, $exception, $worker, $queue) - { - $data = new stdClass; - $data->failed_at = strftime('%a %b %d %H:%M:%S %Z %Y'); - $data->payload = $payload; - $data->exception = get_class($exception); - $data->error = $exception->getMessage(); - $data->backtrace = explode("\n", $exception->getTraceAsString()); - $data->worker = (string)$worker; - $data->queue = $queue; - $data = json_encode($data); - Resque::redis()->rpush('failed', $data); - } + /** + * Initialize a failed job class and save it (where appropriate). + * + * @param object $payload Object containing details of the failed job. + * @param object $exception Instance of the exception that was thrown by the failed job. + * @param object $worker Instance of Resque_Worker that received the job. + * @param string $queue The name of the queue the job was fetched from. + */ + public function __construct($payload, $exception, $worker, $queue) + { + $data = new stdClass; + $data->failed_at = strftime('%a %b %d %H:%M:%S %Z %Y'); + $data->payload = $payload; + $data->exception = get_class($exception); + $data->error = $exception->getMessage(); + $data->backtrace = explode("\n", $exception->getTraceAsString()); + $data->worker = (string)$worker; + $data->queue = $queue; + $data = json_encode($data); + Resque::redis()->rpush('failed', $data); + } } diff --git a/lib/Resque/Job.php b/lib/Resque/Job.php index 8508f76..69322f6 100755 --- a/lib/Resque/Job.php +++ b/lib/Resque/Job.php @@ -1,4 +1,5 @@ * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Job { /** diff --git a/lib/Resque/Job/DirtyExitException.php b/lib/Resque/Job/DirtyExitException.php index 108e061..7b1f88b 100644 --- a/lib/Resque/Job/DirtyExitException.php +++ b/lib/Resque/Job/DirtyExitException.php @@ -1,12 +1,13 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Job + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ class Resque_Job_DirtyExitException extends RuntimeException { -} \ No newline at end of file +} diff --git a/lib/Resque/Job/DontCreate.php b/lib/Resque/Job/DontCreate.php index 31c33cd..931ae91 100644 --- a/lib/Resque/Job/DontCreate.php +++ b/lib/Resque/Job/DontCreate.php @@ -1,12 +1,13 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Job + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ class Resque_Job_DontCreate extends Exception { -} \ No newline at end of file +} diff --git a/lib/Resque/Job/DontPerform.php b/lib/Resque/Job/DontPerform.php index 553327f..69075f4 100644 --- a/lib/Resque/Job/DontPerform.php +++ b/lib/Resque/Job/DontPerform.php @@ -1,12 +1,14 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Job + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Job_DontPerform extends Exception { -} \ No newline at end of file +} diff --git a/lib/Resque/Job/FactoryInterface.php b/lib/Resque/Job/FactoryInterface.php index b8c102c..a1203e1 100644 --- a/lib/Resque/Job/FactoryInterface.php +++ b/lib/Resque/Job/FactoryInterface.php @@ -2,11 +2,11 @@ interface Resque_Job_FactoryInterface { - /** - * @param $className - * @param array $args - * @param $queue - * @return Resque_JobInterface - */ - public function create($className, $args, $queue); + /** + * @param $className + * @param array $args + * @param $queue + * @return Resque_JobInterface + */ + public function create($className, $args, $queue); } diff --git a/lib/Resque/Job/Status.php b/lib/Resque/Job/Status.php index 00fc40c..8987fd7 100644 --- a/lib/Resque/Job/Status.php +++ b/lib/Resque/Job/Status.php @@ -1,142 +1,144 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Job + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Job_Status { - const STATUS_WAITING = 1; - const STATUS_RUNNING = 2; - const STATUS_FAILED = 3; - const STATUS_COMPLETE = 4; + const STATUS_WAITING = 1; + const STATUS_RUNNING = 2; + const STATUS_FAILED = 3; + const STATUS_COMPLETE = 4; - /** - * @var string The ID of the job this status class refers back to. - */ - private $id; + /** + * @var string The ID of the job this status class refers back to. + */ + private $id; - /** - * @var mixed Cache variable if the status of this job is being monitored or not. - * True/false when checked at least once or null if not checked yet. - */ - private $isTracking = null; + /** + * @var mixed Cache variable if the status of this job is being monitored or not. + * True/false when checked at least once or null if not checked yet. + */ + private $isTracking = null; - /** - * @var array Array of statuses that are considered final/complete. - */ - private static $completeStatuses = array( - self::STATUS_FAILED, - self::STATUS_COMPLETE - ); + /** + * @var array Array of statuses that are considered final/complete. + */ + private static $completeStatuses = array( + self::STATUS_FAILED, + self::STATUS_COMPLETE + ); - /** - * Setup a new instance of the job monitor class for the supplied job ID. - * - * @param string $id The ID of the job to manage the status for. - */ - public function __construct($id) - { - $this->id = $id; - } + /** + * Setup a new instance of the job monitor class for the supplied job ID. + * + * @param string $id The ID of the job to manage the status for. + */ + public function __construct($id) + { + $this->id = $id; + } - /** - * Create a new status monitor item for the supplied job ID. Will create - * all necessary keys in Redis to monitor the status of a job. - * - * @param string $id The ID of the job to monitor the status of. - */ - public static function create($id) - { - $statusPacket = array( - 'status' => self::STATUS_WAITING, - 'updated' => time(), - 'started' => time(), - ); - Resque::redis()->set('job:' . $id . ':status', json_encode($statusPacket)); - } + /** + * Create a new status monitor item for the supplied job ID. Will create + * all necessary keys in Redis to monitor the status of a job. + * + * @param string $id The ID of the job to monitor the status of. + */ + public static function create($id) + { + $statusPacket = array( + 'status' => self::STATUS_WAITING, + 'updated' => time(), + 'started' => time(), + ); + Resque::redis()->set('job:' . $id . ':status', json_encode($statusPacket)); + } - /** - * Check if we're actually checking the status of the loaded job status - * instance. - * - * @return boolean True if the status is being monitored, false if not. - */ - public function isTracking() - { - if($this->isTracking === false) { - return false; - } + /** + * Check if we're actually checking the status of the loaded job status + * instance. + * + * @return boolean True if the status is being monitored, false if not. + */ + public function isTracking() + { + if ($this->isTracking === false) { + return false; + } - if(!Resque::redis()->exists((string)$this)) { - $this->isTracking = false; - return false; - } + if (!Resque::redis()->exists((string)$this)) { + $this->isTracking = false; + return false; + } - $this->isTracking = true; - return true; - } + $this->isTracking = true; + return true; + } - /** - * 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) - */ - public function update($status) - { - if(!$this->isTracking()) { - return; - } + /** + * 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) + */ + public function update($status) + { + if (!$this->isTracking()) { + return; + } - $statusPacket = array( - 'status' => $status, - 'updated' => time(), - ); - Resque::redis()->set((string)$this, json_encode($statusPacket)); + $statusPacket = [ + '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); - } - } + // Expire the status for completed jobs after 24 hours + if (in_array($status, self::$completeStatuses)) { + Resque::redis()->expire((string)$this, 86400); + } + } - /** - * 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. - */ - public function get() - { - if(!$this->isTracking()) { - return false; - } + /** + * 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. + */ + public function get() + { + if (!$this->isTracking()) { + return false; + } - $statusPacket = json_decode(Resque::redis()->get((string)$this), true); - if(!$statusPacket) { - return false; - } + $statusPacket = json_decode(Resque::redis()->get((string)$this), true); + if (!$statusPacket) { + return false; + } - return $statusPacket['status']; - } + return $statusPacket['status']; + } - /** - * Stop tracking the status of a job. - */ - public function stop() - { - Resque::redis()->del((string)$this); - } + /** + * Stop tracking the status of a job. + */ + public function stop() + { + Resque::redis()->del((string)$this); + } - /** - * Generate a string representation of this object. - * - * @return string String representation of the current job status class. - */ - public function __toString() - { - return 'job:' . $this->id . ':status'; - } + /** + * Generate a string representation of this object. + * + * @return string String representation of the current job status class. + */ + public function __toString() + { + return 'job:' . $this->id . ':status'; + } } diff --git a/lib/Resque/JobInterface.php b/lib/Resque/JobInterface.php index be5891d..f31281d 100644 --- a/lib/Resque/JobInterface.php +++ b/lib/Resque/JobInterface.php @@ -2,8 +2,8 @@ interface Resque_JobInterface { - /** - * @return bool - */ - public function perform(); + /** + * @return bool + */ + public function perform(); } diff --git a/lib/Resque/Log.php b/lib/Resque/Log.php index ce279cc..fd7d5f5 100644 --- a/lib/Resque/Log.php +++ b/lib/Resque/Log.php @@ -1,62 +1,65 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Stat + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ -class Resque_Log extends Psr\Log\AbstractLogger + +class Resque_Log extends Psr\Log\AbstractLogger { - public $verbose; + public $verbose; - public function __construct($verbose = false) { - $this->verbose = $verbose; - } + public function __construct($verbose = false) + { + $this->verbose = $verbose; + } - /** - * Logs with an arbitrary level. - * - * @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()) - { - if ($this->verbose) { - fwrite( - STDOUT, - '[' . $level . '] [' . strftime('%T %Y-%m-%d') . '] ' . $this->interpolate($message, $context) . PHP_EOL - ); - return; - } + /** + * Logs with an arbitrary level. + * + * @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()) + { + if ($this->verbose) { + fwrite( + STDOUT, + '[' . $level . '] [' . strftime('%T %Y-%m-%d') . '] ' . $this->interpolate($message, $context) . PHP_EOL + ); + return; + } - if (!($level === Psr\Log\LogLevel::INFO || $level === Psr\Log\LogLevel::DEBUG)) { - fwrite( - STDOUT, - '[' . $level . '] ' . $this->interpolate($message, $context) . PHP_EOL - ); - } - } + if (!($level === Psr\Log\LogLevel::INFO || $level === Psr\Log\LogLevel::DEBUG)) { + fwrite( + STDOUT, + '[' . $level . '] ' . $this->interpolate($message, $context) . PHP_EOL + ); + } + } - /** - * Fill placeholders with the provided context - * @author Jordi Boggiano j.boggiano@seld.be - * - * @param string $message Message to be logged - * @param array $context Array of variables to use in message - * @return string - */ - public function interpolate($message, array $context = array()) - { - // build a replacement array with braces around the context keys - $replace = array(); - foreach ($context as $key => $val) { - $replace['{' . $key . '}'] = $val; - } - - // interpolate replacement values into the message and return - return strtr($message, $replace); - } + /** + * Fill placeholders with the provided context + * @author Jordi Boggiano j.boggiano@seld.be + * + * @param string $message Message to be logged + * @param array $context Array of variables to use in message + * @return string + */ + public function interpolate($message, array $context = array()) + { + // build a replacement array with braces around the context keys + $replace = array(); + foreach ($context as $key => $val) { + $replace['{' . $key . '}'] = $val; + } + + // interpolate replacement values into the message and return + return strtr($message, $replace); + } } diff --git a/lib/Resque/Redis.php b/lib/Resque/Redis.php index 153bd40..c6a831b 100644 --- a/lib/Resque/Redis.php +++ b/lib/Resque/Redis.php @@ -1,270 +1,262 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Redis + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Redis { - /** - * Redis namespace - * @var string - */ - private static $defaultNamespace = 'resque:'; + /** + * Redis namespace + * @var string + */ + private static $defaultNamespace = 'resque:'; - /** - * A default host to connect to - */ - const DEFAULT_HOST = 'localhost'; + /** + * A default host to connect to + */ + const DEFAULT_HOST = 'localhost'; - /** - * The default Redis port - */ - const DEFAULT_PORT = 6379; + /** + * The default Redis port + */ + const DEFAULT_PORT = 6379; - /** - * The default Redis Database number - */ - const DEFAULT_DATABASE = 0; + /** + * The default Redis Database number + */ + const DEFAULT_DATABASE = 0; - /** - * @var array List of all commands in Redis that supply a key as their - * first argument. Used to prefix keys with the Resque namespace. - */ - private $keyCommands = array( - 'exists', - 'del', - 'type', - 'keys', - 'expire', - 'ttl', - 'move', - 'set', - 'setex', - 'get', - 'getset', - 'setnx', - 'incr', - 'incrby', - 'decr', - 'decrby', - 'rpush', - 'lpush', - 'llen', - 'lrange', - 'ltrim', - 'lindex', - 'lset', - 'lrem', - 'lpop', - 'blpop', - 'rpop', - 'sadd', - 'srem', - 'spop', - 'scard', - 'sismember', - 'smembers', - 'srandmember', - 'zadd', - 'zrem', - 'zrange', - 'zrevrange', - 'zrangebyscore', - 'zcard', - 'zscore', - 'zremrangebyscore', - 'sort', - 'rename', - 'rpoplpush' - ); - // sinterstore - // sunion - // sunionstore - // sdiff - // sdiffstore - // sinter - // smove - // mget - // msetnx - // mset - // renamenx + /** + * @var array List of all commands in Redis that supply a key as their + * first argument. Used to prefix keys with the Resque namespace. + */ + private $keyCommands = [ + 'exists', + 'del', + 'type', + 'keys', + 'expire', + 'ttl', + 'move', + 'set', + 'setex', + 'get', + 'getset', + 'setnx', + 'incr', + 'incrby', + 'decr', + 'decrby', + 'rpush', + 'lpush', + 'llen', + 'lrange', + 'ltrim', + 'lindex', + 'lset', + 'lrem', + 'lpop', + 'blpop', + 'rpop', + 'sadd', + 'srem', + 'spop', + 'scard', + 'sismember', + 'smembers', + 'srandmember', + 'zadd', + 'zrem', + 'zrange', + 'zrevrange', + 'zrangebyscore', + 'zcard', + 'zscore', + 'zremrangebyscore', + 'sort', + 'rename', + 'rpoplpush' + ]; + // sinterstore + // sunion + // sunionstore + // sdiff + // sdiffstore + // sinter + // smove + // mget + // msetnx + // mset + // renamenx - /** - * Set Redis namespace (prefix) default: resque - * @param string $namespace - */ - public static function prefix($namespace) - { - if (substr($namespace, -1) !== ':' && $namespace != '') { - $namespace .= ':'; - } - self::$defaultNamespace = $namespace; - } + /** + * Set Redis namespace (prefix) default: resque + * @param string $namespace + */ + public static function prefix($namespace) + { + if (substr($namespace, -1) !== ':' && $namespace != '') { + $namespace .= ':'; + } + self::$defaultNamespace = $namespace; + } - /** - * @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 - */ + /** + * @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 + */ public function __construct($server, $database = null, $client = null) - { - try { - if (is_array($server)) { - $this->driver = new Credis_Cluster($server); - } - else if (is_object($client)) { - $this->driver = $client; - } - else { - list($host, $port, $dsnDatabase, $user, $password, $options) = self::parseDsn($server); - // $user is not used, only $password + { + try { + if (is_object($client)) { + $this->redisConnection = $client; + } else { + list($host, $port, $dsnDatabase, $user, $password, $options) = self::parseDsn($server); + // $user is not used, only $password - // Look for known Credis_Client options - $timeout = isset($options['timeout']) ? intval($options['timeout']) : null; - $persistent = isset($options['persistent']) ? $options['persistent'] : ''; - $maxRetries = isset($options['max_connect_retries']) ? $options['max_connect_retries'] : 0; + $timeout = isset($options['timeout']) ? intval($options['timeout']) : null; - $this->driver = new Credis_Client($host, $port, $timeout, $persistent); - $this->driver->setMaxConnectRetries($maxRetries); - if ($password){ - $this->driver->auth($password); - } + $this->redisConnection = new \Redis(); - // 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 (!$this->redisConnection->connect($host, $port, $timeout)) { + throw new RedisException("Connection Failed to Redis!"); + }; - if ($database !== null) { - $this->driver->select($database); - } - } - catch(CredisException $e) { - throw new Resque_RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e); - } - } + if ($password) { + $this->redisConnection->auth($password); + } - /** - * Parse a DSN string, which can have one of the following formats: - * - * - host:port - * - redis://user:pass@host:port/db?option1=val1&option2=val2 - * - tcp://user:pass@host:port/db?option1=val1&option2=val2 - * - unix:///path/to/redis.sock - * - * 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) - { - if ($dsn == '') { - // Use a sensible default for an empty DNS string - $dsn = 'redis://' . self::DEFAULT_HOST; - } - if(substr($dsn, 0, 7) === 'unix://') { - return array( - $dsn, - null, - false, - null, - null, - null, - ); - } - $parts = parse_url($dsn); + // 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; + } - // Check the URI scheme - $validSchemes = array('redis', 'tcp'); - if (isset($parts['scheme']) && ! in_array($parts['scheme'], $validSchemes)) { - throw new \InvalidArgumentException("Invalid DSN. Supported schemes are " . implode(', ', $validSchemes)); - } + if ($database) { + $this->redisConnection->select($database); + } + } + } catch (RedisException $e) { + throw new Resque_RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e); + } + } - // Allow simple 'hostname' format, which `parse_url` treats as a path, not host. - if ( ! isset($parts['host']) && isset($parts['path'])) { - $parts['host'] = $parts['path']; - unset($parts['path']); - } + /** + * Parse a DSN string, which can have one of the following formats: + * + * - host:port + * - redis://user:pass@host:port/db?option1=val1&option2=val2 + * - tcp://user:pass@host:port/db?option1=val1&option2=val2 + * - unix:///path/to/redis.sock + * + * 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) + { + if ($dsn == '') { + // Use a sensible default for an empty DNS string + $dsn = 'redis://' . self::DEFAULT_HOST; + } + if (substr($dsn, 0, 7) === 'unix://') { + return [ + $dsn, + null, + false, + null, + null, + null, + ]; + } + $parts = parse_url($dsn); - // Extract the port number as an integer - $port = isset($parts['port']) ? intval($parts['port']) : self::DEFAULT_PORT; + // Check the URI scheme + $validSchemes = array('redis', 'tcp'); + if (isset($parts['scheme']) && !in_array($parts['scheme'], $validSchemes)) { + throw new \InvalidArgumentException("Invalid DSN. Supported schemes are " . implode(', ', $validSchemes)); + } - // Get the database from the 'path' part of the URI - $database = false; - if (isset($parts['path'])) { - // Strip non-digit chars from path - $database = intval(preg_replace('/[^0-9]/', '', $parts['path'])); - } + // Allow simple 'hostname' format, which `parse_url` treats as a path, not host. + if (!isset($parts['host']) && isset($parts['path'])) { + $parts['host'] = $parts['path']; + unset($parts['path']); + } - // Extract any 'user' and 'pass' values - $user = isset($parts['user']) ? $parts['user'] : false; - $pass = isset($parts['pass']) ? $parts['pass'] : false; + // Extract the port number as an integer + $port = isset($parts['port']) ? intval($parts['port']) : self::DEFAULT_PORT; - // Convert the query string into an associative array - $options = array(); - if (isset($parts['query'])) { - // Parse the query string into an array - parse_str($parts['query'], $options); - } + // Get the database from the 'path' part of the URI + $database = false; + if (isset($parts['path'])) { + // Strip non-digit chars from path + $database = intval(preg_replace('/[^0-9]/', '', $parts['path'])); + } - return array( - $parts['host'], - $port, - $database, - $user, - $pass, - $options, - ); - } + // Extract any 'user' and 'pass' values + $user = isset($parts['user']) ? $parts['user'] : false; + $pass = isset($parts['pass']) ? $parts['pass'] : false; - /** - * Magic method to handle all function requests and prefix key based - * operations with the {self::$defaultNamespace} key prefix. - * - * @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. - */ - public function __call($name, $args) - { - if (in_array($name, $this->keyCommands)) { - if (is_array($args[0])) { - foreach ($args[0] AS $i => $v) { - $args[0][$i] = self::$defaultNamespace . $v; - } - } - else { - $args[0] = self::$defaultNamespace . $args[0]; - } - } - try { - return $this->driver->__call($name, $args); - } - catch (CredisException $e) { - throw new Resque_RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e); - } - } + // Convert the query string into an associative array + $options = array(); + if (isset($parts['query'])) { + // Parse the query string into an array + parse_str($parts['query'], $options); + } - public static function getPrefix() - { - return self::$defaultNamespace; - } + return array( + $parts['host'], + $port, + $database, + $user, + $pass, + $options, + ); + } - public static function removePrefix($string) - { - $prefix=self::getPrefix(); + /** + * Magic method to handle all function requests and prefix key based + * operations with the {self::$defaultNamespace} key prefix. + * + * @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. + */ + public function __call($name, $args) + { + if (in_array($name, $this->keyCommands)) { + if (is_array($args[0])) { + foreach ($args[0] AS $i => $v) { + $args[0][$i] = self::$defaultNamespace . $v; + } + } else { + $args[0] = self::$defaultNamespace . $args[0]; + } + } + } - if (substr($string, 0, strlen($prefix)) == $prefix) { - $string = substr($string, strlen($prefix), strlen($string) ); - } - return $string; - } + public static function getPrefix() + { + 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/lib/Resque/RedisException.php b/lib/Resque/RedisException.php index ca654a0..0c2294e 100644 --- a/lib/Resque/RedisException.php +++ b/lib/Resque/RedisException.php @@ -1,12 +1,14 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_RedisException extends Resque_Exception { + } -?> \ No newline at end of file diff --git a/lib/Resque/Stat.php b/lib/Resque/Stat.php index bc00c63..9855638 100644 --- a/lib/Resque/Stat.php +++ b/lib/Resque/Stat.php @@ -1,56 +1,58 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Stat + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_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. - */ - public static function get($stat) - { - return (int)Resque::redis()->get('stat:' . $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. + */ + public static function get($stat) + { + return (int)Resque::redis()->get('stat:' . $stat); + } - /** - * Increment the value of the specified statistic by a certain amount (default is 1) - * - * @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. - */ - public static function incr($stat, $by = 1) - { - return (bool)Resque::redis()->incrby('stat:' . $stat, $by); - } + /** + * Increment the value of the specified statistic by a certain amount (default is 1) + * + * @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. + */ + public static function incr($stat, $by = 1) + { + return (bool)Resque::redis()->incrby('stat:' . $stat, $by); + } - /** - * Decrement the value of the specified statistic by a certain amount (default is 1) - * - * @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. - */ - public static function decr($stat, $by = 1) - { - return (bool)Resque::redis()->decrby('stat:' . $stat, $by); - } + /** + * Decrement the value of the specified statistic by a certain amount (default is 1) + * + * @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. + */ + public static function decr($stat, $by = 1) + { + return (bool)Resque::redis()->decrby('stat:' . $stat, $by); + } - /** - * 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. - */ - public static function clear($stat) - { - return (bool)Resque::redis()->del('stat:' . $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. + */ + public static function clear($stat) + { + return (bool)Resque::redis()->del('stat:' . $stat); + } } \ No newline at end of file diff --git a/lib/Resque/Worker.php b/lib/Resque/Worker.php index 04714c1..af6c50c 100644 --- a/lib/Resque/Worker.php +++ b/lib/Resque/Worker.php @@ -1,55 +1,56 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Worker + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Worker { - /** - * @var LoggerInterface Logging object that impliments the PSR-3 LoggerInterface - */ - public $logger; + /** + * @var LoggerInterface Logging object that impliments the PSR-3 LoggerInterface + */ + public $logger; - /** - * @var array Array of all associated queues for this worker. - */ - private $queues = array(); + /** + * @var array Array of all associated queues for this worker. + */ + private $queues = array(); - /** - * @var string The hostname of this worker. - */ - private $hostname; + /** + * @var string The hostname of this worker. + */ + private $hostname; - /** - * @var boolean True if on the next iteration, the worker should shutdown. - */ - private $shutdown = false; + /** + * @var boolean True if on the next iteration, the worker should shutdown. + */ + private $shutdown = false; - /** - * @var boolean True if this worker is paused. - */ - private $paused = false; + /** + * @var boolean True if this worker is paused. + */ + private $paused = false; - /** - * @var string String identifying this worker. - */ - private $id; + /** + * @var string String identifying this worker. + */ + private $id; - /** - * @var Resque_Job Current job, if any, being processed by this worker. - */ - private $currentJob = null; + /** + * @var Resque_Job Current job, if any, being processed by this worker. + */ + private $currentJob = null; - /** - * @var int Process ID of child worker processes. - */ - private $child = null; + /** + * @var int Process ID of child worker processes. + */ + private $child = null; /** * Instantiate a new worker, given a list of queues that it should be working @@ -66,497 +67,491 @@ class Resque_Worker { $this->logger = new Resque_Log(); - if(!is_array($queues)) { + if (!is_array($queues)) { $queues = array($queues); } $this->queues = $queues; $this->hostname = php_uname('n'); - $this->id = $this->hostname . ':'.getmypid() . ':' . implode(',', $this->queues); + $this->id = $this->hostname . ':' . getmypid() . ':' . implode(',', $this->queues); } - /** - * Return all workers known to Resque as instantiated instances. - * @return array - */ - public static function all() - { - $workers = Resque::redis()->smembers('workers'); - if(!is_array($workers)) { - $workers = array(); - } + /** + * Return all workers known to Resque as instantiated instances. + * @return array + */ + public static function all() + { + $workers = Resque::redis()->smembers('workers'); + if (!is_array($workers)) { + $workers = array(); + } - $instances = array(); - foreach($workers as $workerId) { - $instances[] = self::find($workerId); - } - return $instances; - } + $instances = array(); + 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. - */ - public static function exists($workerId) - { - return (bool)Resque::redis()->sismember('workers', $workerId); - } + /** + * 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. + */ + public static function exists($workerId) + { + return (bool)Resque::redis()->sismember('workers', $workerId); + } - /** - * 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. - */ - public static function find($workerId) - { - if(!self::exists($workerId) || false === strpos($workerId, ":")) { - return false; - } + /** + * 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. + */ + public static function find($workerId) + { + if (!self::exists($workerId) || false === strpos($workerId, ":")) { + return false; + } - list($hostname, $pid, $queues) = explode(':', $workerId, 3); - $queues = explode(',', $queues); - $worker = new self($queues); - $worker->setId($workerId); - return $worker; - } + list($hostname, $pid, $queues) = explode(':', $workerId, 3); + $queues = explode(',', $queues); + $worker = new self($queues); + $worker->setId($workerId); + return $worker; + } - /** - * Set the ID of this worker to a given ID string. - * - * @param string $workerId ID for the worker. - */ - public function setId($workerId) - { - $this->id = $workerId; - } + /** + * Set the ID of this worker to a given ID string. + * + * @param string $workerId ID for the worker. + */ + public function setId($workerId) + { + $this->id = $workerId; + } - /** - * The primary loop for a worker which when called on an instance starts - * the worker's life cycle. - * - * Queues are checked every $interval (seconds) for new jobs. - * - * @param int $interval How often to check for new jobs across the queues. - */ - public function work($interval = Resque::DEFAULT_INTERVAL, $blocking = false) - { - $this->updateProcLine('Starting'); - $this->startup(); + /** + * The primary loop for a worker which when called on an instance starts + * the worker's life cycle. + * + * Queues are checked every $interval (seconds) for new jobs. + * + * @param int $interval How often to check for new jobs across the queues. + */ + public function work($interval = Resque::DEFAULT_INTERVAL, $blocking = false) + { + $this->updateProcLine('Starting'); + $this->startup(); - while(true) { - if($this->shutdown) { - break; - } + while (true) { + if ($this->shutdown) { + break; + } - // Attempt to find and reserve a job - $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); - } else { - $this->updateProcLine('Waiting for ' . implode(',', $this->queues) . ' with interval ' . $interval); - } + // Attempt to find and reserve a job + $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); + } else { + $this->updateProcLine('Waiting for ' . implode(',', $this->queues) . ' with interval ' . $interval); + } - $job = $this->reserve($blocking, $interval); - } + $job = $this->reserve($blocking, $interval); + } - if(!$job) { - // For an interval of 0, break now - helps with unit testing etc - if($interval == 0) { - break; - } + if (!$job) { + // For an interval of 0, break now - helps with unit testing etc + if ($interval == 0) { + break; + } - 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)); - if($this->paused) { - $this->updateProcLine('Paused'); - } - else { - $this->updateProcLine('Waiting for ' . implode(',', $this->queues)); - } + 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)); + if ($this->paused) { + $this->updateProcLine('Paused'); + } else { + $this->updateProcLine('Waiting for ' . implode(',', $this->queues)); + } - usleep($interval * 1000000); - } + usleep($interval * 1000000); + } - continue; - } + continue; + } - $this->logger->log(Psr\Log\LogLevel::NOTICE, 'Starting work on {job}', array('job' => $job)); - Resque_Event::trigger('beforeFork', $job); - $this->workingOn($job); + $this->logger->log(Psr\Log\LogLevel::NOTICE, 'Starting work on {job}', array('job' => $job)); + Resque_Event::trigger('beforeFork', $job); + $this->workingOn($job); - $this->child = Resque::fork(); + $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'); - $this->updateProcLine($status); - $this->logger->log(Psr\Log\LogLevel::INFO, $status); - $this->perform($job); - if ($this->child === 0) { - exit(0); - } - } + // Forked and we're the child. Run the job. + if ($this->child === 0 || $this->child === false) { + $status = 'Processing ' . $job->queue . ' since ' . strftime('%F %T'); + $this->updateProcLine($status); + $this->logger->log(Psr\Log\LogLevel::INFO, $status); + $this->perform($job); + if ($this->child === 0) { + exit(0); + } + } - if($this->child > 0) { - // Parent process, sit and wait - $status = 'Forked ' . $this->child . ' at ' . strftime('%F %T'); - $this->updateProcLine($status); - $this->logger->log(Psr\Log\LogLevel::INFO, $status); + if ($this->child > 0) { + // Parent process, sit and wait + $status = 'Forked ' . $this->child . ' at ' . strftime('%F %T'); + $this->updateProcLine($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 exited with exit code ' . $exitStatus - )); - } - } + // 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 exited with exit code ' . $exitStatus + )); + } + } - $this->child = null; - $this->doneWorking(); - } + $this->child = null; + $this->doneWorking(); + } - $this->unregisterWorker(); - } + $this->unregisterWorker(); + } - /** - * Process a single job. - * - * @param Resque_Job $job The job to be processed. - */ - public function perform(Resque_Job $job) - { - try { - Resque_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)); - $job->fail($e); - return; - } + /** + * Process a single job. + * + * @param Resque_Job $job The job to be processed. + */ + public function perform(Resque_Job $job) + { + try { + Resque_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)); + $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', array('job' => $job)); + } - /** - * @param bool $blocking - * @param int $timeout - * @return object|boolean Instance of Resque_Job if a job is found, false if not. - */ - public function reserve($blocking = false, $timeout = null) - { - $queues = $this->queues(); - if(!is_array($queues)) { - return; - } + /** + * @param bool $blocking + * @param int $timeout + * @return object|boolean Instance of Resque_Job if a job is found, false if not. + */ + public function reserve($blocking = false, $timeout = null) + { + $queues = $this->queues(); + if (!is_array($queues)) { + return; + } - 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)); - 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)); - return $job; - } - } - } + 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)); + 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)); + return $job; + } + } + } - return false; - } + return false; + } - /** - * Return an array containing all of the queues that this worker should use - * when searching for jobs. - * - * If * is found in the list of queues, every queue will be searched in - * alphabetic order. (@see $fetch) - * - * @param boolean $fetch If true, and the queue is set to *, will fetch - * all queue names from redis. - * @return array Array of associated queues. - */ - public function queues($fetch = true) - { - if(!in_array('*', $this->queues) || $fetch == false) { - return $this->queues; - } + /** + * Return an array containing all of the queues that this worker should use + * when searching for jobs. + * + * If * is found in the list of queues, every queue will be searched in + * alphabetic order. (@see $fetch) + * + * @param boolean $fetch If true, and the queue is set to *, will fetch + * all queue names from redis. + * @return array Array of associated queues. + */ + public function queues($fetch = true) + { + if (!in_array('*', $this->queues) || $fetch == false) { + return $this->queues; + } - $queues = Resque::queues(); - sort($queues); - return $queues; - } + $queues = Resque::queues(); + sort($queues); + return $queues; + } - /** - * Perform necessary actions to start a worker. - */ - private function startup() - { - $this->registerSigHandlers(); - $this->pruneDeadWorkers(); - Resque_Event::trigger('beforeFirstFork', $this); - $this->registerWorker(); - } + /** + * Perform necessary actions to start a worker. + */ + private function startup() + { + $this->registerSigHandlers(); + $this->pruneDeadWorkers(); + Resque_Event::trigger('beforeFirstFork', $this); + $this->registerWorker(); + } - /** - * On supported systems (with the PECL proctitle module installed), update - * the name of the currently running process to indicate the current state - * of a worker. - * - * @param string $status The updated process title. - */ - private function updateProcLine($status) - { - $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')) { - setproctitle($processTitle); - } - } + /** + * On supported systems (with the PECL proctitle module installed), update + * the name of the currently running process to indicate the current state + * of a worker. + * + * @param string $status The updated process title. + */ + private function updateProcLine($status) + { + $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')) { + setproctitle($processTitle); + } + } - /** - * Register signal handlers that a worker should respond to. - * - * TERM: Shutdown immediately and stop processing jobs. - * 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. - */ - private function registerSigHandlers() - { - if(!function_exists('pcntl_signal')) { - return; - } + /** + * Register signal handlers that a worker should respond to. + * + * TERM: Shutdown immediately and stop processing jobs. + * 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. + */ + private function registerSigHandlers() + { + 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, 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'); + } - /** - * Signal handler callback for USR2, pauses processing of new jobs. - */ - public function pauseProcessing() - { - $this->logger->log(Psr\Log\LogLevel::NOTICE, 'USR2 received; pausing job processing'); - $this->paused = true; - } + /** + * Signal handler callback for USR2, pauses processing of new jobs. + */ + public function pauseProcessing() + { + $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. - */ - public function unPauseProcessing() - { - $this->logger->log(Psr\Log\LogLevel::NOTICE, 'CONT received; resuming job processing'); - $this->paused = false; - } + /** + * Signal handler callback for CONT, resumes worker allowing it to pick + * up new jobs. + */ + public function unPauseProcessing() + { + $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. - */ - public function shutdown() - { - $this->shutdown = true; - $this->logger->log(Psr\Log\LogLevel::NOTICE, 'Shutting down'); - } + /** + * Schedule a worker for shutdown. Will finish processing the current job + * and when the timeout interval is reached, the worker will shut down. + */ + public function shutdown() + { + $this->shutdown = true; + $this->logger->log(Psr\Log\LogLevel::NOTICE, 'Shutting down'); + } - /** - * Force an immediate shutdown of the worker, killing any child jobs - * currently running. - */ - public function shutdownNow() - { - $this->shutdown(); - $this->killChild(); - } + /** + * Force an immediate shutdown of the worker, killing any child jobs + * currently running. + */ + public function shutdownNow() + { + $this->shutdown(); + $this->killChild(); + } - /** - * Kill a forked child job immediately. The job it is processing will not - * be completed. - */ - public function killChild() - { - if(!$this->child) { - $this->logger->log(Psr\Log\LogLevel::DEBUG, 'No child to kill.'); - return; - } + /** + * Kill a forked child job immediately. The job it is processing will not + * be completed. + */ + public function killChild() + { + if (!$this->child) { + $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)); - 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)); - 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->shutdown(); - } - } + $this->logger->log(Psr\Log\LogLevel::INFO, 'Killing child at {child}', array('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)); + 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->shutdown(); + } + } - /** - * Look for any workers which should be running on this server and if - * they're not, remove them from Redis. - * - * 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. - */ - public function pruneDeadWorkers() - { - $workerPids = $this->workerPids(); - $workers = self::all(); - foreach($workers as $worker) { - if (is_object($worker)) { - list($host, $pid, $queues) = explode(':', (string)$worker, 3); - 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)); - $worker->unregisterWorker(); - } - } - } + /** + * Look for any workers which should be running on this server and if + * they're not, remove them from Redis. + * + * 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. + */ + public function pruneDeadWorkers() + { + $workerPids = $this->workerPids(); + $workers = self::all(); + foreach ($workers as $worker) { + if (is_object($worker)) { + list($host, $pid, $queues) = explode(':', (string)$worker, 3); + 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)); + $worker->unregisterWorker(); + } + } + } - /** - * Return an array of process IDs for all of the Resque workers currently - * running on this machine. - * - * @return array Array of Resque worker process IDs. - */ - public function workerPids() - { - $pids = array(); - exec('ps -A -o pid,command | grep [r]esque', $cmdOutput); - foreach($cmdOutput as $line) { - list($pids[],) = explode(' ', trim($line), 2); - } - return $pids; - } + /** + * Return an array of process IDs for all of the Resque workers currently + * running on this machine. + * + * @return array Array of Resque worker process IDs. + */ + public function workerPids() + { + $pids = array(); + exec('ps -A -o pid,command | grep [r]esque', $cmdOutput); + foreach ($cmdOutput as $line) { + list($pids[],) = explode(' ', trim($line), 2); + } + return $pids; + } - /** - * Register this worker in Redis. - */ - public function registerWorker() - { - Resque::redis()->sadd('workers', (string)$this); - Resque::redis()->set('worker:' . (string)$this . ':started', strftime('%a %b %d %H:%M:%S %Z %Y')); - } + /** + * Register this worker in Redis. + */ + public function registerWorker() + { + Resque::redis()->sadd('workers', (string)$this); + Resque::redis()->set('worker:' . (string)$this . ':started', strftime('%a %b %d %H:%M:%S %Z %Y')); + } - /** - * Unregister this worker in Redis. (shutdown etc) - */ - public function unregisterWorker() - { - if(is_object($this->currentJob)) { - $this->currentJob->fail(new Resque_Job_DirtyExitException); - } + /** + * Unregister this worker in Redis. (shutdown etc) + */ + public function unregisterWorker() + { + if (is_object($this->currentJob)) { + $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); - } + $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); + } - /** - * Tell Redis which job we're currently working on. - * - * @param object $job Resque_Job instance containing the job we're working on. - */ - public function workingOn(Resque_Job $job) - { - $job->worker = $this; - $this->currentJob = $job; - $job->updateStatus(Resque_Job_Status::STATUS_RUNNING); - $data = json_encode(array( - 'queue' => $job->queue, - 'run_at' => strftime('%a %b %d %H:%M:%S %Z %Y'), - 'payload' => $job->payload - )); - Resque::redis()->set('worker:' . $job->worker, $data); - } + /** + * Tell Redis which job we're currently working on. + * + * @param object $job Resque_Job instance containing the job we're working on. + */ + public function workingOn(Resque_Job $job) + { + $job->worker = $this; + $this->currentJob = $job; + $job->updateStatus(Resque_Job_Status::STATUS_RUNNING); + $data = json_encode(array( + 'queue' => $job->queue, + 'run_at' => strftime('%a %b %d %H:%M:%S %Z %Y'), + 'payload' => $job->payload + )); + Resque::redis()->set('worker:' . $job->worker, $data); + } - /** - * Notify Redis that we've finished working on a job, clearing the working - * state and incrementing the job stats. - */ - public function doneWorking() - { - $this->currentJob = null; - Resque_Stat::incr('processed'); - Resque_Stat::incr('processed:' . (string)$this); - Resque::redis()->del('worker:' . (string)$this); - } + /** + * Notify Redis that we've finished working on a job, clearing the working + * state and incrementing the job stats. + */ + public function doneWorking() + { + $this->currentJob = null; + Resque_Stat::incr('processed'); + Resque_Stat::incr('processed:' . (string)$this); + Resque::redis()->del('worker:' . (string)$this); + } - /** - * Generate a string representation of this worker. - * - * @return string String identifier for this worker instance. - */ - public function __toString() - { - return $this->id; - } + /** + * Generate a string representation of this worker. + * + * @return string String identifier for this worker instance. + */ + public function __toString() + { + return $this->id; + } - /** - * Return an object describing the job this worker is currently working on. - * - * @return object Object with details of current job. - */ - public function job() - { - $job = Resque::redis()->get('worker:' . $this); - if(!$job) { - return array(); - } - else { - return json_decode($job, true); - } - } + /** + * Return an object describing the job this worker is currently working on. + * + * @return object Object with details of current job. + */ + public function job() + { + $job = Resque::redis()->get('worker:' . $this); + if (!$job) { + return array(); + } else { + return json_decode($job, true); + } + } - /** - * Get a statistic belonging to this worker. - * - * @param string $stat Statistic to fetch. - * @return int Statistic value. - */ - public function getStat($stat) - { - return Resque_Stat::get($stat . ':' . $this); - } + /** + * Get a statistic belonging to this worker. + * + * @param string $stat Statistic to fetch. + * @return int Statistic value. + */ + public function getStat($stat) + { + return Resque_Stat::get($stat . ':' . $this); + } - /** - * Inject the logging object into the worker - * - * @param Psr\Log\LoggerInterface $logger - */ - public function setLogger(Psr\Log\LoggerInterface $logger) - { - $this->logger = $logger; - } + /** + * Inject the logging object into the worker + * + * @param Psr\Log\LoggerInterface $logger + */ + public function setLogger(Psr\Log\LoggerInterface $logger) + { + $this->logger = $logger; + } } diff --git a/test/Resque/Tests/EventTest.php b/test/Resque/Tests/EventTest.php index 6e102cf..cbb13d8 100644 --- a/test/Resque/Tests/EventTest.php +++ b/test/Resque/Tests/EventTest.php @@ -1,199 +1,201 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Tests + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Tests_EventTest extends Resque_Tests_TestCase { - private $callbacksHit = array(); + private $callbacksHit = array(); - public function setUp() - { - Test_Job::$called = false; + public function setUp() + { + Test_Job::$called = false; - // Register a worker to test with - $this->worker = new Resque_Worker('jobs'); - $this->worker->setLogger(new Resque_Log()); - $this->worker->registerWorker(); - } + // Register a worker to test with + $this->worker = new Resque_Worker('jobs'); + $this->worker->setLogger(new Resque_Log()); + $this->worker->registerWorker(); + } - public function tearDown() - { - Resque_Event::clearListeners(); - $this->callbacksHit = array(); - } + public function tearDown() + { + Resque_Event::clearListeners(); + $this->callbacksHit = array(); + } - public function getEventTestJob() - { - $payload = array( - 'class' => 'Test_Job', - 'args' => array( - array('somevar'), - ), - ); - $job = new Resque_Job('jobs', $payload); - $job->worker = $this->worker; - return $job; - } + public function getEventTestJob() + { + $payload = array( + 'class' => 'Test_Job', + 'args' => array( + array('somevar'), + ), + ); + $job = new Resque_Job('jobs', $payload); + $job->worker = $this->worker; + return $job; + } - public function eventCallbackProvider() - { - return array( - array('beforePerform', 'beforePerformEventCallback'), - array('afterPerform', 'afterPerformEventCallback'), - array('afterFork', 'afterForkEventCallback'), - ); - } + public function eventCallbackProvider() + { + return array( + array('beforePerform', 'beforePerformEventCallback'), + array('afterPerform', 'afterPerformEventCallback'), + array('afterFork', 'afterForkEventCallback'), + ); + } - /** - * @dataProvider eventCallbackProvider - */ - public function testEventCallbacksFire($event, $callback) - { - Resque_Event::listen($event, array($this, $callback)); + /** + * @dataProvider eventCallbackProvider + */ + public function testEventCallbacksFire($event, $callback) + { + Resque_Event::listen($event, array($this, $callback)); - $job = $this->getEventTestJob(); - $this->worker->perform($job); - $this->worker->work(0); + $job = $this->getEventTestJob(); + $this->worker->perform($job); + $this->worker->work(0); - $this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback .') was not called'); - } + $this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called'); + } - public function testBeforeForkEventCallbackFires() - { - $event = 'beforeFork'; - $callback = 'beforeForkEventCallback'; + public function testBeforeForkEventCallbackFires() + { + $event = 'beforeFork'; + $callback = 'beforeForkEventCallback'; - Resque_Event::listen($event, array($this, $callback)); - Resque::enqueue('jobs', 'Test_Job', array( - 'somevar' - )); - $job = $this->getEventTestJob(); - $this->worker->work(0); - $this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback .') was not called'); - } + Resque_Event::listen($event, array($this, $callback)); + Resque::enqueue('jobs', 'Test_Job', array( + 'somevar' + )); + $job = $this->getEventTestJob(); + $this->worker->work(0); + $this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called'); + } - public function testBeforeEnqueueEventCallbackFires() - { - $event = 'beforeEnqueue'; - $callback = 'beforeEnqueueEventCallback'; + public function testBeforeEnqueueEventCallbackFires() + { + $event = 'beforeEnqueue'; + $callback = 'beforeEnqueueEventCallback'; - Resque_Event::listen($event, array($this, $callback)); - Resque::enqueue('jobs', 'Test_Job', array( - 'somevar' - )); - $this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback .') was not called'); - } + Resque_Event::listen($event, array($this, $callback)); + Resque::enqueue('jobs', 'Test_Job', array( + 'somevar' + )); + $this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called'); + } - public function testBeforePerformEventCanStopWork() - { - $callback = 'beforePerformEventDontPerformCallback'; - Resque_Event::listen('beforePerform', array($this, $callback)); + public function testBeforePerformEventCanStopWork() + { + $callback = 'beforePerformEventDontPerformCallback'; + Resque_Event::listen('beforePerform', array($this, $callback)); - $job = $this->getEventTestJob(); + $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($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'); + } - public function testBeforeEnqueueEventStopsJobCreation() - { - $callback = 'beforeEnqueueEventDontCreateCallback'; - Resque_Event::listen('beforeEnqueue', array($this, $callback)); - Resque_Event::listen('afterEnqueue', array($this, 'afterEnqueueEventCallback')); + public function testBeforeEnqueueEventStopsJobCreation() + { + $callback = 'beforeEnqueueEventDontCreateCallback'; + Resque_Event::listen('beforeEnqueue', array($this, $callback)); + Resque_Event::listen('afterEnqueue', array($this, 'afterEnqueueEventCallback')); - $result = Resque::enqueue('test_job', '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); - } + $result = Resque::enqueue('test_job', '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); + } - public function testAfterEnqueueEventCallbackFires() - { - $callback = 'afterEnqueueEventCallback'; - $event = 'afterEnqueue'; + public function testAfterEnqueueEventCallbackFires() + { + $callback = 'afterEnqueueEventCallback'; + $event = 'afterEnqueue'; - Resque_Event::listen($event, array($this, $callback)); - Resque::enqueue('jobs', 'Test_Job', array( - 'somevar' - )); - $this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback .') was not called'); - } + Resque_Event::listen($event, array($this, $callback)); + Resque::enqueue('jobs', 'Test_Job', array( + 'somevar' + )); + $this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called'); + } - public function testStopListeningRemovesListener() - { - $callback = 'beforePerformEventCallback'; - $event = 'beforePerform'; + public function testStopListeningRemovesListener() + { + $callback = 'beforePerformEventCallback'; + $event = 'beforePerform'; - Resque_Event::listen($event, array($this, $callback)); - Resque_Event::stopListening($event, array($this, $callback)); + Resque_Event::listen($event, array($this, $callback)); + Resque_Event::stopListening($event, array($this, $callback)); - $job = $this->getEventTestJob(); - $this->worker->perform($job); - $this->worker->work(0); + $job = $this->getEventTestJob(); + $this->worker->perform($job); + $this->worker->work(0); - $this->assertNotContains($callback, $this->callbacksHit, - $event . ' callback (' . $callback .') was called though Resque_Event::stopListening was called' - ); - } + $this->assertNotContains($callback, $this->callbacksHit, + $event . ' callback (' . $callback . ') was called though Resque_Event::stopListening was called' + ); + } - public function beforePerformEventDontPerformCallback($instance) - { - $this->callbacksHit[] = __FUNCTION__; - throw new Resque_Job_DontPerform; - } + public function beforePerformEventDontPerformCallback($instance) + { + $this->callbacksHit[] = __FUNCTION__; + throw new Resque_Job_DontPerform; + } - public function beforeEnqueueEventDontCreateCallback($queue, $class, $args, $track = false) - { - $this->callbacksHit[] = __FUNCTION__; - throw new Resque_Job_DontCreate; - } + public function beforeEnqueueEventDontCreateCallback($queue, $class, $args, $track = false) + { + $this->callbacksHit[] = __FUNCTION__; + 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'); - } - $args = $job->getArguments(); - $this->assertEquals($args[0], 'somevar'); - } + 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'); + } + $args = $job->getArguments(); + $this->assertEquals($args[0], 'somevar'); + } - public function afterEnqueueEventCallback($class, $args) - { - $this->callbacksHit[] = __FUNCTION__; - $this->assertEquals('Test_Job', $class); - $this->assertEquals(array( - 'somevar', - ), $args); - } + public function afterEnqueueEventCallback($class, $args) + { + $this->callbacksHit[] = __FUNCTION__; + $this->assertEquals('Test_Job', $class); + $this->assertEquals(array( + 'somevar', + ), $args); + } - public function beforeEnqueueEventCallback($job) - { - $this->callbacksHit[] = __FUNCTION__; - } + public function beforeEnqueueEventCallback($job) + { + $this->callbacksHit[] = __FUNCTION__; + } - public function beforePerformEventCallback($job) - { - $this->assertValidEventCallback(__FUNCTION__, $job); - } + public function beforePerformEventCallback($job) + { + $this->assertValidEventCallback(__FUNCTION__, $job); + } - public function afterPerformEventCallback($job) - { - $this->assertValidEventCallback(__FUNCTION__, $job); - } + public function afterPerformEventCallback($job) + { + $this->assertValidEventCallback(__FUNCTION__, $job); + } - public function beforeForkEventCallback($job) - { - $this->assertValidEventCallback(__FUNCTION__, $job); - } + public function beforeForkEventCallback($job) + { + $this->assertValidEventCallback(__FUNCTION__, $job); + } - public function afterForkEventCallback($job) - { - $this->assertValidEventCallback(__FUNCTION__, $job); - } + public function afterForkEventCallback($job) + { + $this->assertValidEventCallback(__FUNCTION__, $job); + } } diff --git a/test/Resque/Tests/JobStatusTest.php b/test/Resque/Tests/JobStatusTest.php index d751c37..d3ab197 100644 --- a/test/Resque/Tests/JobStatusTest.php +++ b/test/Resque/Tests/JobStatusTest.php @@ -1,11 +1,13 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Tests + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Tests_JobStatusTest extends Resque_Tests_TestCase { /** @@ -13,94 +15,94 @@ class Resque_Tests_JobStatusTest extends Resque_Tests_TestCase */ protected $worker; - public function setUp() - { - parent::setUp(); + public function setUp() + { + parent::setUp(); - // Register a worker to test with - $this->worker = new Resque_Worker('jobs'); - $this->worker->setLogger(new Resque_Log()); - } + // 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 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 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 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 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 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 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 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 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(); + 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); + // 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(); + // Now recreate it + $newToken = $job->recreate(); - // Make sure we've got a new job returned - $this->assertNotEquals($originalToken, $newToken); + // 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()); - } + // 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 index fb55d13..3101ff6 100644 --- a/test/Resque/Tests/JobTest.php +++ b/test/Resque/Tests/JobTest.php @@ -3,444 +3,446 @@ /** * Resque_Job tests. * - * @package Resque/Tests - * @author Chris Boulton - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Tests + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Tests_JobTest extends Resque_Tests_TestCase { - protected $worker; + protected $worker; - public function setUp() - { - parent::setUp(); + 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(); - } + // 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 testJobCanBeQueued() + { + $this->assertTrue((bool)Resque::enqueue('jobs', 'Test_Job')); + } /** * @expectedException Resque_RedisException */ - public function testRedisErrorThrowsExceptionOnJobCreation() - { - $mockCredis = $this->getMockBuilder('Credis_Client') - ->setMethods(['connect', '__call']) - ->getMock(); - $mockCredis->expects($this->any())->method('__call') - ->will($this->throwException(new CredisException('failure'))); +// public function testRedisErrorThrowsExceptionOnJobCreation() +// { +// $mockCredis = $this->getMockBuilder('Credis_Client') +// ->setMethods(['connect', '__call']) +// ->getMock(); +// $mockCredis->expects($this->any())->method('__call') +// ->will($this->throwException(new CredisException('failure'))); +// +// Resque::setBackend(function($database) use ($mockCredis) { +// return new Resque_Redis('localhost:6379', $database, $mockCredis); +// }); +// Resque::enqueue('jobs', 'This is a test'); +// } - Resque::setBackend(function($database) use ($mockCredis) { - return new Resque_Redis('localhost:6379', $database, $mockCredis); - }); - Resque::enqueue('jobs', 'This is a test'); - } + public function testQeueuedJobCanBeReserved() + { + 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']); + } - $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); + } - /** - * @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'); - 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()); + } - $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 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' + ), + ); - 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'); - Resque::enqueue('jobs', 'Test_Job', $args); - $job = Resque_Job::reserve('jobs'); + // Now recreate it + $job->recreate(); - // Now recreate it - $job->recreate(); - - $newJob = Resque_Job::reserve('jobs'); - $this->assertEquals($job->payload['class'], $newJob->payload['class']); - $this->assertEquals($job->getArguments(), $newJob->getArguments()); - } + $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; + 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->worker->perform($job); - $this->assertEquals(1, Resque_Stat::get('failed')); - $this->assertEquals(1, Resque_Stat::get('failed:'.$this->worker)); - } + $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 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); - } + /** + * @expectedException Resque_Exception + */ + public function testInvalidJobThrowsException() + { + Resque::enqueue('jobs', 'Invalid_Job'); + $job = $this->worker->reserve(); + $job->worker = $this->worker; + $job->perform(); + } - 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:'), - ); + public function testJobWithSetUpCallbackFiresSetUp() + { + $payload = array( + 'class' => 'Test_Job_With_SetUp', + 'args' => array( + 'somevar', + 'somevar2', + ), + ); + $job = new Resque_Job('jobs', $payload); + $job->perform(); - foreach($fixture as $item) { - Resque_Redis::prefix($item['test']); - $this->assertEquals(Resque_Redis::getPrefix(), $item['assertValue']); - } - } + $this->assertTrue(Test_Job_With_SetUp::$called); + } - public function testJobWithNamespace() - { - Resque_Redis::prefix('php'); - $queue = 'jobs'; - $payload = array('another_value'); - Resque::enqueue($queue, 'Test_Job_With_TearDown', $payload); + public function testJobWithTearDownCallbackFiresTearDown() + { + $payload = array( + 'class' => 'Test_Job_With_TearDown', + 'args' => array( + 'somevar', + 'somevar2', + ), + ); + $job = new Resque_Job('jobs', $payload); + $job->perform(); - $this->assertEquals(Resque::queues(), array('jobs')); - $this->assertEquals(Resque::size($queue), 1); + $this->assertTrue(Test_Job_With_TearDown::$called); + } - Resque_Redis::prefix('resque'); - $this->assertEquals(Resque::size($queue), 0); - } + 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:'), + ); - 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); - } + foreach ($fixture as $item) { + Resque_Redis::prefix($item['test']); + $this->assertEquals(Resque_Redis::getPrefix(), $item['assertValue']); + } + } - 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 testJobWithNamespace() + { + Resque_Redis::prefix('php'); + $queue = 'jobs'; + $payload = array('another_value'); + Resque::enqueue($queue, 'Test_Job_With_TearDown', $payload); - 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); - } + $this->assertEquals(Resque::queues(), array('jobs')); + $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); - } + Resque_Redis::prefix('resque'); + $this->assertEquals(Resque::size($queue), 0); + } - 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 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 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 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 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 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 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 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 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 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 testDequeueItemWithArg() - { - $queue = 'jobs'; - $arg = array('foo' => 1, 'bar' => 2); - Resque::enqueue($queue, 'Test_Job_Dequeue9'); - Resque::enqueue($queue, 'Test_Job_Dequeue9', $arg); - $this->assertEquals(Resque::size($queue), 2); - $test = array('Test_Job_Dequeue9' => $arg); - $this->assertEquals(Resque::dequeue($queue, $test), 1); - #$this->assertEquals(Resque::size($queue), 1); - } - - public function testDequeueSeveralItemsWithArgs() - { - // GIVEN - $queue = 'jobs'; - $args = array('foo' => 1, 'bar' => 10); - $removeArgs = array('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); - - // WHEN - $test = array('Test_Job_Dequeue9' => $removeArgs); - $removedItems = Resque::dequeue($queue, $test); - - // THEN - $this->assertEquals($removedItems, 2); - $this->assertEquals(Resque::size($queue), 1); - $item = Resque::pop($queue); - $this->assertInternalType('array', $item['args']); - $this->assertEquals(10, $item['args'][0]['bar'], 'Wrong items were dequeued from queue!'); - } + 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 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 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 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 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 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 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 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); - } + public function testDequeueItemWithArg() + { + $queue = 'jobs'; + $arg = array('foo' => 1, 'bar' => 2); + Resque::enqueue($queue, 'Test_Job_Dequeue9'); + Resque::enqueue($queue, 'Test_Job_Dequeue9', $arg); + $this->assertEquals(Resque::size($queue), 2); + $test = array('Test_Job_Dequeue9' => $arg); + $this->assertEquals(Resque::dequeue($queue, $test), 1); + #$this->assertEquals(Resque::size($queue), 1); + } - public function testDoNotUseFactoryToGetInstance() - { - $payload = array( - 'class' => 'Some_Job_Class', - 'args' => array(array()) - ); - $job = new Resque_Job('jobs', $payload); - $factory = $this->getMock('Resque_Job_FactoryInterface'); - $testJob = $this->getMock('Resque_JobInterface'); - $factory->expects(self::never())->method('create')->will(self::returnValue($testJob)); - $instance = $job->getInstance(); - $this->assertInstanceOf('Resque_JobInterface', $instance); - } + public function testDequeueSeveralItemsWithArgs() + { + // GIVEN + $queue = 'jobs'; + $args = array('foo' => 1, 'bar' => 10); + $removeArgs = array('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); + + // WHEN + $test = array('Test_Job_Dequeue9' => $removeArgs); + $removedItems = Resque::dequeue($queue, $test); + + // THEN + $this->assertEquals($removedItems, 2); + $this->assertEquals(Resque::size($queue), 1); + $item = Resque::pop($queue); + $this->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); + } + + public function testDoNotUseFactoryToGetInstance() + { + $payload = array( + 'class' => 'Some_Job_Class', + 'args' => array(array()) + ); + $job = new Resque_Job('jobs', $payload); + $factory = $this->getMock('Resque_Job_FactoryInterface'); + $testJob = $this->getMock('Resque_JobInterface'); + $factory->expects(self::never())->method('create')->will(self::returnValue($testJob)); + $instance = $job->getInstance(); + $this->assertInstanceOf('Resque_JobInterface', $instance); + } } class Some_Job_Class implements Resque_JobInterface { - /** - * @return bool - */ - public function perform() - { - return true; - } + /** + * @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(); - } + /** + * @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/LogTest.php b/test/Resque/Tests/LogTest.php index db97b16..05310eb 100644 --- a/test/Resque/Tests/LogTest.php +++ b/test/Resque/Tests/LogTest.php @@ -1,31 +1,33 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Tests + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Tests_LogTest extends Resque_Tests_TestCase { - public function testLogInterpolate() - { - $logger = new Resque_Log(); - $actual = $logger->interpolate('string {replace}', array('replace' => 'value')); - $expected = 'string value'; + public function testLogInterpolate() + { + $logger = new Resque_Log(); + $actual = $logger->interpolate('string {replace}', array('replace' => 'value')); + $expected = 'string value'; - $this->assertEquals($expected, $actual); - } + $this->assertEquals($expected, $actual); + } - public function testLogInterpolateMutiple() - { - $logger = new Resque_Log(); - $actual = $logger->interpolate( - 'string {replace1} {replace2}', - array('replace1' => 'value1', 'replace2' => 'value2') - ); - $expected = 'string value1 value2'; + public function testLogInterpolateMutiple() + { + $logger = new Resque_Log(); + $actual = $logger->interpolate( + 'string {replace1} {replace2}', + array('replace1' => 'value1', 'replace2' => 'value2') + ); + $expected = 'string value1 value2'; - $this->assertEquals($expected, $actual); - } + $this->assertEquals($expected, $actual); + } } diff --git a/test/Resque/Tests/RedisTest.php b/test/Resque/Tests/RedisTest.php index 55b5e17..6bc4047 100644 --- a/test/Resque/Tests/RedisTest.php +++ b/test/Resque/Tests/RedisTest.php @@ -1,197 +1,199 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Tests + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Tests_RedisTest extends Resque_Tests_TestCase { /** * @expectedException Resque_RedisException */ - public function testRedisExceptionsAreSurfaced() - { - $mockCredis = $this->getMockBuilder('Credis_Client') - ->setMethods(['connect', '__call']) - ->getMock(); - $mockCredis->expects($this->any())->method('__call') - ->will($this->throwException(new CredisException('failure'))); +// public function testRedisExceptionsAreSurfaced() +// { +// $mockCredis = $this->getMockBuilder('Credis_Client') +// ->setMethods(['connect', '__call']) +// ->getMock(); +// $mockCredis->expects($this->any())->method('__call') +// ->will($this->throwException(new CredisException('failure'))); +// +// Resque::setBackend(function($database) use ($mockCredis) { +// return new Resque_Redis('localhost:6379', $database, $mockCredis); +// }); +// Resque::redis()->ping(); +// } - Resque::setBackend(function($database) use ($mockCredis) { - return new Resque_Redis('localhost:6379', $database, $mockCredis); - }); - Resque::redis()->ping(); - } + /** + * These DNS strings are considered valid. + * + * @return array + */ + public function validDsnStringProvider() + { + return [ + // Input , Expected output + ['', [ + 'localhost', + Resque_Redis::DEFAULT_PORT, + false, + false, false, + [], + ]], + ['localhost', [ + 'localhost', + Resque_Redis::DEFAULT_PORT, + false, + false, false, + [], + ]], + ['localhost:1234', [ + 'localhost', + 1234, + false, + false, false, + [], + ]], + ['localhost:1234/2', [ + 'localhost', + 1234, + 2, + false, false, + [], + ]], + ['redis://foobar', [ + 'foobar', + Resque_Redis::DEFAULT_PORT, + false, + false, false, + [], + ]], + ['redis://foobar/', [ + 'foobar', + Resque_Redis::DEFAULT_PORT, + false, + false, false, + [], + ]], + ['redis://foobar:1234', [ + 'foobar', + 1234, + false, + false, false, + [], + ]], + ['redis://foobar:1234/15', [ + 'foobar', + 1234, + 15, + false, false, + [], + ]], + ['redis://foobar:1234/0', [ + 'foobar', + 1234, + 0, + false, false, + [], + ]], + ['redis://user@foobar:1234', [ + 'foobar', + 1234, + false, + 'user', false, + [], + ]], + ['redis://user@foobar:1234/15', [ + 'foobar', + 1234, + 15, + 'user', false, + [], + ]], + ['redis://user:pass@foobar:1234', [ + 'foobar', + 1234, + false, + 'user', 'pass', + [], + ]], + ['redis://user:pass@foobar:1234?x=y&a=b', [ + 'foobar', + 1234, + false, + 'user', 'pass', + ['x' => 'y', 'a' => 'b'], + ]], + ['redis://:pass@foobar:1234?x=y&a=b', [ + 'foobar', + 1234, + false, + false, 'pass', + ['x' => 'y', 'a' => 'b'], + ]], + ['redis://user@foobar:1234?x=y&a=b', [ + 'foobar', + 1234, + false, + 'user', false, + ['x' => 'y', 'a' => 'b'], + ]], + ['redis://foobar:1234?x=y&a=b', [ + 'foobar', + 1234, + false, + false, false, + ['x' => 'y', 'a' => 'b'], + ]], + ['redis://user@foobar:1234/12?x=y&a=b', [ + 'foobar', + 1234, + 12, + 'user', false, + ['x' => 'y', 'a' => 'b'], + ]], + ['tcp://user@foobar:1234/12?x=y&a=b', [ + 'foobar', + 1234, + 12, + 'user', false, + ['x' => 'y', 'a' => 'b'], + ]], + ]; + } - /** - * These DNS strings are considered valid. - * - * @return array - */ - public function validDsnStringProvider() - { - return array( - // Input , Expected output - array('', array( - 'localhost', - Resque_Redis::DEFAULT_PORT, - false, - false, false, - array(), - )), - array('localhost', array( - 'localhost', - Resque_Redis::DEFAULT_PORT, - false, - false, false, - array(), - )), - array('localhost:1234', array( - 'localhost', - 1234, - false, - false, false, - array(), - )), - array('localhost:1234/2', array( - 'localhost', - 1234, - 2, - false, false, - array(), - )), - array('redis://foobar', array( - 'foobar', - Resque_Redis::DEFAULT_PORT, - false, - false, false, - array(), - )), - array('redis://foobar/', array( - 'foobar', - Resque_Redis::DEFAULT_PORT, - false, - false, false, - array(), - )), - array('redis://foobar:1234', array( - 'foobar', - 1234, - false, - false, false, - array(), - )), - array('redis://foobar:1234/15', array( - 'foobar', - 1234, - 15, - false, false, - array(), - )), - array('redis://foobar:1234/0', array( - 'foobar', - 1234, - 0, - false, false, - array(), - )), - array('redis://user@foobar:1234', array( - 'foobar', - 1234, - false, - 'user', false, - array(), - )), - array('redis://user@foobar:1234/15', array( - 'foobar', - 1234, - 15, - 'user', false, - array(), - )), - array('redis://user:pass@foobar:1234', array( - 'foobar', - 1234, - false, - 'user', 'pass', - array(), - )), - array('redis://user:pass@foobar:1234?x=y&a=b', array( - 'foobar', - 1234, - false, - 'user', 'pass', - array('x' => 'y', 'a' => 'b'), - )), - array('redis://:pass@foobar:1234?x=y&a=b', array( - 'foobar', - 1234, - false, - false, 'pass', - array('x' => 'y', 'a' => 'b'), - )), - array('redis://user@foobar:1234?x=y&a=b', array( - 'foobar', - 1234, - false, - 'user', false, - array('x' => 'y', 'a' => 'b'), - )), - array('redis://foobar:1234?x=y&a=b', array( - 'foobar', - 1234, - false, - false, false, - array('x' => 'y', 'a' => 'b'), - )), - array('redis://user@foobar:1234/12?x=y&a=b', array( - 'foobar', - 1234, - 12, - 'user', false, - array('x' => 'y', 'a' => 'b'), - )), - array('tcp://user@foobar:1234/12?x=y&a=b', array( - 'foobar', - 1234, - 12, - 'user', false, - array('x' => 'y', 'a' => 'b'), - )), - ); - } + /** + * These DSN values should throw exceptions + * @return array + */ + public function bogusDsnStringProvider() + { + return [ + ['http://foo.bar/'], + ['user:@foobar:1234?x=y&a=b'], + ['foobar:1234?x=y&a=b'], + ]; + } - /** - * These DSN values should throw exceptions - * @return array - */ - public function bogusDsnStringProvider() - { - return array( - array('http://foo.bar/'), - array('user:@foobar:1234?x=y&a=b'), - array('foobar:1234?x=y&a=b'), - ); - } + /** + * @dataProvider validDsnStringProvider + */ + public function testParsingValidDsnString($dsn, $expected) + { + $result = Resque_Redis::parseDsn($dsn); + $this->assertEquals($expected, $result); + } - /** - * @dataProvider validDsnStringProvider - */ - public function testParsingValidDsnString($dsn, $expected) - { - $result = Resque_Redis::parseDsn($dsn); - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider bogusDsnStringProvider - * @expectedException InvalidArgumentException - */ - public function testParsingBogusDsnStringThrowsException($dsn) - { - // The next line should throw an InvalidArgumentException - $result = Resque_Redis::parseDsn($dsn); - } + /** + * @dataProvider bogusDsnStringProvider + * @expectedException InvalidArgumentException + */ + public function testParsingBogusDsnStringThrowsException($dsn) + { + // The next line should throw an InvalidArgumentException + Resque_Redis::parseDsn($dsn); + } } \ No newline at end of file diff --git a/test/Resque/Tests/StatTest.php b/test/Resque/Tests/StatTest.php index aa41888..121aaff 100644 --- a/test/Resque/Tests/StatTest.php +++ b/test/Resque/Tests/StatTest.php @@ -1,49 +1,51 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Tests + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Tests_StatTest extends Resque_Tests_TestCase { - public function testStatCanBeIncremented() - { - Resque_Stat::incr('test_incr'); - Resque_Stat::incr('test_incr'); - $this->assertEquals(2, $this->redis->get('resque:stat:test_incr')); - } + public function testStatCanBeIncremented() + { + 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); - $this->assertEquals(21, $this->redis->get('resque:stat:test_incrX')); - } + public function testStatCanBeIncrementedByX() + { + 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'); - $this->assertEquals(21, $this->redis->get('resque:stat:test_decr')); - } + public function testStatCanBeDecremented() + { + 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); - $this->assertEquals(11, $this->redis->get('resque:stat:test_decrX')); - } + public function testStatCanBeDecrementedByX() + { + 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')); - } + public function testGetStatByName() + { + 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')); - } + public function testGetUnknownStatReturns0() + { + $this->assertEquals(0, Resque_Stat::get('test_get_unknown')); + } } \ No newline at end of file diff --git a/test/Resque/Tests/TestCase.php b/test/Resque/Tests/TestCase.php index a97f64b..2ba176a 100644 --- a/test/Resque/Tests/TestCase.php +++ b/test/Resque/Tests/TestCase.php @@ -1,30 +1,34 @@ - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Tests + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ -class Resque_Tests_TestCase extends PHPUnit_Framework_TestCase + +class Resque_Tests_TestCase extends PHPUnit\Framework\TestCase { - protected $resque; - protected $redis; + protected $resque; + protected $redis; - public static function setUpBeforeClass() - { - date_default_timezone_set('UTC'); - } + public static function setUpBeforeClass() + { + date_default_timezone_set('UTC'); + } - public function setUp() - { - $config = file_get_contents(REDIS_CONF); - preg_match('#^\s*port\s+([0-9]+)#m', $config, $matches); - $this->redis = new Credis_Client('localhost', $matches[1]); + public function setUp() + { +// $config = file_get_contents(REDIS_CONF); +// preg_match('#^\s*port\s+([0-9]+)#m', $config, $matches); + $this->redis = new \Redis(); + $this->redis->connect('localhost'); + $this->redis->select(9); - Resque::setBackend('redis://localhost:' . $matches[1]); + Resque::setBackend('localhost', 9); - // Flush redis - $this->redis->flushAll(); - } + // Flush redis + $this->redis->flushAll(); + } } diff --git a/test/Resque/Tests/WorkerTest.php b/test/Resque/Tests/WorkerTest.php index 93c0621..0090277 100644 --- a/test/Resque/Tests/WorkerTest.php +++ b/test/Resque/Tests/WorkerTest.php @@ -1,4 +1,5 @@ * @license http://www.opensource.org/licenses/mit-license.php */ + class Resque_Tests_WorkerTest extends Resque_Tests_TestCase { public function testWorkerRegistersInList() diff --git a/test/bootstrap.php b/test/bootstrap.php index a4b6837..a92611c 100644 --- a/test/bootstrap.php +++ b/test/bootstrap.php @@ -2,9 +2,9 @@ /** * Resque test bootstrap file - sets up a test environment. * - * @package Resque/Tests - * @author Chris Boulton - * @license http://www.opensource.org/licenses/mit-license.php + * @package Resque/Tests + * @author Chris Boulton + * @license http://www.opensource.org/licenses/mit-license.php */ $loader = require __DIR__ . '/../vendor/autoload.php'; @@ -15,24 +15,24 @@ 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); +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); +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); +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]); @@ -43,57 +43,59 @@ 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; - } + $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); + $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); - } - } + if (is_file($pidFile)) { + unlink($pidFile); + } + } - // Remove the redis database - if(!preg_match('#^\s*dir\s+([^\s]+)#m', $config, $matches)) { - return; - } - $dir = $matches[1]; + // 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; - } + if (!preg_match('#^\s*dbfilename\s+([^\s]+)#m', $config, $matches)) { + return; + } - $filename = TEST_MISC . '/' . $dir . '/' . $matches[1]; - if(is_file($filename)) { - unlink($filename); - } + $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'); +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 static $called = false; - public function perform() - { - self::$called = true; - } + public function perform() + { + self::$called = true; + } } class Failing_Job_Exception extends Exception @@ -103,10 +105,10 @@ class Failing_Job_Exception extends Exception class Failing_Job { - public function perform() - { - throw new Failing_Job_Exception('Message!'); - } + public function perform() + { + throw new Failing_Job_Exception('Message!'); + } } class Test_Job_Without_Perform_Method @@ -116,33 +118,33 @@ class Test_Job_Without_Perform_Method class Test_Job_With_SetUp { - public static $called = false; - public $args = false; + public static $called = false; + public $args = false; - public function setUp() - { - self::$called = true; - } + public function setUp() + { + self::$called = true; + } - public function perform() - { + public function perform() + { - } + } } class Test_Job_With_TearDown { - public static $called = false; - public $args = false; + public static $called = false; + public $args = false; - public function perform() - { + public function perform() + { - } + } - public function tearDown() - { - self::$called = true; - } + public function tearDown() + { + self::$called = true; + } } \ No newline at end of file