Example #1
0
/**
 * 代码级的模块调用
 *
 * @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;
}
Example #2
0
 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();
 }