/** * Constructor * Checks for the required gearman extension, * fetches the bootstrap and loads in the gearman worker * * @return Gearman_Worker */ public function __construct($bootstrap) { if (!extension_loaded('gearman')) { throw new RuntimeException('The PECL::gearman extension is required.'); } $this->_worker = $bootstrap->getWorker(); if (empty($this->_registerFunction)) { throw new InvalidArgumentException(get_class($this) . ' must implement a registerFunction'); } // allow for a small memory gap: $memoryLimit = ($this->_memory + 128) * 1024 * 1024; ini_set('memory_limit', $memoryLimit); $this->_worker->addFunction($this->_registerFunction, array(&$this, 'work')); $this->_worker->setTimeout($this->_timeout); $this->init(); while ($this->_worker->work() || $this->_worker->returnCode() == GEARMAN_TIMEOUT) { if ($this->_worker->returnCode() == GEARMAN_TIMEOUT) { $this->timeout(); continue; } if ($this->_worker->returnCode() != GEARMAN_SUCCESS) { $this->setError($this->_worker->returnCode() . ': ' . $this->_worker->getErrno() . ': ' . $this->_worker->error()); break; } } $this->shutdown(); }
/** * Get GearmanWorker * * @return \GearmanWorker */ public function getGearmanWorker() { if (!$this->worker) { $this->worker = new \GearmanWorker(); } if ($this->timeout !== null) { $this->worker->setTimeout($this->timeout); } if ($this->functions !== null) { foreach ($this->functions as $f) { $this->register($f, array($this, 'proxify')); } } return $this->worker; }
/** * Constructor * Checks for the required gearman extension, * fetches the bootstrap and loads in the gearman worker * * @param Zend_Application_Bootstrap_BootstrapAbstract $bootstrap * @return Zend_Gearman_Worker */ public function __construct(Zend_Application_Bootstrap_BootstrapAbstract $bootstrap) { if (!extension_loaded('gearman')) { throw new RuntimeException('The PECL::gearman extension is required.'); } $this->_bootstrap = $bootstrap; $this->_worker = $this->_bootstrap->bootstrap('gearmanworker')->getResource('gearmanworker'); if (empty($this->_registerFunction)) { throw new InvalidArgumentException(get_class($this) . ' must implement a registerFunction'); } // allow for a small memory gap: $memoryLimit = ($this->_memory + 128) * 1024 * 1024; ini_set('memory_limit', $memoryLimit); $this->_worker->addFunction($this->_registerFunction, array(&$this, 'work')); $this->_worker->setTimeout($this->_timeout); $this->init(); $check = 10; $c = 0; while (@$this->_worker->work() || $this->_worker->returnCode() == GEARMAN_TIMEOUT) { $c++; if ($this->_worker->returnCode() == GEARMAN_TIMEOUT) { $this->timeout(); continue; } if ($this->_worker->returnCode() != GEARMAN_SUCCESS) { $this->setError($this->_worker->returnCode() . ': ' . $this->_worker->getErrno() . ': ' . $this->_worker->error()); break; } if ($c % $check === 0 && $this->isMemoryOverflow()) { break; // we've consumed our memory and the worker needs to be restarted } } $this->shutdown(); }
/** * Starts a worker for the PECL library * * @param array $worker_list List of worker functions to add * @param array $timeouts list of worker timeouts to pass to server * @return void * */ protected function start_lib_worker($worker_list, $timeouts = array()) { $thisWorker = new GearmanWorker(); $thisWorker->addOptions(GEARMAN_WORKER_NON_BLOCKING); $thisWorker->setTimeout(5000); foreach ($this->servers as $s) { $this->log("Adding server {$s}", GearmanManager::LOG_LEVEL_WORKER_INFO); // see: https://bugs.php.net/bug.php?id=63041 try { $thisWorker->addServers($s); } catch (\GearmanException $e) { if ($e->getMessage() !== 'Failed to set exception option') { throw $e; } } } foreach ($worker_list as $w) { $timeout = isset($timeouts[$w]) ? $timeouts[$w] : null; $this->log("Adding job {$w} ; timeout: " . $timeout, GearmanManager::LOG_LEVEL_WORKER_INFO); $thisWorker->addFunction($w, array($this, "do_job"), $this, $timeout); } $start = time(); while (!$this->stop_work) { if (@$thisWorker->work() || $thisWorker->returnCode() == GEARMAN_IO_WAIT || $thisWorker->returnCode() == GEARMAN_NO_JOBS) { if ($thisWorker->returnCode() == GEARMAN_SUCCESS) { continue; } if (!@$thisWorker->wait()) { if ($thisWorker->returnCode() == GEARMAN_NO_ACTIVE_FDS) { sleep(5); } } } /** * Check the running time of the current child. If it has * been too long, stop working. */ if ($this->max_run_time > 0 && time() - $start > $this->max_run_time) { $this->log("Been running too long, exiting", GearmanManager::LOG_LEVEL_WORKER_INFO); $this->stop_work = true; } if (!empty($this->config["max_runs_per_worker"]) && $this->job_execution_count >= $this->config["max_runs_per_worker"]) { $this->log("Ran {$this->job_execution_count} jobs which is over the maximum({$this->config['max_runs_per_worker']}), exiting", GearmanManager::LOG_LEVEL_WORKER_INFO); $this->stop_work = true; } } $thisWorker->unregisterAll(); }
/** * Starts a worker for the PECL library * * @param array $worker_list List of worker functions to add * @return void * */ protected function start_lib_worker($worker_list) { $thisWorker = new GearmanWorker(); $thisWorker->addOptions(GEARMAN_WORKER_NON_BLOCKING); $thisWorker->setTimeout(5000); foreach ($this->servers as $s) { $this->log("Adding server {$s}", GearmanManager::LOG_LEVEL_WORKER_INFO); $thisWorker->addServers($s); } foreach ($worker_list as $w) { $this->log("Adding job {$w}", GearmanManager::LOG_LEVEL_WORKER_INFO); $thisWorker->addFunction($w, array($this, "do_job"), $this); } $start = time(); while (!$this->stop_work) { if (@$thisWorker->work() || $thisWorker->returnCode() == GEARMAN_IO_WAIT || $thisWorker->returnCode() == GEARMAN_NO_JOBS) { if ($thisWorker->returnCode() == GEARMAN_SUCCESS) { continue; } if (!@$thisWorker->wait()) { if ($thisWorker->returnCode() == GEARMAN_NO_ACTIVE_FDS) { sleep(5); } } } /** * Check the running time of the current child. If it has * been too long, stop working. */ if ($this->max_run_time > 0 && time() - $start > $this->max_run_time) { $this->log("Been running too long, exiting", GearmanManager::LOG_LEVEL_WORKER_INFO); $this->stop_work = true; } if (!empty($this->config["max_runs_per_worker"]) && $this->job_execution_count >= $this->config["max_runs_per_worker"]) { $this->log("Ran {$this->job_execution_count} jobs which is over the maximum({$this->config['max_runs_per_worker']}), exiting", GearmanManager::LOG_LEVEL_WORKER_INFO); $this->stop_work = true; } } $thisWorker->unregisterAll(); }
/** * Given a GearmanWorker and an instance of Job, run it * * @param \GearmanWorker $gearmanWorker Gearman Worker * @param Object $objInstance Job instance * @param array $jobs Array of jobs to subscribe * @param integer $iterations Number of iterations * @param integer $timeout Timeout * * @return GearmanExecute self Object */ private function runJob(\GearmanWorker $gearmanWorker, $objInstance, array $jobs, $iterations, $timeout = null) { /** * Set the output of this instance, this should allow workers to use the console output. */ if ($objInstance instanceof GearmanOutputAwareInterface) { $objInstance->setOutput($this->output ?: new NullOutput()); } /** * Every job defined in worker is added into GearmanWorker */ foreach ($jobs as $job) { /** * worker needs to have it's context into separated memory space; * if it's passed as a value, then garbage collector remove the target * what causes a segfault */ $this->workersBucket[$job['realCallableName']] = array('job_object_instance' => $objInstance, 'job_method' => $job['methodName'], 'jobs' => $jobs); $gearmanWorker->addFunction($job['realCallableName'], array($this, 'handleJob')); } /** * If iterations value is 0, is like worker will never die */ $alive = 0 === $iterations; if ($timeout > 0) { $gearmanWorker->setTimeout($timeout * 1000); } /** * Executes GearmanWorker with all jobs defined */ while (false === $this->stopWorkSignalReceived && $gearmanWorker->work()) { $iterations--; $event = new GearmanWorkExecutedEvent($jobs, $iterations, $gearmanWorker->returnCode()); $this->eventDispatcher->dispatch(GearmanEvents::GEARMAN_WORK_EXECUTED, $event); if ($gearmanWorker->returnCode() != GEARMAN_SUCCESS) { break; } /** * Only finishes its execution if alive is false and iterations * arrives to 0 */ if (!$alive && $iterations <= 0) { break; } } }
// Non-blocking $worker->addOptions(GEARMAN_WORKER_NON_BLOCKING); // Add the localhost:4730 as server (default) $worker->addServer(); // Add the functions to the worker // Fetch all photo Ids of this twitpic user $worker->addFunction("fetchPhotoIds", "fetchPhotoIds"); // Fetch a photo from twitpic $worker->addFunction("fetchPhoto", "fetchPhoto"); // This worker will destroy itself in 5 seconds. $worker->setTimeout(5000); // Keep worker alive as long as there are jobs while (@$worker->work() || $worker->returnCode() == GEARMAN_IO_WAIT || $worker->returnCode() == GEARMAN_NO_JOBS){ if ($worker->returnCode() == GEARMAN_SUCCESS){ echo date('d-m-Y H:i:s') . "| Job Successful \n"; continue; } if (!@$worker->wait()) { if ($worker->returnCode() == GEARMAN_NO_ACTIVE_FDS) { // We are not connected to the Gearman Server // We shall not hammer the Gearman Server // We have patience, not much, but some.
} else { die("\nJSON config file is specified but cannot be found: {$jsonConfigFile}\n\n"); } } /* * Get the functions to register with Gearman */ $gasWorker = new $workerClass(); $arrWorkerFunctions = $gasWorker->getFunctions(); foreach ($arrWorkerFunctions as $functionName) { $worker->addFunction($functionName, array($gasWorker, $functionName)); } $maxJobs = $gasWorker->getMaxJobs(); $workerLifetimeMins = $gasWorker->getWorkerLifetimeMins(); //$worker->setId('worker_' . uniqid(true)); $worker->setTimeout($workerLifetimeMins * 60 * 1000); error_log(date('c') . " - Starting worker " . $workerClass); $load = 0; $i = 0; while ($i < $maxJobs && $load < 1.9 && ($foo = $worker->work())) { //TODO What happens when a worker doesn't process? if (!$foo) { error_log('$worker->work() returned false'); } $arrAverageLoad = sys_getloadavg(); $load = $arrAverageLoad[0]; if ($worker->returnCode() != GEARMAN_SUCCESS) { echo "return_code: " . $worker->returnCode() . "\n"; break; } $i++;