Passed
Push — develop ( 86d31c...191f96 )
by nguereza
03:18
created

Scheduler::get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
/**
4
 * Platine Framework
5
 *
6
 * Platine Framework is a lightweight, high-performance, simple and elegant
7
 * PHP Web framework
8
 *
9
 * This content is released under the MIT License (MIT)
10
 *
11
 * Copyright (c) 2020 Platine Framework
12
 *
13
 * Permission is hereby granted, free of charge, to any person obtaining a copy
14
 * of this software and associated documentation files (the "Software"), to deal
15
 * in the Software without restriction, including without limitation the rights
16
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
 * copies of the Software, and to permit persons to whom the Software is
18
 * furnished to do so, subject to the following conditions:
19
 *
20
 * The above copyright notice and this permission notice shall be included in all
21
 * copies or substantial portions of the Software.
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
 * SOFTWARE.
30
 */
31
32
/**
33
 *  @file Scheduler.php
34
 *
35
 *  The Scheduler Task class
36
 *
37
 *  @package    Platine\Framework\Task
38
 *  @author Platine Developers team
39
 *  @copyright  Copyright (c) 2020
40
 *  @license    http://opensource.org/licenses/MIT  MIT License
41
 *  @link   http://www.iacademy.cf
42
 *  @version 1.0.0
43
 *  @filesource
44
 */
45
46
declare(strict_types=1);
47
48
namespace Platine\Framework\Task;
49
50
use DateTime;
51
use Platine\Logger\LoggerInterface;
52
use RuntimeException;
53
use Throwable;
54
55
/**
56
 * @class Scheduler
57
 * @package Platine\Framework\Task
58
 */
59
class Scheduler implements SchedulerInterface
60
{
61
    /**
62
     * The logger instance
63
     * @var LoggerInterface
64
     */
65
    protected LoggerInterface $logger;
66
67
    /**
68
     * The task list
69
     * @var TaskInterface[]
70
     */
71
    protected array $tasks = [];
72
73
    /**
74
     * Create new instance
75
     * @param LoggerInterface $logger
76
     */
77
    public function __construct(
78
        LoggerInterface $logger
79
    ) {
80
        $this->logger = $logger;
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function run(): void
87
    {
88
        $datetime = new DateTime();
89
        $tasks = $this->tasks;
90
        foreach ($tasks as $task) {
91
            if ($this->isDue($task, $datetime)) {
92
                $this->execute($task);
93
            }
94
        }
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100
    public function add(TaskInterface $task): void
101
    {
102
        $key = $task->name();
103
        if (array_key_exists($key, $this->tasks)) {
104
            throw new RuntimeException(sprintf('Task [%s] already exist', $key));
105
        }
106
        $this->tasks[$key] = $task;
107
    }
108
109
110
    /**
111
     * {@inheritdoc}
112
     */
113
    public function get(string $key): ?TaskInterface
114
    {
115
        return $this->tasks[$key] ?? null;
116
    }
117
118
119
    /**
120
     * {@inheritdoc}
121
     */
122
    public function all(): array
123
    {
124
        return $this->tasks;
125
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130
    public function remove(string $key): void
131
    {
132
        unset($this->tasks[$key]);
133
    }
134
135
    /**
136
     * {@inheritdoc}
137
     */
138
    public function removeAll(): void
139
    {
140
        $this->tasks = [];
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146
    public function execute(TaskInterface $task): void
147
    {
148
        $this->logger->info('Execute task {task}', ['task' => $task->name()]);
149
        try {
150
            $task->run();
151
        } catch (Throwable $e) {
152
            $this->logger->error('Error occurred when execute task {task}, error: {error}', [
153
               'task' => $task->name(),
154
               'error' => $e->getMessage()
155
            ]);
156
        }
157
    }
158
159
    /**
160
     * Whether the given task is due
161
     * @param TaskInterface $task
162
     * @param DateTime $datetime
163
     * @return bool
164
     */
165
    protected function isDue(TaskInterface $task, DateTime $datetime): bool
166
    {
167
        $expression = $task->expression();
168
        $time = Cron::parse($expression);
169
        $cronDatetime = date('Y-m-d H:i', $time);
170
171
        return $datetime->format('Y-m-d H:i') === $cronDatetime;
172
    }
173
}
174