Completed
Push — master ( 9f8be7...b45da4 )
by Vuong
02:22 queued 01:13
created

Async::getPool()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * @link https://github.com/vuongxuongminh/laravel-async
4
 *
5
 * @copyright (c) Vuong Xuong Minh
6
 * @license [MIT](https://opensource.org/licenses/MIT)
7
 */
8
9
namespace VXM\Async;
10
11
use Closure;
12
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
13
use Illuminate\Support\Str;
14
use Spatie\Async\Process\Runnable;
15
use VXM\Async\Runtime\ParentRuntime;
16
17
/**
18
 * @author Vuong Minh <[email protected]>
19
 * @since  1.0.0
20
 */
21
class Async
22
{
23
    /**
24
     * A pool manage async processes.
25
     *
26
     * @var Pool
27
     */
28
    protected $pool;
29
30
    /**
31
     * Event dispatcher manage async events.
32
     *
33
     * @var EventDispatcher
34
     */
35
    protected $events;
36
37
    /**
38
     * Create a new Async instance.
39
     *
40
     * @param  \VXM\Async\Pool  $pool
41
     * @param  \Illuminate\Contracts\Events\Dispatcher  $events
42
     */
43
    public function __construct(Pool $pool, EventDispatcher $events)
44
    {
45
        $this->pool = $pool;
46
        $this->events = $events;
47
    }
48
49
    /**
50
     * Execute async job.
51
     *
52
     * @param  callable|string|object  $job  need to execute.
53
     * @param  array  $events  event. Have key is an event name, value is a callable triggered when event
54
     *                                       happen, have three events `error`, `success`, `timeout`.
55
     * @param  int|null  $outputLength
56
     * @return static
57
     */
58
    public function run($job, array $events = [], int $outputLength = null): self
59
    {
60
        $process = $this->pool->add($this->makeJob($job), $outputLength);
61
62
        $this->addProcessListeners($events, $process);
63
64
        $process->then($this->makeProcessListener('success', $process));
65
        $process->catch($this->makeProcessListener('error', $process));
66
        $process->timeout($this->makeProcessListener('timeout', $process));
67
68
        return $this;
69
    }
70
71
    /**
72
     * Batch execute async jobs.
73
     *
74
     * @param  array  $jobs
75
     * @return static
76
     * @see run()
77
     * @since 2.0.0
78
     */
79
    public function batchRun(...$jobs): self
80
    {
81
        foreach ($jobs as $job) {
82
            $events = [];
83
            $outputLength = null;
84
85
            if (is_array($job)) {
86
                if (count($job) === 2) {
87
                    [$job, $events] = $job;
88
                } else {
89
                    [$job, $events, $outputLength] = $job;
90
                }
91
            }
92
93
            $this->run($job, $events, $outputLength);
94
        }
95
96
        return $this;
97
    }
98
99
    /**
100
     * Wait until all async jobs done and return job results.
101
     *
102
     * @return array
103
     */
104
    public function wait()
105
    {
106
        $results = $this->pool->wait();
107
        $this->pool->flush();
108
109
        return $results;
110
    }
111
112
    /**
113
     * Make async job.
114
     *
115
     * @param $job
116
     *
117
     * @return mixed
118
     */
119
    protected function makeJob($job)
120
    {
121
        if (is_string($job)) {
122
            return $this->createClassJob($job);
123
        }
124
125
        return $job;
126
    }
127
128
    /**
129
     * Create class and method job.
130
     *
131
     * @param  string  $job
132
     *
133
     * @return Closure
134
     */
135
    protected function createClassJob(string $job): Closure
136
    {
137
        [$class, $method] = Str::parseCallback($job, 'handle');
0 ignored issues
show
Bug introduced by
The variable $class does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $method does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
138
139
        return function () use ($class, $method) {
140
            return app()->call($class.'@'.$method);
141
        };
142
    }
143
144
    /**
145
     * Listen events of process given.
146
     *
147
     * @param  array  $events
148
     * @param  Runnable  $process
149
     */
150
    protected function addProcessListeners(array $events, Runnable $process): void
151
    {
152
        foreach ($events as $event => $callable) {
153
            $this->events->listen("async.{$event}_{$process->getId()}", $callable);
154
        }
155
    }
156
157
    /**
158
     * Make a base listener for integration with [[EventDispatcher]].
159
     *
160
     * @param  string  $event
161
     * @param  Runnable  $process
162
     *
163
     * @return callable
164
     */
165
    protected function makeProcessListener(string $event, Runnable $process): callable
166
    {
167
        return function (...$args) use ($event, $process) {
168
            $event = "async.{$event}_{$process->getId()}";
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $event, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
169
            $this->events->dispatch($event, $args);
170
            $this->events->forget($event);
171
        };
172
    }
173
174
    /**
175
     * Create a new process for run a job.
176
     *
177
     * @param  callable  $job  need to execute.
178
     *
179
     * @return Runnable process.
180
     * @deprecated since 2.1.0
181
     */
182
    protected function createProcess($job): Runnable
183
    {
184
        return ParentRuntime::createProcess($job);
185
    }
186
187
    /**
188
     * Get current pool.
189
     *
190
     * @return Pool
191
     * @since 2.1.0
192
     */
193
    public function getPool(): Pool
194
    {
195
        return $this->pool;
196
    }
197
}
198