Issues (33)

src/Watcher.php (4 issues)

1
<?php
2
declare(strict_types=1);
3
4
namespace Utilities\Router;
5
6
use Utilities\Common\Common;
7
use Utilities\Common\Connection;
8
use Utilities\Common\Loop;
9
10
/**
11
 * Watcher class
12
 *
13
 * @link    https://github.com/utilities-php/router
14
 * @author  Shahrad Elahi (https://github.com/shahradelahi)
15
 * @license https://github.com/utilities-php/router/blob/master/LICENSE (MIT License)
16
 */
17
class Watcher
18
{
19
20
    /**
21
     * Watchers.
22
     *
23
     * @var array
24
     */
25
    private static array $watchers = [];
26
27
    /**
28
     * Add a watcher.
29
     *
30
     * @param array $watchers [['key', 'class', 'interval'], ...]
31
     * @return void
32
     */
33
    public static function add(array $watchers): void
34
    {
35
        foreach ($watchers as $watcher) {
36
            if (!is_array($watcher) || !is_string($watcher['class']) || !is_numeric($watcher['interval'])) {
37
                throw new \RuntimeException(sprintf(
38
                    'The watcher `%s` is not valid.',
39
                    $watcher
40
                ));
41
            }
42
43
            if (!method_exists($watcher['class'], '__run')) {
44
                throw new \RuntimeException(sprintf(
45
                    'The watcher `%s` does not have a __run method.',
46
                    $watcher['class']
47
                ));
48
            }
49
50
            static::$watchers[] = $watcher;
0 ignored issues
show
Since $watchers is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $watchers to at least protected.
Loading history...
51
        }
52
    }
53
54
    /**
55
     * Create instance of the watcher.
56
     *
57
     * @param string $key The key of the watcher.
58
     * @param string $class Watcher class name.
59
     * @param int $interval Watcher interval. (e.g. 60 for 1 minute)
60
     * @return array ['key', 'class', 'interval']
61
     */
62
    public static function create(string $key, string $class, int $interval): array
63
    {
64
        return [
65
            'key' => $key,
66
            'class' => $class,
67
            'interval' => $interval
68
        ];
69
    }
70
71
    /**
72
     * Remove a watcher from the list.
73
     *
74
     * @param string $key
75
     * @return void
76
     */
77
    public static function remove(string $key): void
78
    {
79
        foreach (static::$watchers as $index => $watcher) {
80
            if ($watcher['key'] === $key) {
81
                unset(static::$watchers[$index]);
0 ignored issues
show
Since $watchers is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $watchers to at least protected.
Loading history...
82
            }
83
        }
84
    }
85
86
    /**
87
     * Run the watchers.
88
     *
89
     * @return void
90
     */
91
    public static function run(): void
92
    {
93
        header('Content-Type: application/json');
94
        Connection::closeConnection(Common::prettyJson([
95
            'ok' => true,
96
            'message' => 'Services are running...'
97
        ]));
98
99
        $last_runs = [];
100
        $startTime = time();
101
        Loop::run(function () use (&$last_runs, $startTime) {
102
            if (time() - $startTime > 60) {
103
                Loop::stop();
104
            }
105
106
            foreach (static::$watchers as $watcher) {
0 ignored issues
show
Since $watchers is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $watchers to at least protected.
Loading history...
107
                if (time() - $last_runs[$watcher['key']] >= $watcher['interval']) {
108
                    (new $watcher['class']())->__run();
109
                    $last_runs[$watcher['key']] = time();
110
                }
111
            }
112
        });
113
114
        die(200);
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
115
    }
116
117
}