<?php
|
/**
|
* 计划任务调度器
|
*
|
* - 异常失败,会轮循重试
|
* - 彩蛋式的抽象方法名
|
*
|
* @author dogstar <chanzonghuang@gmail.com> 20150516
|
*/
|
|
abstract class Task_Runner {
|
|
/**
|
* @var MQ队列实例
|
*/
|
protected $mq;
|
|
/**
|
* @var int $step 批次的数据,步长
|
*/
|
protected $step;
|
|
/**
|
* @param Task_MQ $mq MQ队列实例
|
* @param int $step 批次的数据,步长
|
*/
|
public function __construct(Task_MQ $mq, $step = 10) {
|
$this->mq = $mq;
|
|
$this->step = max(1, intval($step));
|
}
|
|
/**
|
* 执行任务
|
* @param string $service MQ中的接口服务名称,如:Default.Index
|
* @return array('total' => 总数量, 'fail' => 失败数量)
|
*/
|
public function go($service) {
|
$rs = array('total' => 0, 'fail' => 0);
|
|
$todoList = $this->mq->pop($service, $this->step);
|
$failList = array();
|
|
while (!empty($todoList)) {
|
$rs['total'] += count($todoList);
|
|
foreach ($todoList as $params) {
|
try {
|
$isFinish = $this->youGo($service, $params);
|
|
if (!$isFinish) {
|
$rs['fail'] ++;
|
}
|
} catch (PhalApi_Exception_InternalServerError $ex) {
|
$rs['fail'] ++;
|
|
$failList[] = $params;
|
|
DI()->logger->error('task occur exception to go',
|
array('service' => $service, 'params' => $params, 'error' => $ex->getMessage()));
|
}
|
}
|
|
$todoList = $this->mq->pop($service, $this->step);
|
}
|
|
foreach ($failList as $params) {
|
$this->mq->add($service, $params);
|
}
|
|
return $rs;
|
}
|
|
/**
|
* 具体的执行,这里使用了一个彩蛋的命名
|
* @param string $service MQ中的接口服务名称,如:Default.Index
|
* @param array $params 参数
|
* @return boolean 成功返回TRUE,失败返回FALSE
|
*/
|
abstract protected function youGo($service, $params);
|
}
|