/** * Look for any jobs which are running but the worker is dead. * Meaning that they are also not running but left in limbo * * This is a form of garbage collection to handle cases where the * server may have been killed and the workers did not die gracefully * and therefore leave state information in Redis. * * @param array $queues list of queues to check */ public static function cleanup(array $queues = array('*')) { $cleaned = array('zombie' => 0, 'processed' => 0); $redis = Redis::instance(); if (in_array('*', $queues)) { $queues = (array) $redis->smembers(Queue::redisKey()); sort($queues); } $workers = $redis->smembers(Worker::redisKey()); foreach ($queues as $queue) { $jobs = $redis->zrangebyscore(Queue::redisKey($queue, 'running'), 0, time()); foreach ($jobs as $payload) { $job = self::loadPayload($queue, $payload); $packet = $job->getPacket(); if (!in_array($packet['worker'], $workers)) { $job->fail(new Exception\Zombie()); $cleaned['zombie']++; } } $cleaned['processed'] = $redis->zremrangebyscore(Queue::redisKey($queue, 'processed'), 0, time() - \Resque::getConfig('default.expiry_time', \Resque::DEFAULT_EXPIRY_TIME)); } return $cleaned; }
/** * Cleans up any dead hosts * * @return array List of cleaned hosts */ public function cleanup() { $hosts = $this->redis->smembers(self::redisKey()); $workers = $this->redis->smembers(Worker::redisKey()); $cleaned = array('hosts' => array(), 'workers' => array()); foreach ($hosts as $hostname) { $host = new static($hostname); if (!$this->redis->exists(self::redisKey($host))) { $this->redis->srem(self::redisKey(), (string) $host); $cleaned['hosts'][] = (string) $host; } else { $host_workers = $this->redis->smembers(self::redisKey($host)); foreach ($host_workers as $host_worker) { if (!in_array($host_worker, $workers)) { $cleaned['workers'][] = $host_worker; $this->redis->srem(self::redisKey($host), $host_worker); } } } } return $cleaned; }