Skip to content

Commit ebe7665

Browse files
author
Chris Boulton
committed
fix lost jobs when there is more than one worker process started by the same parent process
1 parent 4700375 commit ebe7665

File tree

1 file changed

+46
-13
lines changed

1 file changed

+46
-13
lines changed

lib/Resque.php

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,23 @@ class Resque
1919
*/
2020
public static $redis = null;
2121

22+
/**
23+
* @var mixed Host/port conbination separated by a colon, or a nested
24+
* array of server swith host/port pairs
25+
*/
26+
protected static $redisServer = null;
27+
28+
/**
29+
* @var int ID of Redis database to select.
30+
*/
31+
protected static $redisDatabase = 0;
32+
33+
/**
34+
* @var int PID of current process. Used to detect changes when forking
35+
* and implement "thread" safety to avoid race conditions.
36+
*/
37+
protected static $pid = null;
38+
2239
/**
2340
* Given a host/port combination separated by a colon, set it as
2441
* the redis server that Resque will talk to.
@@ -28,17 +45,9 @@ class Resque
2845
*/
2946
public static function setBackend($server, $database = 0)
3047
{
31-
if(is_array($server)) {
32-
require_once dirname(__FILE__) . '/Resque/RedisCluster.php';
33-
self::$redis = new Resque_RedisCluster($server);
34-
}
35-
else {
36-
list($host, $port) = explode(':', $server);
37-
require_once dirname(__FILE__) . '/Resque/Redis.php';
38-
self::$redis = new Resque_Redis($host, $port);
39-
}
40-
41-
self::redis()->select($database);
48+
self::$redisServer = $server;
49+
self::$redisDatabase = $database;
50+
self::$redis = null;
4251
}
4352

4453
/**
@@ -48,10 +57,34 @@ public static function setBackend($server, $database = 0)
4857
*/
4958
public static function redis()
5059
{
51-
if(is_null(self::$redis)) {
52-
self::setBackend('localhost:6379');
60+
// Detect when the PID of the current process has changed (from a fork, etc)
61+
// and force a reconnect to redis.
62+
$pid = getmypid();
63+
if (self::$pid !== $pid) {
64+
self::$redis = null;
65+
self::$pid = $pid;
66+
}
67+
68+
if(!is_null(self::$redis)) {
69+
return self::$redis;
70+
}
71+
72+
$server = self::$redisServer;
73+
if (empty($server)) {
74+
$server = 'localhost:6379';
75+
}
76+
77+
if(is_array($server)) {
78+
require_once dirname(__FILE__) . '/Resque/RedisCluster.php';
79+
self::$redis = new Resque_RedisCluster($server);
80+
}
81+
else {
82+
list($host, $port) = explode(':', $server);
83+
require_once dirname(__FILE__) . '/Resque/Redis.php';
84+
self::$redis = new Resque_Redis($host, $port);
5385
}
5486

87+
self::$redis->select(self::$redisDatabase);
5588
return self::$redis;
5689
}
5790

0 commit comments

Comments
 (0)