/** * Push a new job onto the queue * * @param string $job The job class * @param mixed $data The job data * @param string $queue The queue to add the job to * @return Job job instance */ public function push($job, array $data = null, $queue = null) { if (false !== ($delay = \Resque::getConfig('default.jobs.delay', false))) { return $this->later($delay, $job, $data, $queue); } return Job::create($this->getQueue($queue), $job, $data); }
/** * 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; }
/** * 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; }