1 | <?php |
||||
2 | |||||
0 ignored issues
–
show
Coding Style
introduced
by
![]() |
|||||
3 | namespace Hhxsv5\LaravelS\Swoole\Timer; |
||||
4 | |||||
5 | use Swoole\Timer; |
||||
6 | |||||
7 | abstract class CronJob implements CronJobInterface |
||||
0 ignored issues
–
show
|
|||||
8 | { |
||||
9 | /** |
||||
10 | * The seconds of global timer locking |
||||
11 | * @var int |
||||
0 ignored issues
–
show
|
|||||
12 | */ |
||||
13 | const GLOBAL_TIMER_LOCK_SECONDS = 60; |
||||
14 | |||||
15 | /** |
||||
16 | * Swoole timer id |
||||
17 | * @var int |
||||
0 ignored issues
–
show
|
|||||
18 | */ |
||||
19 | protected $timerId; |
||||
20 | |||||
21 | /** |
||||
22 | * The interval of Job in millisecond |
||||
23 | * @var int |
||||
0 ignored issues
–
show
|
|||||
24 | */ |
||||
25 | protected $interval; |
||||
26 | |||||
27 | /** |
||||
28 | * Whether run immediately after start |
||||
29 | * @var bool |
||||
0 ignored issues
–
show
|
|||||
30 | */ |
||||
31 | protected $isImmediate; |
||||
32 | |||||
33 | /** |
||||
34 | * The lock key of global timer |
||||
35 | * @var string |
||||
0 ignored issues
–
show
|
|||||
36 | */ |
||||
37 | protected static $globalTimerLockKey; |
||||
38 | |||||
39 | /** |
||||
40 | * Whether enable CronJob |
||||
41 | * @var bool |
||||
0 ignored issues
–
show
|
|||||
42 | */ |
||||
43 | protected static $enable = true; |
||||
44 | |||||
45 | /** |
||||
46 | * CronJob constructor. |
||||
47 | * Optional: |
||||
48 | * argument 0 is interval, int ms, default null, overridden by method interval() |
||||
49 | * argument 1 is isImmediate, bool, default false, overridden by method isImmediate() |
||||
50 | */ |
||||
51 | public function __construct() |
||||
52 | { |
||||
53 | $args = func_get_args(); |
||||
54 | $config = isset($args[0]) ? $args[0] : []; |
||||
55 | if (is_array($config)) { |
||||
56 | if (isset($config[0])) { |
||||
57 | $this->interval = $config[0]; |
||||
58 | } |
||||
59 | if (isset($config[1])) { |
||||
60 | $this->isImmediate = $config[1]; |
||||
61 | } |
||||
62 | } |
||||
63 | } |
||||
64 | |||||
65 | /** |
||||
0 ignored issues
–
show
|
|||||
66 | * @return int |
||||
67 | */ |
||||
68 | public function interval() |
||||
69 | { |
||||
70 | return $this->interval; |
||||
71 | } |
||||
72 | |||||
73 | /** |
||||
0 ignored issues
–
show
|
|||||
74 | * @return bool |
||||
75 | */ |
||||
76 | public function isImmediate() |
||||
77 | { |
||||
78 | return $this->isImmediate; |
||||
79 | } |
||||
80 | |||||
81 | public function setTimerId($timerId) |
||||
0 ignored issues
–
show
|
|||||
82 | { |
||||
83 | $this->timerId = $timerId; |
||||
84 | } |
||||
85 | |||||
86 | public function stop() |
||||
0 ignored issues
–
show
|
|||||
87 | { |
||||
88 | if ($this->timerId && Timer::exists($this->timerId)) { |
||||
89 | Timer::clear($this->timerId); |
||||
90 | } |
||||
91 | } |
||||
92 | |||||
93 | public static function getGlobalTimerCacheKey() |
||||
0 ignored issues
–
show
|
|||||
94 | { |
||||
95 | return 'laravels:timer:' . strtolower(self::$globalTimerLockKey); |
||||
96 | } |
||||
97 | |||||
98 | public static function getGlobalTimerLock() |
||||
0 ignored issues
–
show
|
|||||
99 | { |
||||
100 | /**@var \Illuminate\Redis\RedisManager $redis */ |
||||
0 ignored issues
–
show
|
|||||
101 | $redis = app('redis'); |
||||
0 ignored issues
–
show
The function
app was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
102 | |||||
103 | $key = self::getGlobalTimerCacheKey(); |
||||
104 | $value = self::getCurrentInstanceId(); |
||||
105 | $expire = self::GLOBAL_TIMER_LOCK_SECONDS; |
||||
106 | $result = $redis->set($key, $value, 'ex', $expire, 'nx'); |
||||
107 | // Compatible with Predis and PhpRedis |
||||
108 | return $result === true || ((string)$result === 'OK'); |
||||
109 | } |
||||
110 | |||||
111 | protected static function getCurrentInstanceId() |
||||
0 ignored issues
–
show
|
|||||
112 | { |
||||
113 | return sprintf('%s:%d', current(swoole_get_local_ip()) ?: gethostname(), config('laravels.listen_port')); |
||||
0 ignored issues
–
show
The function
config was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
114 | } |
||||
115 | |||||
116 | public static function isGlobalTimerAlive() |
||||
0 ignored issues
–
show
|
|||||
117 | { |
||||
118 | /**@var \Redis|\RedisCluster|\Predis\Client $redis */ |
||||
0 ignored issues
–
show
|
|||||
119 | $redis = app('redis')->client(); // Fix: Redis exists() always returns false on cluster mode for some older versions of Laravel/Lumen, see https://github.com/illuminate/redis/commit/62ff6a06a9c91902d3baa7feda20bab5e807606f |
||||
0 ignored issues
–
show
The function
app was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
120 | return (bool)$redis->exists(self::getGlobalTimerCacheKey()); |
||||
121 | } |
||||
122 | |||||
123 | public static function isCurrentTimerAlive() |
||||
0 ignored issues
–
show
|
|||||
124 | { |
||||
125 | /**@var \Illuminate\Redis\RedisManager $redis */ |
||||
0 ignored issues
–
show
|
|||||
126 | $redis = app('redis'); |
||||
0 ignored issues
–
show
The function
app was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
127 | $key = self::getGlobalTimerCacheKey(); |
||||
128 | $instanceId = $redis->get($key); |
||||
129 | return $instanceId === self::getCurrentInstanceId(); |
||||
130 | } |
||||
131 | |||||
132 | public static function renewGlobalTimerLock($expire) |
||||
0 ignored issues
–
show
|
|||||
133 | { |
||||
134 | /**@var \Illuminate\Redis\RedisManager $redis */ |
||||
0 ignored issues
–
show
|
|||||
135 | $redis = app('redis'); |
||||
0 ignored issues
–
show
The function
app was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
136 | return (bool)$redis->expire(self::getGlobalTimerCacheKey(), $expire); |
||||
137 | } |
||||
138 | |||||
139 | public static function setGlobalTimerLockKey($lockKey) |
||||
0 ignored issues
–
show
|
|||||
140 | { |
||||
141 | self::$globalTimerLockKey = $lockKey; |
||||
142 | } |
||||
143 | |||||
144 | public static function checkSetEnable() |
||||
0 ignored issues
–
show
|
|||||
145 | { |
||||
146 | if (self::isGlobalTimerAlive()) { |
||||
147 | // Reset current timer to avoid repeated execution |
||||
148 | self::setEnable(self::isCurrentTimerAlive()); |
||||
149 | } else { |
||||
150 | // Compete for timer lock |
||||
151 | self::setEnable(self::getGlobalTimerLock()); |
||||
152 | } |
||||
153 | } |
||||
154 | |||||
155 | public static function setEnable($enable) |
||||
0 ignored issues
–
show
|
|||||
156 | { |
||||
157 | self::$enable = (bool)$enable; |
||||
158 | } |
||||
159 | |||||
160 | public static function isEnable() |
||||
0 ignored issues
–
show
|
|||||
161 | { |
||||
162 | return self::$enable; |
||||
163 | } |
||||
164 | } |