From c90e21d88eb2a495c52dfb81d95b3af701995029 Mon Sep 17 00:00:00 2001 From: d11wtq Date: Sat, 24 Sep 2011 15:08:53 +1000 Subject: [PATCH] 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. --- lib/Redisent/Redisent.php | 4 ++++ lib/Resque/Worker.php | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/lib/Redisent/Redisent.php b/lib/Redisent/Redisent.php index ac70c81..19f5cdf 100644 --- a/lib/Redisent/Redisent.php +++ b/lib/Redisent/Redisent.php @@ -49,6 +49,10 @@ class Redisent { 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}"); diff --git a/lib/Resque/Worker.php b/lib/Resque/Worker.php index a5c70b9..3e7eefc 100644 --- a/lib/Resque/Worker.php +++ b/lib/Resque/Worker.php @@ -358,6 +358,7 @@ class Resque_Worker pcntl_signal(SIGUSR1, array($this, 'killChild')); pcntl_signal(SIGUSR2, array($this, 'pauseProcessing')); pcntl_signal(SIGCONT, array($this, 'unPauseProcessing')); + pcntl_signal(SIGPIPE, array($this, 'reestablishRedisConnection')); $this->log('Registered signals', self::LOG_VERBOSE); } @@ -380,6 +381,15 @@ class Resque_Worker $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 * and when the timeout interval is reached, the worker will shut down.