This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * @link https://github.com/vuongxuongminh/yii2-async |
||
4 | * @copyright Copyright (c) 2019 Vuong Xuong Minh |
||
5 | * @license [New BSD License](http://www.opensource.org/licenses/bsd-license.php) |
||
6 | */ |
||
7 | |||
8 | namespace vxm\async; |
||
9 | |||
10 | use Yii; |
||
11 | use Closure; |
||
12 | use Throwable; |
||
13 | |||
14 | use yii\base\Component; |
||
15 | |||
16 | use Spatie\Async\Process\Runnable; |
||
17 | |||
18 | use vxm\async\event\Event; |
||
19 | use vxm\async\event\ErrorEvent; |
||
20 | use vxm\async\event\SuccessEvent; |
||
21 | use vxm\async\runtime\ParentRuntime; |
||
22 | |||
23 | /** |
||
24 | * Support run code async. To use it, you just config it to your application components in configure file: |
||
25 | * |
||
26 | * ```php |
||
27 | * 'components' => [ |
||
28 | * 'async' => 'vxm\async\Async' |
||
29 | * ] |
||
30 | * |
||
31 | * ``` |
||
32 | * |
||
33 | * And after that you can run an async code: |
||
34 | * |
||
35 | * ```php |
||
36 | * |
||
37 | * Yii::$app->async->run(function () { |
||
38 | * |
||
39 | * sleep(5); |
||
40 | * }); |
||
41 | * |
||
42 | * ``` |
||
43 | * |
||
44 | * If you want to wait until task done, you just to call [[wait]]. |
||
45 | * |
||
46 | * ```php |
||
47 | * |
||
48 | * Yii::$app->async->run(function () { |
||
49 | * |
||
50 | * sleep(5); |
||
51 | * })->wait(); |
||
52 | * |
||
53 | * ``` |
||
54 | * |
||
55 | * Run multi tasks: |
||
56 | * |
||
57 | * ```php |
||
58 | * |
||
59 | * Yii::$app->async->run(function () { |
||
60 | * |
||
61 | * sleep(5); |
||
62 | * }); |
||
63 | * |
||
64 | * Yii::$app->async->run(function () { |
||
65 | * |
||
66 | * sleep(5); |
||
67 | * }); |
||
68 | * |
||
69 | * Yii::$app->async->wait(); |
||
70 | * ``` |
||
71 | * |
||
72 | * @property string $autoload path of autoload file for runtime task execute environment. |
||
73 | * @property int $sleepTimeWait time to sleep on wait tasks execute. |
||
74 | * @property int $concurrency tasks executable. |
||
75 | * @property int $timeout of task executable. |
||
76 | * |
||
77 | * @author Vuong Minh <[email protected]> |
||
78 | * @since 1.0.0 |
||
79 | */ |
||
80 | class Async extends Component |
||
81 | { |
||
82 | |||
83 | /** |
||
84 | * @event SuccessEvent an event that is triggered when task done. |
||
85 | */ |
||
86 | const EVENT_SUCCESS = 'success'; |
||
87 | |||
88 | /** |
||
89 | * @event ErrorEvent an event that is triggered when task error. |
||
90 | */ |
||
91 | const EVENT_ERROR = 'error'; |
||
92 | |||
93 | /** |
||
94 | * @event \yii\base\Event an event that is triggered when task timeout. |
||
95 | */ |
||
96 | const EVENT_TIMEOUT = 'timeout'; |
||
97 | |||
98 | /** |
||
99 | * @var Pool handling tasks. |
||
100 | */ |
||
101 | protected $pool; |
||
102 | |||
103 | /** |
||
104 | * @var string a file config of an application run in child process. |
||
105 | * Note: If an autoload file's set, it will not affect, you need to invoke an app in your autoload if needed. |
||
106 | */ |
||
107 | protected $appConfigFile; |
||
108 | |||
109 | /** |
||
110 | * Async constructor. |
||
111 | * |
||
112 | * @param array $config |
||
113 | * @throws \yii\base\InvalidConfigException |
||
114 | */ |
||
115 | 8 | public function __construct($config = []) |
|
116 | { |
||
117 | 8 | $pool = $this->pool = Yii::createObject(Pool::class); |
|
118 | 8 | $pool->autoload(__DIR__ . '/runtime/AutoloadRuntime.php'); |
|
119 | |||
120 | 8 | parent::__construct($config); |
|
121 | 8 | } |
|
122 | |||
123 | /** |
||
124 | * Execute async task. |
||
125 | * |
||
126 | * @param callable|\Spatie\Async\Task|Task $callable need to execute. |
||
127 | * @param array $callbacks event. Have key is an event name, value is a callable triggered when event happen, |
||
128 | * have three events `error`, `success`, `timeout`. |
||
129 | * @return static |
||
130 | */ |
||
131 | 8 | public function run($callable, array $callbacks = []): self |
|
132 | { |
||
133 | 8 | $process = $this->createProcess($callable); |
|
134 | 8 | $this->registerProcessEvents($callbacks, $process); |
|
135 | 8 | $this->registerProcessGlobalEvents($process); |
|
136 | 8 | $this->pool->add($process); |
|
0 ignored issues
–
show
|
|||
137 | |||
138 | 8 | return $this; |
|
139 | } |
||
140 | |||
141 | /** |
||
142 | * This method is called when task executed success. |
||
143 | * When overriding this method, make sure you call the parent implementation to ensure the |
||
144 | * event is triggered. |
||
145 | * |
||
146 | * @param mixed $output of task executed. |
||
147 | * @throws \yii\base\InvalidConfigException |
||
148 | */ |
||
149 | 3 | public function success($output): void |
|
150 | { |
||
151 | 3 | $event = Yii::createObject([ |
|
152 | 3 | 'class' => SuccessEvent::class, |
|
153 | 3 | 'output' => $output |
|
154 | ]); |
||
155 | |||
156 | 3 | $this->trigger(self::EVENT_SUCCESS, $event); |
|
157 | 3 | } |
|
158 | |||
159 | /** |
||
160 | * This method is called when task executed error. |
||
161 | * When overriding this method, make sure you call the parent implementation to ensure the |
||
162 | * event is triggered. |
||
163 | * |
||
164 | * @param Throwable $throwable when executing task. |
||
165 | * @throws \yii\base\InvalidConfigException |
||
166 | */ |
||
167 | 1 | public function error(Throwable $throwable): void |
|
168 | { |
||
169 | 1 | $event = Yii::createObject([ |
|
170 | 1 | 'class' => ErrorEvent::class, |
|
171 | 1 | 'throwable' => $throwable |
|
172 | ]); |
||
173 | |||
174 | 1 | $this->trigger(self::EVENT_ERROR, $event); |
|
175 | 1 | } |
|
176 | |||
177 | /** |
||
178 | * This method is called when task executed timeout. |
||
179 | * When overriding this method, make sure you call the parent implementation to ensure the |
||
180 | * event is triggered. |
||
181 | * |
||
182 | * @throws \yii\base\InvalidConfigException |
||
183 | */ |
||
184 | 2 | public function timeout(): void |
|
185 | { |
||
186 | 2 | $event = Yii::createObject(Event::class); |
|
187 | |||
188 | 2 | $this->trigger(self::EVENT_TIMEOUT, $event); |
|
189 | 2 | } |
|
190 | |||
191 | /** |
||
192 | * Register events to process given. |
||
193 | * |
||
194 | * @param array $events register to process given. |
||
195 | * @param Runnable $process need to add events. |
||
196 | * @since 1.0.3 |
||
197 | */ |
||
198 | 8 | protected function registerProcessEvents(array $events, Runnable $process): void |
|
199 | { |
||
200 | 8 | foreach ($events as $event => $callable) { |
|
201 | 4 | switch (strtolower($event)) { |
|
202 | 4 | case 'success': |
|
203 | 2 | $process->then(Closure::fromCallable($callable)); |
|
204 | 2 | break; |
|
205 | 2 | case 'error': |
|
206 | 1 | case 'catch': |
|
207 | 1 | $process->catch(Closure::fromCallable($callable)); |
|
208 | 1 | break; |
|
209 | 1 | case 'timeout': |
|
210 | 1 | $process->timeout(Closure::fromCallable($callable)); |
|
211 | 1 | break; |
|
212 | default: |
||
213 | 4 | break; |
|
214 | } |
||
215 | } |
||
216 | 8 | } |
|
217 | |||
218 | /** |
||
219 | * Register global events to process given. |
||
220 | * |
||
221 | * @param Runnable $process need to add global events. |
||
222 | */ |
||
223 | 8 | protected function registerProcessGlobalEvents(Runnable $process): void |
|
224 | { |
||
225 | 8 | $process->then(Closure::fromCallable([$this, 'success'])); |
|
226 | 8 | $process->catch(Closure::fromCallable([$this, 'error'])); |
|
227 | 8 | $process->timeout(Closure::fromCallable([$this, 'timeout'])); |
|
228 | 8 | } |
|
229 | |||
230 | /** |
||
231 | * Wait until all tasks done. |
||
232 | * |
||
233 | * @since 1.0.3 return results of async processes. |
||
234 | */ |
||
235 | 7 | public function wait() |
|
236 | { |
||
237 | 7 | $results = $this->pool->wait(); |
|
238 | 7 | $this->pool->flush(); |
|
239 | |||
240 | 7 | return $results; |
|
241 | } |
||
242 | |||
243 | /** |
||
244 | * Set concurrency process do tasks. |
||
245 | * |
||
246 | * @param int $concurrency |
||
247 | */ |
||
248 | public function setConcurrency(int $concurrency): void |
||
249 | { |
||
250 | $this->pool->concurrency($concurrency); |
||
251 | } |
||
252 | |||
253 | /** |
||
254 | * Set timeout of task when execute. |
||
255 | * |
||
256 | * @param int $timeout |
||
257 | */ |
||
258 | 8 | public function setTimeout(int $timeout): void |
|
259 | { |
||
260 | 8 | $this->pool->timeout($timeout); |
|
261 | 8 | } |
|
262 | |||
263 | /** |
||
264 | * Set sleep time when wait tasks execute. |
||
265 | * |
||
266 | * @param int $sleepTimeWait |
||
267 | */ |
||
268 | public function setSleepTimeWait(int $sleepTimeWait): void |
||
269 | { |
||
270 | $this->pool->sleepTime($sleepTimeWait); |
||
271 | } |
||
272 | |||
273 | /** |
||
274 | * Set autoload for environment tasks execute. |
||
275 | * @param string $autoload it can use at an alias. |
||
276 | */ |
||
277 | public function setAutoload(string $autoload): void |
||
278 | { |
||
279 | $this->pool->autoload(Yii::getAlias($autoload)); |
||
0 ignored issues
–
show
It seems like
\Yii::getAlias($autoload) targeting yii\BaseYii::getAlias() can also be of type boolean ; however, Spatie\Async\Pool::autoload() does only seem to accept string , maybe add an additional type check?
This check looks at variables that are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
280 | } |
||
281 | |||
282 | /** |
||
283 | * Set an application config file for invoke in child runtime process. |
||
284 | * |
||
285 | * @param string $appConfigFile it can use at an alias. |
||
286 | */ |
||
287 | 8 | public function setAppConfigFile(string $appConfigFile): void |
|
288 | { |
||
289 | 8 | $this->appConfigFile = Yii::getAlias($appConfigFile); |
|
0 ignored issues
–
show
It seems like
\Yii::getAlias($appConfigFile) can also be of type boolean . However, the property $appConfigFile is declared as type string . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||
290 | 8 | } |
|
291 | |||
292 | /** |
||
293 | * Create an async process. |
||
294 | * |
||
295 | * @param callable|\Spatie\Async\Task|Task $callable need to execute. |
||
296 | * @return Runnable process. |
||
297 | */ |
||
298 | 8 | protected function createProcess($callable): Runnable |
|
299 | { |
||
300 | 8 | return ParentRuntime::createProcess([$callable, $this->appConfigFile]); |
|
301 | } |
||
302 | |||
303 | } |
||
304 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: