/** * 代码级的模块调用 * * @param string $api * job名 类似 ToBusiness_Industry_load * @param string $args * 类似前端call的数据 * */ function module_invoke($api, array $args = array()) { static $functions; if (!isset($functions)) { $functions = GearmanKernel::getFunctions(); } $api = strtr($api, '_', '\\'); if (isset($functions[$api])) { $start = microtime(TRUE); $class = $functions[$api]['class']; $method = $functions[$api]['name']; $request = new Request($args); try { $result = $class::$method($request); if ($result instanceof Response) { $response = $result; } else { $response = new Response($result); } } catch (AccessException $e) { $response = new Response(NULL, array(), array(), $e->getCode(), $e->getMessage()); } catch (Exception $e) { $response = new Response(NULL, array(), array(), $e->getCode() ?: 409, $e->getMessage()); } $timer = round((microtime(TRUE) - $start) * 1000, 2); logger('daemon')->info('(InsideCall) ' . $api . ' takes ' . $timer . ' ms'); } else { $response = new Response(NULL, array(), array(), 404); } if (isset($args['request']['o']) and $keys = $args['request']['o']) { $data = $response->getData(); if (is_object($data)) { $data = object_intersect_key($data, $keys); } elseif (GearmanKernel::digitalArray($data)) { foreach ($data as $k => $v) { $data[$k] = object_intersect_key($v, $keys); } } $response->setData($data); } return $response; }
public function runWorker($pid = 0) { $worker = new Worker(); $worker->setTimeout(5000); if (!empty($this->servers) && is_array($this->servers)) { $worker->setServers($this->servers); } else { $worker->setServer(); } $functions = \GearmanKernel::getFunctions(null, $this->prefix); if (empty($functions)) { $this->output("Worker has no functions"); return false; } $worker->addFunctions($functions, array('GearmanKernel', 'responseGearman')); while (!$this->stop) { //@notice GearmanWork的work()默认是阻塞,所以上面设置了timeout if ($worker->work()) { switch ($worker->returnCode()) { case GEARMAN_SUCCESS: case GEARMAN_IO_WAIT: case GEARMAN_NO_JOBS: break; case GEARMAN_NO_ACTIVE_FDS: sleep(2); break; case GEARMAN_NOT_CONNECTED: case GEARMAN_COULD_NOT_CONNECT: case GEARMAN_LOST_CONNECTION: $this->output("Try to stop worker with pid {$pid} [not connected]"); $this->stop = true; break; default: $this->output("Try to stop worker with pid {$pid} [unknown gearman runcode]"); $this->stop = true; break; } } //超过最大运行时间则退出 if ($this->maxRuntime > 0 && time() > $this->stopTime) { $this->output("Try to stop worker with pid {$pid} [out of maxRuntime]"); $this->stop = true; } } $worker->unregisterAll(); }