colly_wyx
2018-04-18 2ee7d19834f3d566579df33e8b86c8ee1d350238
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?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);
}