mirror of
https://github.com/idanoo/php-resque.git
synced 2024-11-24 17:25:13 +00:00
Merge branch 'master' of git://github.com/chrisboulton/php-resque into blocking-list-pop
Conflicts: lib/Resque.php lib/Resque/RedisCluster.php lib/Resque/Worker.php
This commit is contained in:
commit
5687c8fe82
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
vendor/
|
@ -1,5 +1,12 @@
|
|||||||
language: php
|
language: php
|
||||||
php:
|
php:
|
||||||
- 5.2
|
|
||||||
- 5.3
|
- 5.3
|
||||||
- 5.4
|
- 5.4
|
||||||
|
env:
|
||||||
|
- REDIS_STANDALONE=0
|
||||||
|
- REDIS_STANDALONE=1
|
||||||
|
before_script:
|
||||||
|
- sh -c "if [ $REDIS_STANDALONE -eq 0 ]; then wget https://github.com/nicolasff/phpredis/archive/2.2.2.zip -O php-redis.zip && unzip php-redis.zip; fi"
|
||||||
|
- sh -c "if [ $REDIS_STANDALONE -eq 0 ]; then cd phpredis-2.2.2/ && phpize && ./configure && make && make install; fi"
|
||||||
|
- sh -c "if [ $REDIS_STANDALONE -eq 0 ]; then echo \"extension=redis.so\" >> `php --ini | grep \"Loaded Configuration\" | sed -e \"s|.*:\s*||\"`; fi"
|
||||||
|
- composer install
|
45
CHANGELOG.md
45
CHANGELOG.md
@ -1,4 +1,35 @@
|
|||||||
## 1.2 (Unreleased) ##
|
## 1.3 (2013-??-??) - Current Master ##
|
||||||
|
|
||||||
|
**Note:** This release introduces backwards incompatible changes with all previous versions of php-resque. Please see below for details.
|
||||||
|
|
||||||
|
### Redisent (Redis Library) Replaced with Credis
|
||||||
|
|
||||||
|
Redisent has always been the Redis backend for php-resque because of its lightweight nature. Unfortunately, Redisent is largely unmaintained.
|
||||||
|
|
||||||
|
[Credis](http://example.com/) is a fork of Redisent, which among other improvements will automatically use the [phpredis](https://github.com/nicolasff/phpredis) native PHP extension if it is available. (you want this for speed, trust me)
|
||||||
|
|
||||||
|
php-resque now utilizes Credis for all Redis based operations. Credis automatically required and installed as a Composer dependency.
|
||||||
|
|
||||||
|
### Composer Support
|
||||||
|
|
||||||
|
Composer support has been improved and is now the recommended method for including php-resque in your project. Details on Composer support can be found in the Getting Started section of the readme.
|
||||||
|
|
||||||
|
### Other Improvements/Changes
|
||||||
|
|
||||||
|
* **COMPATIBILITY BREAKING**: The bundled worker manager `resque.php` has been moved to `bin/resque`, and is available as `vendor/bin/resque` when php-resque is installed as a Composer package.
|
||||||
|
|
||||||
|
* Restructure tests and test bootstrapping. Autoload tests via Composer (install test dependencies with `composer install --dev`)
|
||||||
|
|
||||||
|
* Add `SETEX` to list of commands which supply a key as the first argument in Redisent (danhunsaker)
|
||||||
|
|
||||||
|
* Fix an issue where a lost connection to Redis could cause an infinite loop (atorres757)
|
||||||
|
|
||||||
|
* Add a helper method to `Resque_Redis` to remove the namespace applied to Redis keys (tonypiper)
|
||||||
|
|
||||||
|
|
||||||
|
## 1.2 (2012-10-13) ##
|
||||||
|
|
||||||
|
**Note:** This release is largely backwards compatible with php-resque 1.1. The next release will introduce backwards incompatible changes (moving from Redisent to Credis), and will drop compatibility with PHP 5.2.
|
||||||
|
|
||||||
* Allow alternate redis database to be selected when calling setBackend by supplying a second argument (patrickbajao)
|
* Allow alternate redis database to be selected when calling setBackend by supplying a second argument (patrickbajao)
|
||||||
* Use `require_once` when including php-resque after the app has been included in the sample resque.php to prevent include conflicts (andrewjshults)
|
* Use `require_once` when including php-resque after the app has been included in the sample resque.php to prevent include conflicts (andrewjshults)
|
||||||
@ -10,7 +41,17 @@
|
|||||||
* Fix lost jobs when there is more than one worker process started by the same parent process (salimane)
|
* Fix lost jobs when there is more than one worker process started by the same parent process (salimane)
|
||||||
* Move include for resque before APP_INCLUDE is loaded in, so that way resque is available for the app
|
* Move include for resque before APP_INCLUDE is loaded in, so that way resque is available for the app
|
||||||
* Avoid working with dirty worker IDs (salimane)
|
* Avoid working with dirty worker IDs (salimane)
|
||||||
|
* Allow UNIX socket to be passed to Resque when connecting to Redis (pedroarnal)
|
||||||
|
* Fix typographical errors in PHP docblocks (chaitanyakuber)
|
||||||
|
* Set the queue name on job instances when jobs are executed (chaitanyakuber)
|
||||||
|
* Fix and add tests for Resque_Event::stopListening (ebernhardson)
|
||||||
|
* Documentation cleanup (maetl)
|
||||||
|
* Pass queue name to afterEvent callback
|
||||||
|
* Only declare RedisException if it doesn't already exist (Matt Heath)
|
||||||
|
* Add support for Composer
|
||||||
|
* Fix missing and incorrect paths for Resque and Resque_Job_Status classes in demo (jjfrey)
|
||||||
|
* Disable autoload for the RedisException class_exists call (scragg0x)
|
||||||
|
* General tidy up of comments and files/folders
|
||||||
|
|
||||||
## 1.1 (2011-03-27) ##
|
## 1.1 (2011-03-27) ##
|
||||||
|
|
||||||
|
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
|||||||
(c) 2010 Chris Boulton <chris.boulton@interspire.com>
|
(c) Chris Boulton <chris@bigcommerce.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
72
README.md
72
README.md
@ -37,8 +37,34 @@ pre and post jobs
|
|||||||
|
|
||||||
## Requirements ##
|
## Requirements ##
|
||||||
|
|
||||||
* PHP 5.2+
|
* PHP 5.3+
|
||||||
* Redis 2.2+
|
* Redis 2.2+
|
||||||
|
* Optional but Recommended: Composer
|
||||||
|
|
||||||
|
## Getting Started ##
|
||||||
|
|
||||||
|
The easiest way to work with php-resque is when it's installed as a
|
||||||
|
Composer package inside your project. Composer isn't strictly
|
||||||
|
required, but makes life a lot easier.
|
||||||
|
|
||||||
|
If you're not familiar with Composer, please see <http://getcomposer.org/>.
|
||||||
|
|
||||||
|
1. Add php-resque to your application's composer.json.
|
||||||
|
|
||||||
|
{
|
||||||
|
...
|
||||||
|
"require": {
|
||||||
|
"chrisboulton/php-resque": "1.2.x"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
2. Run `composer install`.
|
||||||
|
|
||||||
|
3. If you haven't already, add the Composer autoload to your project's
|
||||||
|
initialization file. (example)
|
||||||
|
|
||||||
|
require 'vendor/autoload.php';
|
||||||
|
|
||||||
## Jobs ##
|
## Jobs ##
|
||||||
|
|
||||||
@ -46,8 +72,6 @@ pre and post jobs
|
|||||||
|
|
||||||
Jobs are queued as follows:
|
Jobs are queued as follows:
|
||||||
|
|
||||||
require_once 'lib/Resque.php';
|
|
||||||
|
|
||||||
// Required if redis is located elsewhere
|
// Required if redis is located elsewhere
|
||||||
Resque::setBackend('localhost:6379');
|
Resque::setBackend('localhost:6379');
|
||||||
|
|
||||||
@ -87,12 +111,12 @@ The `tearDown` method if defined, will be called after the job finishes.
|
|||||||
{
|
{
|
||||||
// ... Set up environment for this job
|
// ... Set up environment for this job
|
||||||
}
|
}
|
||||||
|
|
||||||
public function perform()
|
public function perform()
|
||||||
{
|
{
|
||||||
// .. Run job
|
// .. Run job
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tearDown()
|
public function tearDown()
|
||||||
{
|
{
|
||||||
// ... Remove environment for this job
|
// ... Remove environment for this job
|
||||||
@ -136,8 +160,9 @@ class.
|
|||||||
Workers work in the exact same way as the Ruby workers. For complete
|
Workers work in the exact same way as the Ruby workers. For complete
|
||||||
documentation on workers, see the original documentation.
|
documentation on workers, see the original documentation.
|
||||||
|
|
||||||
A basic "up-and-running" resque.php file is included that sets up a
|
A basic "up-and-running" `bin/resque` file is included that sets up a
|
||||||
running worker environment is included in the root directory.
|
running worker environment is included. (`vendor/bin/resque` when installed
|
||||||
|
via Composer)
|
||||||
|
|
||||||
The exception to the similarities with the Ruby version of resque is
|
The exception to the similarities with the Ruby version of resque is
|
||||||
how a worker is initially setup. To work under all environments,
|
how a worker is initially setup. To work under all environments,
|
||||||
@ -146,13 +171,17 @@ not having a single environment such as with Ruby, the PHP port makes
|
|||||||
|
|
||||||
To start a worker, it's very similar to the Ruby version:
|
To start a worker, it's very similar to the Ruby version:
|
||||||
|
|
||||||
$ QUEUE=file_serve php resque.php
|
$ QUEUE=file_serve php bin/resque
|
||||||
|
|
||||||
It's your responsibility to tell the worker which file to include to get
|
It's your responsibility to tell the worker which file to include to get
|
||||||
your application underway. You do so by setting the `APP_INCLUDE` environment
|
your application underway. You do so by setting the `APP_INCLUDE` environment
|
||||||
variable:
|
variable:
|
||||||
|
|
||||||
$ QUEUE=file_serve APP_INCLUDE=../application/init.php php resque.php
|
$ QUEUE=file_serve APP_INCLUDE=../application/init.php php bin/resque
|
||||||
|
|
||||||
|
*Pro tip: Using Composer? More than likely, you don't need to worry about
|
||||||
|
`APP_INCLUDE`, because hopefully Composer is responsible for autoloading
|
||||||
|
your application too!*
|
||||||
|
|
||||||
Getting your application underway also includes telling the worker your job
|
Getting your application underway also includes telling the worker your job
|
||||||
classes, by means of either an autoloader or including them.
|
classes, by means of either an autoloader or including them.
|
||||||
@ -163,8 +192,8 @@ The port supports the same environment variables for logging to STDOUT.
|
|||||||
Setting `VERBOSE` will print basic debugging information and `VVERBOSE`
|
Setting `VERBOSE` will print basic debugging information and `VVERBOSE`
|
||||||
will print detailed information.
|
will print detailed information.
|
||||||
|
|
||||||
$ VERBOSE QUEUE=file_serve php resque.php
|
$ VERBOSE QUEUE=file_serve bin/resque
|
||||||
$ VVERBOSE QUEUE=file_serve php resque.php
|
$ VVERBOSE QUEUE=file_serve bin/resque
|
||||||
|
|
||||||
### Priorities and Queue Lists ###
|
### Priorities and Queue Lists ###
|
||||||
|
|
||||||
@ -175,7 +204,7 @@ checked in.
|
|||||||
|
|
||||||
As per the original example:
|
As per the original example:
|
||||||
|
|
||||||
$ QUEUE=file_serve,warm_cache php resque.php
|
$ QUEUE=file_serve,warm_cache bin/resque
|
||||||
|
|
||||||
The `file_serve` queue will always be checked for new jobs on each
|
The `file_serve` queue will always be checked for new jobs on each
|
||||||
iteration before the `warm_cache` queue is checked.
|
iteration before the `warm_cache` queue is checked.
|
||||||
@ -185,14 +214,14 @@ iteration before the `warm_cache` queue is checked.
|
|||||||
All queues are supported in the same manner and processed in alphabetical
|
All queues are supported in the same manner and processed in alphabetical
|
||||||
order:
|
order:
|
||||||
|
|
||||||
$ QUEUE=* php resque.php
|
$ QUEUE=* bin/resque
|
||||||
|
|
||||||
### Running Multiple Workers ###
|
### Running Multiple Workers ###
|
||||||
|
|
||||||
Multiple workers ca be launched and automatically worked by supplying
|
Multiple workers ca be launched and automatically worked by supplying
|
||||||
the `COUNT` environment variable:
|
the `COUNT` environment variable:
|
||||||
|
|
||||||
$ COUNT=5 php resque.php
|
$ COUNT=5 bin/resque
|
||||||
|
|
||||||
### Forking ###
|
### Forking ###
|
||||||
|
|
||||||
@ -257,7 +286,7 @@ It is up to your application to register event listeners. When enqueuing events
|
|||||||
in your application, it should be as easy as making sure php-resque is loaded
|
in your application, it should be as easy as making sure php-resque is loaded
|
||||||
and calling `Resque_Event::listen`.
|
and calling `Resque_Event::listen`.
|
||||||
|
|
||||||
When running workers, if you run workers via the default `resque.php` script,
|
When running workers, if you run workers via the default `bin/resque` script,
|
||||||
your `APP_INCLUDE` script should initialize and register any listeners required
|
your `APP_INCLUDE` script should initialize and register any listeners required
|
||||||
for operation. If you have rolled your own worker manager, then it is again your
|
for operation. If you have rolled your own worker manager, then it is again your
|
||||||
responsibility to register listeners.
|
responsibility to register listeners.
|
||||||
@ -329,3 +358,16 @@ Called after a job has been queued using the `Resque::enqueue` method. Arguments
|
|||||||
* KevBurnsJr
|
* KevBurnsJr
|
||||||
* jmathai
|
* jmathai
|
||||||
* dceballos
|
* dceballos
|
||||||
|
* patrickbajao
|
||||||
|
* andrewjshults
|
||||||
|
* warezthebeef
|
||||||
|
* d11wtq
|
||||||
|
* hlegius
|
||||||
|
* salimane
|
||||||
|
* humancopy
|
||||||
|
* pedroarnal
|
||||||
|
* chaitanyakuber
|
||||||
|
* maetl
|
||||||
|
* Matt Heath
|
||||||
|
* jjfrey
|
||||||
|
* scragg0x
|
||||||
|
8
TODO.md
8
TODO.md
@ -1,8 +0,0 @@
|
|||||||
* Write tests for:
|
|
||||||
* `Resque_Failure`
|
|
||||||
* `Resque_Failure_Redis`
|
|
||||||
* Change to preforking worker model
|
|
||||||
* Clean up /bin and /demo
|
|
||||||
* Add a way to store arbitrary text in job statuses (for things like progress
|
|
||||||
indicators)
|
|
||||||
* Write plugin for Ruby resque that calls setUp and tearDown methods
|
|
107
bin/resque
107
bin/resque
@ -1 +1,106 @@
|
|||||||
#!/bin/sh
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Find and initialize Composer
|
||||||
|
$files = array(
|
||||||
|
__DIR__ . '/../../vendor/autoload.php',
|
||||||
|
__DIR__ . '/../../../autoload.php',
|
||||||
|
__DIR__ . '/../../../../autoload.php',
|
||||||
|
__DIR__ . '/../vendor/autoload.php',
|
||||||
|
);
|
||||||
|
|
||||||
|
$found = false;
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if (file_exists($file)) {
|
||||||
|
require_once $file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!class_exists('Composer\Autoload\ClassLoader', false)) {
|
||||||
|
die(
|
||||||
|
'You need to set up the project dependencies using the following commands:' . PHP_EOL .
|
||||||
|
'curl -s http://getcomposer.org/installer | php' . PHP_EOL .
|
||||||
|
'php composer.phar install' . PHP_EOL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$QUEUE = getenv('QUEUE');
|
||||||
|
if(empty($QUEUE)) {
|
||||||
|
die("Set QUEUE env var containing the list of queues to work.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
$REDIS_BACKEND = getenv('REDIS_BACKEND');
|
||||||
|
$REDIS_BACKEND_DB = getenv('REDIS_BACKEND_DB');
|
||||||
|
if(!empty($REDIS_BACKEND)) {
|
||||||
|
if (empty($REDIS_BACKEND_DB))
|
||||||
|
Resque::setBackend($REDIS_BACKEND);
|
||||||
|
else
|
||||||
|
Resque::setBackend($REDIS_BACKEND, $REDIS_BACKEND_DB);
|
||||||
|
}
|
||||||
|
|
||||||
|
$logLevel = 0;
|
||||||
|
$LOGGING = getenv('LOGGING');
|
||||||
|
$VERBOSE = getenv('VERBOSE');
|
||||||
|
$VVERBOSE = getenv('VVERBOSE');
|
||||||
|
if(!empty($LOGGING) || !empty($VERBOSE)) {
|
||||||
|
$logLevel = Resque_Worker::LOG_NORMAL;
|
||||||
|
}
|
||||||
|
else if(!empty($VVERBOSE)) {
|
||||||
|
$logLevel = Resque_Worker::LOG_VERBOSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$APP_INCLUDE = getenv('APP_INCLUDE');
|
||||||
|
if($APP_INCLUDE) {
|
||||||
|
if(!file_exists($APP_INCLUDE)) {
|
||||||
|
die('APP_INCLUDE ('.$APP_INCLUDE.") does not exist.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once $APP_INCLUDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$interval = 5;
|
||||||
|
$INTERVAL = getenv('INTERVAL');
|
||||||
|
if(!empty($INTERVAL)) {
|
||||||
|
$interval = $INTERVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = 1;
|
||||||
|
$COUNT = getenv('COUNT');
|
||||||
|
if(!empty($COUNT) && $COUNT > 1) {
|
||||||
|
$count = $COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($count > 1) {
|
||||||
|
for($i = 0; $i < $count; ++$i) {
|
||||||
|
$pid = Resque::fork();
|
||||||
|
if($pid == -1) {
|
||||||
|
die("Could not fork worker ".$i."\n");
|
||||||
|
}
|
||||||
|
// Child, start the worker
|
||||||
|
else if(!$pid) {
|
||||||
|
$queues = explode(',', $QUEUE);
|
||||||
|
$worker = new Resque_Worker($queues);
|
||||||
|
$worker->logLevel = $logLevel;
|
||||||
|
fwrite(STDOUT, '*** Starting worker '.$worker."\n");
|
||||||
|
$worker->work($interval);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Start a single worker
|
||||||
|
else {
|
||||||
|
$queues = explode(',', $QUEUE);
|
||||||
|
$worker = new Resque_Worker($queues);
|
||||||
|
$worker->logLevel = $logLevel;
|
||||||
|
|
||||||
|
$PIDFILE = getenv('PIDFILE');
|
||||||
|
if ($PIDFILE) {
|
||||||
|
file_put_contents($PIDFILE, getmypid()) or
|
||||||
|
die('Could not write PID information to ' . $PIDFILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(STDOUT, '*** Starting worker '.$worker."\n");
|
||||||
|
$worker->work($interval);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
@ -11,9 +11,26 @@
|
|||||||
"email": "chris@bigcommerce.com"
|
"email": "chris@bigcommerce.com"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "vcs",
|
||||||
|
"url": "https://github.com/chrisboulton/credis"
|
||||||
|
}
|
||||||
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.0"
|
"php": ">=5.3.0",
|
||||||
|
"colinmollenhour/credis": "dev-master"
|
||||||
},
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-proctitle": "Allows php-resque to rename the title of UNIX processes to show the status of a worker.",
|
||||||
|
"ext-redis": "Native PHP extension for Redis connectivity. Credis will automatically utilize when available."
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "3.7.*"
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"bin/resque"
|
||||||
|
],
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-0": {
|
"psr-0": {
|
||||||
"Resque": "lib"
|
"Resque": "lib"
|
||||||
|
53
composer.lock
generated
Normal file
53
composer.lock
generated
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"hash": "d37909ad0ffc11ed4d1e67dcaabe00b2",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "colinmollenhour/credis",
|
||||||
|
"version": "dev-master",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/chrisboulton/credis",
|
||||||
|
"reference": "62c73dd16e08069e3fd8f224cb4a5ddd73db8095"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/chrisboulton/credis/zipball/62c73dd16e08069e3fd8f224cb4a5ddd73db8095",
|
||||||
|
"reference": "62c73dd16e08069e3fd8f224cb4a5ddd73db8095",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"time": "2013-01-12 10:15:31",
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"classmap": [
|
||||||
|
"Client.php",
|
||||||
|
"Cluster.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Colin Mollenhour",
|
||||||
|
"email": "colin@mollenhour.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.",
|
||||||
|
"homepage": "https://github.com/colinmollenhour/credis",
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/chrisboulton/credis/tree/master"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": null,
|
||||||
|
"aliases": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": {
|
||||||
|
"colinmollenhour/credis": 20
|
||||||
|
}
|
||||||
|
}
|
@ -3,8 +3,8 @@ if(empty($argv[1])) {
|
|||||||
die('Specify the ID of a job to monitor the status of.');
|
die('Specify the ID of a job to monitor the status of.');
|
||||||
}
|
}
|
||||||
|
|
||||||
require '../lib/Resque/Job/Status.php';
|
require __DIR__ . '/init.php';
|
||||||
require '../lib/Resque.php';
|
|
||||||
date_default_timezone_set('GMT');
|
date_default_timezone_set('GMT');
|
||||||
Resque::setBackend('127.0.0.1:6379');
|
Resque::setBackend('127.0.0.1:6379');
|
||||||
|
|
||||||
|
25
demo/init.php
Normal file
25
demo/init.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
// Find and initialize Composer
|
||||||
|
// NOTE: You should NOT use this when developing against php-resque.
|
||||||
|
// The autoload code below is specifically for this demo.
|
||||||
|
$files = array(
|
||||||
|
__DIR__ . '/../../vendor/autoload.php',
|
||||||
|
__DIR__ . '/../../../../autoload.php',
|
||||||
|
__DIR__ . '/../vendor/autoload.php',
|
||||||
|
);
|
||||||
|
|
||||||
|
$found = false;
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if (file_exists($file)) {
|
||||||
|
require_once $file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!class_exists('Composer\Autoload\ClassLoader', false)) {
|
||||||
|
die(
|
||||||
|
'You need to set up the project dependencies using the following commands:' . PHP_EOL .
|
||||||
|
'curl -s http://getcomposer.org/installer | php' . PHP_EOL .
|
||||||
|
'php composer.phar install' . PHP_EOL
|
||||||
|
);
|
||||||
|
}
|
@ -3,7 +3,7 @@ if(empty($argv[1])) {
|
|||||||
die('Specify the name of a job to add. e.g, php queue.php PHP_Job');
|
die('Specify the name of a job to add. e.g, php queue.php PHP_Job');
|
||||||
}
|
}
|
||||||
|
|
||||||
require '../lib/Resque.php';
|
require __DIR__ . '/init.php';
|
||||||
date_default_timezone_set('GMT');
|
date_default_timezone_set('GMT');
|
||||||
Resque::setBackend('127.0.0.1:6379');
|
Resque::setBackend('127.0.0.1:6379');
|
||||||
|
|
||||||
|
@ -4,5 +4,5 @@ require 'bad_job.php';
|
|||||||
require 'job.php';
|
require 'job.php';
|
||||||
require 'php_error_job.php';
|
require 'php_error_job.php';
|
||||||
|
|
||||||
require '../resque.php';
|
require '../bin/resque';
|
||||||
?>
|
?>
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
check process resque_worker_[QUEUE]
|
check process resque_worker_[QUEUE]
|
||||||
with pidfile /var/run/resque/worker_[QUEUE].pid
|
with pidfile /var/run/resque/worker_[QUEUE].pid
|
||||||
start program = "/bin/sh -c 'APP_INCLUDE=[APP_INCLUDE] QUEUE=[QUEUE] VERBOSE=1 PIDFILE=/var/run/resque/worker_[QUEUE].pid nohup php -f [PATH/TO/RESQUE]/resque.php > /var/log/resque/worker_[QUEUE].log &'" as uid [UID] and gid [GID]
|
start program = "/bin/sh -c 'APP_INCLUDE=[APP_INCLUDE] QUEUE=[QUEUE] VERBOSE=1 PIDFILE=/var/run/resque/worker_[QUEUE].pid nohup php -f [PATH/TO/RESQUE]/bin/resque > /var/log/resque/worker_[QUEUE].log &'" as uid [UID] and gid [GID]
|
||||||
stop program = "/bin/sh -c 'kill -s QUIT `cat /var/run/resque/worker_[QUEUE].pid` && rm -f /var/run/resque/worker_[QUEUE].pid; exit 0;'"
|
stop program = "/bin/sh -c 'kill -s QUIT `cat /var/run/resque/worker_[QUEUE].pid` && rm -f /var/run/resque/worker_[QUEUE].pid; exit 0;'"
|
||||||
if totalmem is greater than 300 MB for 10 cycles then restart # eating up memory?
|
if totalmem is greater than 300 MB for 10 cycles then restart # eating up memory?
|
||||||
group resque_workers
|
group resque_workers
|
@ -1,22 +0,0 @@
|
|||||||
Copyright (c) 2009 Justin Poliey <jdp34@njit.edu>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
|
||||||
obtaining a copy of this software and associated documentation
|
|
||||||
files (the "Software"), to deal in the Software without
|
|
||||||
restriction, including without limitation the rights to use,
|
|
||||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,67 +0,0 @@
|
|||||||
# Redisent
|
|
||||||
|
|
||||||
Redisent is a simple, no-nonsense interface to the [Redis](http://code.google.com/p/redis/) key-value store for modest developers.
|
|
||||||
Due to the way it is implemented, it is flexible and tolerant of changes to the Redis protocol.
|
|
||||||
|
|
||||||
## Getting to work
|
|
||||||
|
|
||||||
If you're at all familiar with the Redis protocol and PHP objects, you've already mastered Redisent.
|
|
||||||
All Redisent does is map the Redis protocol to a PHP object, abstract away the nitty-gritty, and make the return values PHP compatible.
|
|
||||||
|
|
||||||
require 'redisent.php';
|
|
||||||
$redis = new Redisent('localhost');
|
|
||||||
$redis->set('awesome', 'absolutely');
|
|
||||||
echo sprintf('Is Redisent awesome? %s.\n', $redis->get('awesome'));
|
|
||||||
|
|
||||||
You use the exact same command names, and the exact same argument order. **How wonderful.** How about a more complex example?
|
|
||||||
|
|
||||||
require 'redisent.php';
|
|
||||||
$redis = new Redisent('localhost');
|
|
||||||
$redis->rpush('particles', 'proton');
|
|
||||||
$redis->rpush('particles', 'electron');
|
|
||||||
$redis->rpush('particles', 'neutron');
|
|
||||||
$particles = $redis->lrange('particles', 0, -1);
|
|
||||||
$particle_count = $redis->llen('particles');
|
|
||||||
echo "<p>The {$particle_count} particles that make up atoms are:</p>";
|
|
||||||
echo "<ul>";
|
|
||||||
foreach ($particles as $particle) {
|
|
||||||
echo "<li>{$particle}</li>";
|
|
||||||
}
|
|
||||||
echo "</ul>";
|
|
||||||
|
|
||||||
Be aware that Redis error responses will be wrapped in a RedisException class and thrown, so do be sure to use proper coding techniques.
|
|
||||||
|
|
||||||
## Clustering your servers
|
|
||||||
|
|
||||||
Redisent also includes a way for developers to fully utilize the scalability of Redis with multiple servers and [consistent hashing](http://en.wikipedia.org/wiki/Consistent_hashing).
|
|
||||||
Using the RedisentCluster class, you can use Redisent the same way, except that keys will be hashed across multiple servers.
|
|
||||||
Here is how to set up a cluster:
|
|
||||||
|
|
||||||
include 'redisent_cluster.php';
|
|
||||||
|
|
||||||
$cluster = new RedisentCluster(array(
|
|
||||||
array('host' => '127.0.0.1', 'port' => 6379),
|
|
||||||
array('host' => '127.0.0.1', 'port' => 6380)
|
|
||||||
));
|
|
||||||
|
|
||||||
You can then use Redisent the way you normally would, i.e., `$cluster->set('key', 'value')` or `$cluster->lrange('particles', 0, -1)`.
|
|
||||||
But what about when you need to use commands that are server specific and do not operate on keys? You can use routing, with the `RedisentCluster::to` method.
|
|
||||||
To use routing, you need to assign a server an alias in the constructor of the Redis cluster. Aliases are not required on all servers, just the ones you want to be able to access directly.
|
|
||||||
|
|
||||||
include 'redisent_cluster.php';
|
|
||||||
|
|
||||||
$cluster = new RedisentCluster(array(
|
|
||||||
'alpha' => array('host' => '127.0.0.1', 'port' => 6379),
|
|
||||||
array('host' => '127.0.0.1', 'port' => 6380)
|
|
||||||
));
|
|
||||||
|
|
||||||
Now there is an alias of the server running on 127.0.0.1:6379 called **alpha**, and can be interacted with like this:
|
|
||||||
|
|
||||||
// get server info
|
|
||||||
$cluster->to('alpha')->info();
|
|
||||||
|
|
||||||
Now you have complete programatic control over your Redis servers.
|
|
||||||
|
|
||||||
## About
|
|
||||||
|
|
||||||
© 2009 [Justin Poliey](http://justinpoliey.com)
|
|
@ -1,150 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Redisent, a Redis interface for the modest
|
|
||||||
* @author Justin Poliey <jdp34@njit.edu>
|
|
||||||
* @copyright 2009 Justin Poliey <jdp34@njit.edu>
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
* @package Redisent
|
|
||||||
*/
|
|
||||||
|
|
||||||
define('CRLF', sprintf('%s%s', chr(13), chr(10)));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wraps native Redis errors in friendlier PHP exceptions
|
|
||||||
* Only declared if class doesn't already exist to ensure compatibility with php-redis
|
|
||||||
*/
|
|
||||||
if (! class_exists('RedisException')) {
|
|
||||||
class RedisException extends Exception {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redisent, a Redis interface for the modest among us
|
|
||||||
*/
|
|
||||||
class Redisent {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Socket connection to the Redis server
|
|
||||||
* @var resource
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private $__sock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Host of the Redis server
|
|
||||||
* @var string
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
public $host;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Port on which the Redis server is running
|
|
||||||
* @var integer
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
public $port;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Redisent connection to the Redis server on host {@link $host} and port {@link $port}.
|
|
||||||
* @param string $host The hostname of the Redis server
|
|
||||||
* @param integer $port The port number of the Redis server
|
|
||||||
*/
|
|
||||||
function __construct($host, $port = 6379) {
|
|
||||||
$this->host = $host;
|
|
||||||
$this->port = $port;
|
|
||||||
$this->establishConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
function establishConnection() {
|
|
||||||
$this->__sock = fsockopen($this->host, $this->port, $errno, $errstr);
|
|
||||||
if (!$this->__sock) {
|
|
||||||
throw new Exception("{$errno} - {$errstr}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function __destruct() {
|
|
||||||
fclose($this->__sock);
|
|
||||||
}
|
|
||||||
|
|
||||||
function __call($name, $args) {
|
|
||||||
|
|
||||||
/* Build the Redis unified protocol command */
|
|
||||||
array_unshift($args, strtoupper($name));
|
|
||||||
$command = sprintf('*%d%s%s%s', count($args), CRLF, implode(array_map(array($this, 'formatArgument'), $args), CRLF), CRLF);
|
|
||||||
|
|
||||||
/* Open a Redis connection and execute the command */
|
|
||||||
for ($written = 0; $written < strlen($command); $written += $fwrite) {
|
|
||||||
$fwrite = fwrite($this->__sock, substr($command, $written));
|
|
||||||
if ($fwrite === FALSE) {
|
|
||||||
throw new Exception('Failed to write entire command to stream');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse the response based on the reply identifier */
|
|
||||||
$reply = trim(fgets($this->__sock, 512));
|
|
||||||
switch (substr($reply, 0, 1)) {
|
|
||||||
/* Error reply */
|
|
||||||
case '-':
|
|
||||||
throw new RedisException(substr(trim($reply), 4));
|
|
||||||
break;
|
|
||||||
/* Inline reply */
|
|
||||||
case '+':
|
|
||||||
$response = substr(trim($reply), 1);
|
|
||||||
break;
|
|
||||||
/* Bulk reply */
|
|
||||||
case '$':
|
|
||||||
$response = null;
|
|
||||||
if ($reply == '$-1') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$read = 0;
|
|
||||||
$size = substr($reply, 1);
|
|
||||||
do {
|
|
||||||
$block_size = ($size - $read) > 1024 ? 1024 : ($size - $read);
|
|
||||||
$response .= fread($this->__sock, $block_size);
|
|
||||||
$read += $block_size;
|
|
||||||
} while ($read < $size);
|
|
||||||
fread($this->__sock, 2); /* discard crlf */
|
|
||||||
break;
|
|
||||||
/* Multi-bulk reply */
|
|
||||||
case '*':
|
|
||||||
$count = substr($reply, 1);
|
|
||||||
if ($count == '-1') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$response = array();
|
|
||||||
for ($i = 0; $i < $count; $i++) {
|
|
||||||
$bulk_head = trim(fgets($this->__sock, 512));
|
|
||||||
$size = substr($bulk_head, 1);
|
|
||||||
if ($size == '-1') {
|
|
||||||
$response[] = null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$read = 0;
|
|
||||||
$block = "";
|
|
||||||
do {
|
|
||||||
$block_size = ($size - $read) > 1024 ? 1024 : ($size - $read);
|
|
||||||
$block .= fread($this->__sock, $block_size);
|
|
||||||
$read += $block_size;
|
|
||||||
} while ($read < $size);
|
|
||||||
fread($this->__sock, 2); /* discard crlf */
|
|
||||||
$response[] = $block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
/* Integer reply */
|
|
||||||
case ':':
|
|
||||||
$response = intval(substr(trim($reply), 1));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new RedisException("invalid server response: {$reply}");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Party on */
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function formatArgument($arg) {
|
|
||||||
return sprintf('$%d%s%s', strlen($arg), CRLF, $arg);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,138 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Redisent, a Redis interface for the modest
|
|
||||||
* @author Justin Poliey <jdp34@njit.edu>
|
|
||||||
* @copyright 2009 Justin Poliey <jdp34@njit.edu>
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
* @package Redisent
|
|
||||||
*/
|
|
||||||
|
|
||||||
require_once dirname(__FILE__) . '/Redisent.php';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A generalized Redisent interface for a cluster of Redis servers
|
|
||||||
*/
|
|
||||||
class RedisentCluster {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collection of Redisent objects attached to Redis servers
|
|
||||||
* @var array
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private $redisents;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Aliases of Redisent objects attached to Redis servers, used to route commands to specific servers
|
|
||||||
* @see RedisentCluster::to
|
|
||||||
* @var array
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private $aliases;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hash ring of Redis server nodes
|
|
||||||
* @var array
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private $ring;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Individual nodes of pointers to Redis servers on the hash ring
|
|
||||||
* @var array
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private $nodes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of replicas of each node to make around the hash ring
|
|
||||||
* @var integer
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private $replicas = 128;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The commands that are not subject to hashing
|
|
||||||
* @var array
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private $dont_hash = array(
|
|
||||||
'RANDOMKEY', 'DBSIZE',
|
|
||||||
'SELECT', 'MOVE', 'FLUSHDB', 'FLUSHALL',
|
|
||||||
'SAVE', 'BGSAVE', 'LASTSAVE', 'SHUTDOWN',
|
|
||||||
'INFO', 'MONITOR', 'SLAVEOF'
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Redisent interface to a cluster of Redis servers
|
|
||||||
* @param array $servers The Redis servers in the cluster. Each server should be in the format array('host' => hostname, 'port' => port)
|
|
||||||
*/
|
|
||||||
function __construct($servers) {
|
|
||||||
$this->ring = array();
|
|
||||||
$this->aliases = array();
|
|
||||||
foreach ($servers as $alias => $server) {
|
|
||||||
$this->redisents[] = new Redisent($server['host'], $server['port']);
|
|
||||||
if (is_string($alias)) {
|
|
||||||
$this->aliases[$alias] = $this->redisents[count($this->redisents)-1];
|
|
||||||
}
|
|
||||||
for ($replica = 1; $replica <= $this->replicas; $replica++) {
|
|
||||||
$this->ring[crc32($server['host'].':'.$server['port'].'-'.$replica)] = $this->redisents[count($this->redisents)-1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ksort($this->ring, SORT_NUMERIC);
|
|
||||||
$this->nodes = array_keys($this->ring);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Routes a command to a specific Redis server aliased by {$alias}.
|
|
||||||
* @param string $alias The alias of the Redis server
|
|
||||||
* @return Redisent The Redisent object attached to the Redis server
|
|
||||||
*/
|
|
||||||
function to($alias) {
|
|
||||||
if (isset($this->aliases[$alias])) {
|
|
||||||
return $this->aliases[$alias];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Exception("That Redisent alias does not exist");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Execute a Redis command on the cluster */
|
|
||||||
function __call($name, $args) {
|
|
||||||
|
|
||||||
/* Pick a server node to send the command to */
|
|
||||||
$name = strtoupper($name);
|
|
||||||
if (!in_array($name, $this->dont_hash)) {
|
|
||||||
$node = $this->nextNode(crc32($args[0]));
|
|
||||||
$redisent = $this->ring[$node];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$redisent = $this->redisents[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Execute the command on the server */
|
|
||||||
return call_user_func_array(array($redisent, $name), $args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Routes to the proper server node
|
|
||||||
* @param integer $needle The hash value of the Redis command
|
|
||||||
* @return Redisent The Redisent object associated with the hash
|
|
||||||
*/
|
|
||||||
private function nextNode($needle) {
|
|
||||||
$haystack = $this->nodes;
|
|
||||||
while (count($haystack) > 2) {
|
|
||||||
$try = floor(count($haystack) / 2);
|
|
||||||
if ($haystack[$try] == $needle) {
|
|
||||||
return $needle;
|
|
||||||
}
|
|
||||||
if ($needle < $haystack[$try]) {
|
|
||||||
$haystack = array_slice($haystack, 0, $try + 1);
|
|
||||||
}
|
|
||||||
if ($needle > $haystack[$try]) {
|
|
||||||
$haystack = array_slice($haystack, $try + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $haystack[count($haystack)-1];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once dirname(__FILE__) . '/Resque/Event.php';
|
|
||||||
require_once dirname(__FILE__) . '/Resque/Exception.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base Resque class.
|
* Base Resque class.
|
||||||
*
|
*
|
||||||
* @package Resque
|
* @package Resque
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque
|
class Resque
|
||||||
{
|
{
|
||||||
const VERSION = '1.0';
|
const VERSION = '1.2';
|
||||||
|
|
||||||
const DEFAULT_INTERVAL = 5;
|
const DEFAULT_INTERVAL = 5;
|
||||||
|
|
||||||
@ -32,12 +28,6 @@ class Resque
|
|||||||
*/
|
*/
|
||||||
protected static $redisDatabase = 0;
|
protected static $redisDatabase = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int PID of current process. Used to detect changes when forking
|
|
||||||
* and implement "thread" safety to avoid race conditions.
|
|
||||||
*/
|
|
||||||
protected static $pid = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a host/port combination separated by a colon, set it as
|
* Given a host/port combination separated by a colon, set it as
|
||||||
* the redis server that Resque will talk to.
|
* the redis server that Resque will talk to.
|
||||||
@ -60,15 +50,7 @@ class Resque
|
|||||||
*/
|
*/
|
||||||
public static function redis()
|
public static function redis()
|
||||||
{
|
{
|
||||||
// Detect when the PID of the current process has changed (from a fork, etc)
|
if (self::$redis !== null) {
|
||||||
// and force a reconnect to redis.
|
|
||||||
$pid = getmypid();
|
|
||||||
if (self::$pid !== $pid) {
|
|
||||||
self::$redis = null;
|
|
||||||
self::$pid = $pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!is_null(self::$redis)) {
|
|
||||||
return self::$redis;
|
return self::$redis;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,24 +59,35 @@ class Resque
|
|||||||
$server = 'localhost:6379';
|
$server = 'localhost:6379';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_array($server)) {
|
self::$redis = new Resque_Redis($server, self::$redisDatabase);
|
||||||
require_once dirname(__FILE__) . '/Resque/RedisCluster.php';
|
return self::$redis;
|
||||||
self::$redis = new Resque_RedisCluster($server);
|
}
|
||||||
}
|
|
||||||
else {
|
/**
|
||||||
if (strpos($server, 'unix:') === false) {
|
* fork() helper method for php-resque that handles issues PHP socket
|
||||||
list($host, $port) = explode(':', $server);
|
* and phpredis have with passing around sockets between child/parent
|
||||||
}
|
* processes.
|
||||||
else {
|
*
|
||||||
$host = $server;
|
* Will close connection to Redis before forking.
|
||||||
$port = null;
|
*
|
||||||
}
|
* @return int Return vars as per pcntl_fork()
|
||||||
require_once dirname(__FILE__) . '/Resque/Redis.php';
|
*/
|
||||||
self::$redis = new Resque_Redis($host, $port);
|
public static function fork()
|
||||||
|
{
|
||||||
|
if(!function_exists('pcntl_fork')) {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$redis->select(self::$redisDatabase);
|
// Close the connection to Redis before forking.
|
||||||
return self::$redis;
|
// 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.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,7 +149,6 @@ class Resque
|
|||||||
*/
|
*/
|
||||||
public static function enqueue($queue, $class, $args = null, $trackStatus = false)
|
public static function enqueue($queue, $class, $args = null, $trackStatus = false)
|
||||||
{
|
{
|
||||||
require_once dirname(__FILE__) . '/Resque/Job.php';
|
|
||||||
$result = Resque_Job::create($queue, $class, $args, $trackStatus);
|
$result = Resque_Job::create($queue, $class, $args, $trackStatus);
|
||||||
if ($result) {
|
if ($result) {
|
||||||
Resque_Event::trigger('afterEnqueue', array(
|
Resque_Event::trigger('afterEnqueue', array(
|
||||||
@ -177,7 +169,6 @@ class Resque
|
|||||||
*/
|
*/
|
||||||
public static function reserve($queue, $interval = null)
|
public static function reserve($queue, $interval = null)
|
||||||
{
|
{
|
||||||
require_once dirname(__FILE__) . '/Resque/Job.php';
|
|
||||||
return Resque_Job::reserve($queue, $interval);
|
return Resque_Job::reserve($queue, $interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
* Resque event/plugin system class
|
* Resque event/plugin system class
|
||||||
*
|
*
|
||||||
* @package Resque/Event
|
* @package Resque/Event
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Event
|
class Resque_Event
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
* Resque exception.
|
* Resque exception.
|
||||||
*
|
*
|
||||||
* @package Resque
|
* @package Resque
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Exception extends Exception
|
class Resque_Exception extends Exception
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once dirname(__FILE__) . '/Failure/Interface.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Failed Resque job.
|
* Failed Resque job.
|
||||||
*
|
*
|
||||||
* @package Resque/Failure
|
* @package Resque/Failure
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Failure
|
class Resque_Failure
|
||||||
@ -38,7 +36,6 @@ class Resque_Failure
|
|||||||
public static function getBackend()
|
public static function getBackend()
|
||||||
{
|
{
|
||||||
if(self::$backend === null) {
|
if(self::$backend === null) {
|
||||||
require dirname(__FILE__) . '/Failure/Redis.php';
|
|
||||||
self::$backend = 'Resque_Failure_Redis';
|
self::$backend = 'Resque_Failure_Redis';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
* Interface that all failure backends should implement.
|
* Interface that all failure backends should implement.
|
||||||
*
|
*
|
||||||
* @package Resque/Failure
|
* @package Resque/Failure
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
interface Resque_Failure_Interface
|
interface Resque_Failure_Interface
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
* Redis backend for storing failed Resque jobs.
|
* Redis backend for storing failed Resque jobs.
|
||||||
*
|
*
|
||||||
* @package Resque/Failure
|
* @package Resque/Failure
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once dirname(__FILE__) . '/Event.php';
|
|
||||||
require_once dirname(__FILE__) . '/Job/Status.php';
|
|
||||||
require_once dirname(__FILE__) . '/Job/DontPerform.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resque job.
|
* Resque job.
|
||||||
*
|
*
|
||||||
* @package Resque/Job
|
* @package Resque/Job
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Job
|
class Resque_Job
|
||||||
@ -209,7 +204,6 @@ class Resque_Job
|
|||||||
));
|
));
|
||||||
|
|
||||||
$this->updateStatus(Resque_Job_Status::STATUS_FAILED);
|
$this->updateStatus(Resque_Job_Status::STATUS_FAILED);
|
||||||
require_once dirname(__FILE__) . '/Failure.php';
|
|
||||||
Resque_Failure::create(
|
Resque_Failure::create(
|
||||||
$this->payload,
|
$this->payload,
|
||||||
$exception,
|
$exception,
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
* Runtime exception class for a job that does not exit cleanly.
|
* Runtime exception class for a job that does not exit cleanly.
|
||||||
*
|
*
|
||||||
* @package Resque/Job
|
* @package Resque/Job
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Job_DirtyExitException extends RuntimeException
|
class Resque_Job_DirtyExitException extends RuntimeException
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
* Exception to be thrown if a job should not be performed/run.
|
* Exception to be thrown if a job should not be performed/run.
|
||||||
*
|
*
|
||||||
* @package Resque/Job
|
* @package Resque/Job
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Job_DontPerform extends Exception
|
class Resque_Job_DontPerform extends Exception
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
* Status tracker/information for a job.
|
* Status tracker/information for a job.
|
||||||
*
|
*
|
||||||
* @package Resque/Job
|
* @package Resque/Job
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Job_Status
|
class Resque_Job_Status
|
||||||
|
@ -1,26 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
// Third- party apps may have already loaded Resident from elsewhere
|
|
||||||
// so lets be careful.
|
|
||||||
if(!class_exists('Redisent', false)) {
|
|
||||||
require_once dirname(__FILE__) . '/../Redisent/Redisent.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extended Redisent class used by Resque for all communication with
|
* Wrap Credis to add namespace support and various helper methods.
|
||||||
* redis. Essentially adds namespace support to Redisent.
|
|
||||||
*
|
*
|
||||||
* @package Resque/Redis
|
* @package Resque/Redis
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Redis extends Redisent
|
class Resque_Redis
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Redis namespace
|
* Redis namespace
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private static $defaultNamespace = 'resque:';
|
private static $defaultNamespace = 'resque:';
|
||||||
|
|
||||||
|
private $server;
|
||||||
|
private $database;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array List of all commands in Redis that supply a key as their
|
* @var array List of all commands in Redis that supply a key as their
|
||||||
* first argument. Used to prefix keys with the Resque namespace.
|
* first argument. Used to prefix keys with the Resque namespace.
|
||||||
@ -34,6 +30,7 @@ class Resque_Redis extends Redisent
|
|||||||
'ttl',
|
'ttl',
|
||||||
'move',
|
'move',
|
||||||
'set',
|
'set',
|
||||||
|
'setex',
|
||||||
'get',
|
'get',
|
||||||
'getset',
|
'getset',
|
||||||
'setnx',
|
'setnx',
|
||||||
@ -82,7 +79,7 @@ class Resque_Redis extends Redisent
|
|||||||
// msetnx
|
// msetnx
|
||||||
// mset
|
// mset
|
||||||
// renamenx
|
// renamenx
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Redis namespace (prefix) default: resque
|
* Set Redis namespace (prefix) default: resque
|
||||||
* @param string $namespace
|
* @param string $namespace
|
||||||
@ -94,7 +91,48 @@ class Resque_Redis extends Redisent
|
|||||||
}
|
}
|
||||||
self::$defaultNamespace = $namespace;
|
self::$defaultNamespace = $namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __construct($server, $database = null)
|
||||||
|
{
|
||||||
|
$this->server = $server;
|
||||||
|
$this->database = $database;
|
||||||
|
|
||||||
|
if (is_array($this->server)) {
|
||||||
|
$this->driver = new Credis_Cluster($server);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$port = null;
|
||||||
|
$password = null;
|
||||||
|
$host = $server;
|
||||||
|
|
||||||
|
// If not a UNIX socket path or tcp:// formatted connections string
|
||||||
|
// assume host:port combination.
|
||||||
|
if (strpos($server, '/') === false) {
|
||||||
|
$parts = explode(':', $server);
|
||||||
|
if (isset($parts[1])) {
|
||||||
|
$port = $parts[1];
|
||||||
|
}
|
||||||
|
$host = $parts[0];
|
||||||
|
}else if (strpos($server, 'redis://') !== false){
|
||||||
|
// Redis format is:
|
||||||
|
// redis://[user]:[password]@[host]:[port]
|
||||||
|
list($userpwd,$hostport) = explode('@', $server);
|
||||||
|
$userpwd = substr($userpwd, strpos($userpwd, 'redis://')+8);
|
||||||
|
list($host, $port) = explode(':', $hostport);
|
||||||
|
list($user, $password) = explode(':', $userpwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->driver = new Credis_Client($host, $port);
|
||||||
|
if (isset($password)){
|
||||||
|
$this->driver->auth($password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->database !== null) {
|
||||||
|
$this->driver->select($database);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Magic method to handle all function requests and prefix key based
|
* Magic method to handle all function requests and prefix key based
|
||||||
* operations with the {self::$defaultNamespace} key prefix.
|
* operations with the {self::$defaultNamespace} key prefix.
|
||||||
@ -104,16 +142,30 @@ class Resque_Redis extends Redisent
|
|||||||
* @return mixed Return value from Resident::call() based on the command.
|
* @return mixed Return value from Resident::call() based on the command.
|
||||||
*/
|
*/
|
||||||
public function __call($name, $args) {
|
public function __call($name, $args) {
|
||||||
$args = func_get_args();
|
|
||||||
if(in_array($name, $this->keyCommands)) {
|
if(in_array($name, $this->keyCommands)) {
|
||||||
$args[1][0] = self::$defaultNamespace . $args[1][0];
|
$args[0] = self::$defaultNamespace . $args[0];
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return parent::__call($name, $args[1]);
|
return $this->driver->__call($name, $args);
|
||||||
}
|
}
|
||||||
catch(RedisException $e) {
|
catch(CredisException $e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
@ -1,119 +0,0 @@
|
|||||||
<?php
|
|
||||||
// Third- party apps may have already loaded Resident from elsewhere
|
|
||||||
// so lets be careful.
|
|
||||||
if(!class_exists('RedisentCluster', false)) {
|
|
||||||
require_once dirname(__FILE__) . '/../Redisent/RedisentCluster.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extended Redisent class used by Resque for all communication with
|
|
||||||
* redis. Essentially adds namespace support to Redisent.
|
|
||||||
*
|
|
||||||
* @package Resque/Redis
|
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
|
||||||
*/
|
|
||||||
class Resque_RedisCluster extends RedisentCluster
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Redis namespace
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private static $defaultNamespace = 'resque:';
|
|
||||||
/**
|
|
||||||
* @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',
|
|
||||||
'get',
|
|
||||||
'getset',
|
|
||||||
'setnx',
|
|
||||||
'incr',
|
|
||||||
'incrby',
|
|
||||||
'decrby',
|
|
||||||
'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'
|
|
||||||
);
|
|
||||||
// sinterstore
|
|
||||||
// sunion
|
|
||||||
// sunionstore
|
|
||||||
// sdiff
|
|
||||||
// sdiffstore
|
|
||||||
// sinter
|
|
||||||
// smove
|
|
||||||
// rename
|
|
||||||
// rpoplpush
|
|
||||||
// mget
|
|
||||||
// msetnx
|
|
||||||
// mset
|
|
||||||
// renamenx
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Redis namespace (prefix) default: resque
|
|
||||||
* @param string $namespace
|
|
||||||
*/
|
|
||||||
public static function prefix($namespace)
|
|
||||||
{
|
|
||||||
if (strpos($namespace, ':') === false) {
|
|
||||||
$namespace .= ':';
|
|
||||||
}
|
|
||||||
self::$defaultNamespace = $namespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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) {
|
|
||||||
$args = func_get_args();
|
|
||||||
if(in_array($name, $this->keyCommands)) {
|
|
||||||
$args[1][0] = self::$defaultNamespace . $args[1][0];
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return parent::__call($name, $args[1]);
|
|
||||||
}
|
|
||||||
catch(RedisException $e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
@ -3,8 +3,7 @@
|
|||||||
* Resque statistic management (jobs processed, failed, etc)
|
* Resque statistic management (jobs processed, failed, etc)
|
||||||
*
|
*
|
||||||
* @package Resque/Stat
|
* @package Resque/Stat
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Stat
|
class Resque_Stat
|
||||||
|
@ -1,16 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once dirname(__FILE__) . '/Stat.php';
|
|
||||||
require_once dirname(__FILE__) . '/Event.php';
|
|
||||||
require_once dirname(__FILE__) . '/Job.php';
|
|
||||||
require_once dirname(__FILE__) . '/Job/DirtyExitException.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resque worker that handles checking queues for jobs, fetching them
|
* Resque worker that handles checking queues for jobs, fetching them
|
||||||
* off the queues, running them and handling the result.
|
* off the queues, running them and handling the result.
|
||||||
*
|
*
|
||||||
* @package Resque/Worker
|
* @package Resque/Worker
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Worker
|
class Resque_Worker
|
||||||
@ -190,7 +184,7 @@ class Resque_Worker
|
|||||||
Resque_Event::trigger('beforeFork', $job);
|
Resque_Event::trigger('beforeFork', $job);
|
||||||
$this->workingOn($job);
|
$this->workingOn($job);
|
||||||
|
|
||||||
$this->child = $this->fork();
|
$this->child = Resque::fork();
|
||||||
|
|
||||||
// Forked and we're the child. Run the job.
|
// Forked and we're the child. Run the job.
|
||||||
if ($this->child === 0 || $this->child === false) {
|
if ($this->child === 0 || $this->child === false) {
|
||||||
@ -292,27 +286,6 @@ class Resque_Worker
|
|||||||
return $queues;
|
return $queues;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempt to fork a child process from the parent to run a job in.
|
|
||||||
*
|
|
||||||
* Return values are those of pcntl_fork().
|
|
||||||
*
|
|
||||||
* @return int -1 if the fork failed, 0 for the forked child, the PID of the child for the parent.
|
|
||||||
*/
|
|
||||||
private function fork()
|
|
||||||
{
|
|
||||||
if(!function_exists('pcntl_fork')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$pid = pcntl_fork();
|
|
||||||
if($pid === -1) {
|
|
||||||
throw new RuntimeException('Unable to fork child worker.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform necessary actions to start a worker.
|
* Perform necessary actions to start a worker.
|
||||||
*/
|
*/
|
||||||
@ -480,7 +453,7 @@ class Resque_Worker
|
|||||||
*/
|
*/
|
||||||
public function registerWorker()
|
public function registerWorker()
|
||||||
{
|
{
|
||||||
Resque::redis()->sadd('workers', $this);
|
Resque::redis()->sadd('workers', (string)$this);
|
||||||
Resque::redis()->set('worker:' . (string)$this . ':started', strftime('%a %b %d %H:%M:%S %Z %Y'));
|
Resque::redis()->set('worker:' . (string)$this . ':started', strftime('%a %b %d %H:%M:%S %Z %Y'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,16 +517,21 @@ class Resque_Worker
|
|||||||
/**
|
/**
|
||||||
* Output a given log message to STDOUT.
|
* Output a given log message to STDOUT.
|
||||||
*
|
*
|
||||||
* @param string $message Message to output.
|
* @param string $message Message to output.
|
||||||
|
* @param int $logLevel The logging level to capture
|
||||||
*/
|
*/
|
||||||
public function log($message)
|
public function log($message, $logLevel = self::LOG_NORMAL)
|
||||||
{
|
{
|
||||||
if($this->logLevel == self::LOG_NORMAL) {
|
if ($logLevel > $this->logLevel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->logLevel == self::LOG_NORMAL) {
|
||||||
fwrite(STDOUT, "*** " . $message . "\n");
|
fwrite(STDOUT, "*** " . $message . "\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if($this->logLevel == self::LOG_VERBOSE) {
|
|
||||||
fwrite(STDOUT, "** [" . strftime('%T %Y-%m-%d') . "] " . $message . "\n");
|
fwrite(STDOUT, "** [" . strftime('%T %Y-%m-%d') . "] " . $message . "\n");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<phpunit backupGlobals="false"
|
<phpunit backupGlobals="false"
|
||||||
|
bootstrap="test/bootstrap.php"
|
||||||
backupStaticAttributes="false"
|
backupStaticAttributes="false"
|
||||||
colors="false"
|
colors="true"
|
||||||
convertErrorsToExceptions="true"
|
convertErrorsToExceptions="true"
|
||||||
convertNoticesToExceptions="true"
|
convertNoticesToExceptions="true"
|
||||||
convertWarningsToExceptions="true"
|
convertWarningsToExceptions="true"
|
||||||
|
79
resque.php
79
resque.php
@ -1,79 +0,0 @@
|
|||||||
<?php
|
|
||||||
$QUEUE = getenv('QUEUE');
|
|
||||||
if(empty($QUEUE)) {
|
|
||||||
die("Set QUEUE env var containing the list of queues to work.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once 'lib/Resque.php';
|
|
||||||
require_once 'lib/Resque/Worker.php';
|
|
||||||
|
|
||||||
$REDIS_BACKEND = getenv('REDIS_BACKEND');
|
|
||||||
if(!empty($REDIS_BACKEND)) {
|
|
||||||
Resque::setBackend($REDIS_BACKEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
$logLevel = 0;
|
|
||||||
$LOGGING = getenv('LOGGING');
|
|
||||||
$VERBOSE = getenv('VERBOSE');
|
|
||||||
$VVERBOSE = getenv('VVERBOSE');
|
|
||||||
if(!empty($LOGGING) || !empty($VERBOSE)) {
|
|
||||||
$logLevel = Resque_Worker::LOG_NORMAL;
|
|
||||||
}
|
|
||||||
else if(!empty($VVERBOSE)) {
|
|
||||||
$logLevel = Resque_Worker::LOG_VERBOSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
$APP_INCLUDE = getenv('APP_INCLUDE');
|
|
||||||
if($APP_INCLUDE) {
|
|
||||||
if(!file_exists($APP_INCLUDE)) {
|
|
||||||
die('APP_INCLUDE ('.$APP_INCLUDE.") does not exist.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once $APP_INCLUDE;
|
|
||||||
}
|
|
||||||
|
|
||||||
$interval = 5;
|
|
||||||
$INTERVAL = getenv('INTERVAL');
|
|
||||||
if(!empty($INTERVAL)) {
|
|
||||||
$interval = $INTERVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
$count = 1;
|
|
||||||
$COUNT = getenv('COUNT');
|
|
||||||
if(!empty($COUNT) && $COUNT > 1) {
|
|
||||||
$count = $COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if($count > 1) {
|
|
||||||
for($i = 0; $i < $count; ++$i) {
|
|
||||||
$pid = pcntl_fork();
|
|
||||||
if($pid == -1) {
|
|
||||||
die("Could not fork worker ".$i."\n");
|
|
||||||
}
|
|
||||||
// Child, start the worker
|
|
||||||
else if(!$pid) {
|
|
||||||
$queues = explode(',', $QUEUE);
|
|
||||||
$worker = new Resque_Worker($queues);
|
|
||||||
$worker->logLevel = $logLevel;
|
|
||||||
fwrite(STDOUT, '*** Starting worker '.$worker."\n");
|
|
||||||
$worker->work($interval);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Start a single worker
|
|
||||||
else {
|
|
||||||
$queues = explode(',', $QUEUE);
|
|
||||||
$worker = new Resque_Worker($queues);
|
|
||||||
$worker->logLevel = $logLevel;
|
|
||||||
|
|
||||||
$PIDFILE = getenv('PIDFILE');
|
|
||||||
if ($PIDFILE) {
|
|
||||||
file_put_contents($PIDFILE, getmypid()) or
|
|
||||||
die('Could not write PID information to ' . $PIDFILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
fwrite(STDOUT, '*** Starting worker '.$worker."\n");
|
|
||||||
$worker->work($interval);
|
|
||||||
}
|
|
||||||
?>
|
|
@ -1,12 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once dirname(__FILE__) . '/bootstrap.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resque_Event tests.
|
* Resque_Event tests.
|
||||||
*
|
*
|
||||||
* @package Resque/Tests
|
* @package Resque/Tests
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Tests_EventTest extends Resque_Tests_TestCase
|
class Resque_Tests_EventTest extends Resque_Tests_TestCase
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once dirname(__FILE__) . '/bootstrap.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resque_Job_Status tests.
|
* Resque_Job_Status tests.
|
||||||
*
|
*
|
||||||
* @package Resque/Tests
|
* @package Resque/Tests
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Tests_JobStatusTest extends Resque_Tests_TestCase
|
class Resque_Tests_JobStatusTest extends Resque_Tests_TestCase
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once dirname(__FILE__) . '/bootstrap.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resque_Job tests.
|
* Resque_Job tests.
|
||||||
*
|
*
|
||||||
* @package Resque/Tests
|
* @package Resque/Tests
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Tests_JobTest extends Resque_Tests_TestCase
|
class Resque_Tests_JobTest extends Resque_Tests_TestCase
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once dirname(__FILE__) . '/bootstrap.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resque_Stat tests.
|
* Resque_Stat tests.
|
||||||
*
|
*
|
||||||
* @package Resque/Tests
|
* @package Resque/Tests
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Tests_StatTest extends Resque_Tests_TestCase
|
class Resque_Tests_StatTest extends Resque_Tests_TestCase
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
* Resque test case class. Contains setup and teardown methods.
|
* Resque test case class. Contains setup and teardown methods.
|
||||||
*
|
*
|
||||||
* @package Resque/Tests
|
* @package Resque/Tests
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @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
|
||||||
@ -16,7 +15,7 @@ class Resque_Tests_TestCase extends PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
$config = file_get_contents(REDIS_CONF);
|
$config = file_get_contents(REDIS_CONF);
|
||||||
preg_match('#^\s*port\s+([0-9]+)#m', $config, $matches);
|
preg_match('#^\s*port\s+([0-9]+)#m', $config, $matches);
|
||||||
$this->redis = new Redisent('localhost', $matches[1]);
|
$this->redis = new Credis_Client('localhost', $matches[1]);
|
||||||
|
|
||||||
// Flush redis
|
// Flush redis
|
||||||
$this->redis->flushAll();
|
$this->redis->flushAll();
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once dirname(__FILE__) . '/bootstrap.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resque_Worker tests.
|
* Resque_Worker tests.
|
||||||
*
|
*
|
||||||
* @package Resque/Tests
|
* @package Resque/Tests
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
|
class Resque_Tests_WorkerTest extends Resque_Tests_TestCase
|
||||||
|
@ -3,26 +3,16 @@
|
|||||||
* Resque test bootstrap file - sets up a test environment.
|
* Resque test bootstrap file - sets up a test environment.
|
||||||
*
|
*
|
||||||
* @package Resque/Tests
|
* @package Resque/Tests
|
||||||
* @author Chris Boulton <chris.boulton@interspire.com>
|
* @author Chris Boulton <chris@bigcommerce.com>
|
||||||
* @copyright (c) 2010 Chris Boulton
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php
|
* @license http://www.opensource.org/licenses/mit-license.php
|
||||||
*/
|
*/
|
||||||
define('CWD', dirname(__FILE__));
|
|
||||||
define('RESQUE_LIB', CWD . '/../../../lib/');
|
|
||||||
|
|
||||||
define('TEST_MISC', realpath(CWD . '/../../misc/'));
|
$loader = require __DIR__ . '/../vendor/autoload.php';
|
||||||
|
$loader->add('Resque_Tests', __DIR__);
|
||||||
|
|
||||||
|
define('TEST_MISC', realpath(__DIR__ . '/misc/'));
|
||||||
define('REDIS_CONF', TEST_MISC . '/redis.conf');
|
define('REDIS_CONF', TEST_MISC . '/redis.conf');
|
||||||
|
|
||||||
// Change to the directory this file lives in. This is important, due to
|
|
||||||
// how we'll be running redis.
|
|
||||||
|
|
||||||
require_once CWD . '/TestCase.php';
|
|
||||||
|
|
||||||
// Include Resque
|
|
||||||
require_once RESQUE_LIB . 'Resque.php';
|
|
||||||
require_once RESQUE_LIB . 'Resque/Worker.php';
|
|
||||||
require_once RESQUE_LIB . 'Resque/Redis.php';
|
|
||||||
|
|
||||||
// Attempt to start our own redis instance for tesitng.
|
// Attempt to start our own redis instance for tesitng.
|
||||||
exec('which redis-server', $output, $returnVar);
|
exec('which redis-server', $output, $returnVar);
|
||||||
if($returnVar != 0) {
|
if($returnVar != 0) {
|
||||||
@ -62,7 +52,7 @@ function killRedis($pid)
|
|||||||
if (file_exists($pidFile)) {
|
if (file_exists($pidFile)) {
|
||||||
$pid = trim(file_get_contents($pidFile));
|
$pid = trim(file_get_contents($pidFile));
|
||||||
posix_kill((int) $pid, 9);
|
posix_kill((int) $pid, 9);
|
||||||
|
|
||||||
if(is_file($pidFile)) {
|
if(is_file($pidFile)) {
|
||||||
unlink($pidFile);
|
unlink($pidFile);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user