Fix a bug where the worker would spin out of control taking the server with it, if the redis connection was interrupted even briefly. Use SIGPIPE to trap this scenario cleanly.

This commit is contained in:
d11wtq 2011-09-24 15:08:53 +10:00
parent 700af834b4
commit c90e21d88e
2 changed files with 14 additions and 0 deletions

View File

@ -49,6 +49,10 @@ class Redisent {
function __construct($host, $port = 6379) { function __construct($host, $port = 6379) {
$this->host = $host; $this->host = $host;
$this->port = $port; $this->port = $port;
$this->establishConnection();
}
function establishConnection() {
$this->__sock = fsockopen($this->host, $this->port, $errno, $errstr); $this->__sock = fsockopen($this->host, $this->port, $errno, $errstr);
if (!$this->__sock) { if (!$this->__sock) {
throw new Exception("{$errno} - {$errstr}"); throw new Exception("{$errno} - {$errstr}");

View File

@ -358,6 +358,7 @@ class Resque_Worker
pcntl_signal(SIGUSR1, array($this, 'killChild')); pcntl_signal(SIGUSR1, array($this, 'killChild'));
pcntl_signal(SIGUSR2, array($this, 'pauseProcessing')); pcntl_signal(SIGUSR2, array($this, 'pauseProcessing'));
pcntl_signal(SIGCONT, array($this, 'unPauseProcessing')); pcntl_signal(SIGCONT, array($this, 'unPauseProcessing'));
pcntl_signal(SIGPIPE, array($this, 'reestablishRedisConnection'));
$this->log('Registered signals', self::LOG_VERBOSE); $this->log('Registered signals', self::LOG_VERBOSE);
} }
@ -380,6 +381,15 @@ class Resque_Worker
$this->paused = false; $this->paused = false;
} }
/**
* Signal handler for SIGPIPE, in the event the redis connection has gone away.
* Attempts to reconnect to redis, or raises an Exception.
*/
public function reestablishRedisConnection() {
$this->log('SIGPIPE received; attempting to reconnect');
Resque::redis()->establishConnection();
}
/** /**
* Schedule a worker for shutdown. Will finish processing the current job * Schedule a worker for shutdown. Will finish processing the current job
* and when the timeout interval is reached, the worker will shut down. * and when the timeout interval is reached, the worker will shut down.