| <?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); | 
| } |