/** * Mark the current job as having failed * * @param \Exception $e */ public function fail(\Exception $e) { $this->stopped(); $this->setStatus(Job::STATUS_FAILED, $e); // For the failed jobs we store a lot more data for debugging $packet = $this->getPacket(); $failed_payload = array_merge(json_decode($this->payload, true), array('worker' => $packet['worker'], 'started' => $packet['started'], 'finished' => $packet['finished'], 'output' => $packet['output'], 'exception' => (array) json_decode($packet['exception'], true))); $this->redis->zadd(Queue::redisKey($this->queue, 'failed'), time(), json_encode($failed_payload)); Stats::incr('failed', 1); Stats::incr('failed', 1, Queue::redisKey($this->queue, 'stats')); Event::fire(Event::JOB_FAILURE, array($this, $e)); }
/** * Look for any workers which should be running on this server and if * they're not, remove them from Redis. * * 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. */ public function cleanup() { $workers = self::allWorkers(); $hosts = $this->redis->smembers(Host::redisKey()); $cleaned = array(); foreach ($workers as $worker) { list($host, $pid) = explode(':', (string) $worker, 2); if ($host != (string) $this->host and in_array($host, $hosts) or $host == (string) $this->host and posix_kill((int) $pid, 0)) { continue; } $this->log('Pruning dead worker: ' . $worker, Logger::DEBUG); $worker->unregister(); $cleaned[] = (string) $worker; } $workerIds = array_map(function ($w) { return (string) $w; }, $workers); $keys = (array) $this->redis->keys('worker:' . $this->host . ':*'); foreach ($keys as $key) { $key = $this->redis->removeNamespace($key); $id = substr($key, strlen('worker:')); if (!in_array($id, $workerIds)) { if ($this->redis->ttl($key) < 0) { $this->log('Expiring worker data: ' . $key, Logger::DEBUG); $this->redis->expire($key, \Resque::getConfig('default.expiry_time', \Resque::DEFAULT_EXPIRY_TIME)); } } } Event::fire(Event::WORKER_CLEANUP, array($this, $cleaned)); return $cleaned; }