Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 399 | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Queue\Console;
4
 
5
use Illuminate\Console\Command;
6
use Illuminate\Contracts\Cache\Repository as Cache;
7
use Illuminate\Contracts\Queue\Job;
8
use Illuminate\Queue\Events\JobFailed;
9
use Illuminate\Queue\Events\JobProcessed;
10
use Illuminate\Queue\Events\JobProcessing;
11
use Illuminate\Queue\Events\JobReleasedAfterException;
12
use Illuminate\Queue\Worker;
13
use Illuminate\Queue\WorkerOptions;
14
use Illuminate\Support\Carbon;
15
use Symfony\Component\Console\Attribute\AsCommand;
16
use Symfony\Component\Console\Terminal;
991 lars 17
 
148 lars 18
use function Termwind\terminal;
19
 
20
#[AsCommand(name: 'queue:work')]
21
class WorkCommand extends Command
22
{
23
    /**
24
     * The console command name.
25
     *
26
     * @var string
27
     */
28
    protected $signature = 'queue:work
29
                            {connection? : The name of the queue connection to work}
30
                            {--name=default : The name of the worker}
31
                            {--queue= : The names of the queues to work}
32
                            {--daemon : Run the worker in daemon mode (Deprecated)}
33
                            {--once : Only process the next job on the queue}
34
                            {--stop-when-empty : Stop when the queue is empty}
35
                            {--delay=0 : The number of seconds to delay failed jobs (Deprecated)}
36
                            {--backoff=0 : The number of seconds to wait before retrying a job that encountered an uncaught exception}
37
                            {--max-jobs=0 : The number of jobs to process before stopping}
38
                            {--max-time=0 : The maximum number of seconds the worker should run}
39
                            {--force : Force the worker to run even in maintenance mode}
40
                            {--memory=128 : The memory limit in megabytes}
41
                            {--sleep=3 : Number of seconds to sleep when no job is available}
42
                            {--rest=0 : Number of seconds to rest between jobs}
43
                            {--timeout=60 : The number of seconds a child process can run}
44
                            {--tries=1 : Number of times to attempt a job before logging it failed}';
45
 
46
    /**
47
     * The name of the console command.
48
     *
49
     * This name is used to identify the command during lazy loading.
50
     *
51
     * @var string|null
52
     *
53
     * @deprecated
54
     */
55
    protected static $defaultName = 'queue:work';
56
 
57
    /**
58
     * The console command description.
59
     *
60
     * @var string
61
     */
62
    protected $description = 'Start processing jobs on the queue as a daemon';
63
 
64
    /**
65
     * The queue worker instance.
66
     *
67
     * @var \Illuminate\Queue\Worker
68
     */
69
    protected $worker;
70
 
71
    /**
72
     * The cache store implementation.
73
     *
74
     * @var \Illuminate\Contracts\Cache\Repository
75
     */
76
    protected $cache;
77
 
78
    /**
79
     * Holds the start time of the last processed job, if any.
80
     *
81
     * @var float|null
82
     */
83
    protected $latestStartedAt;
84
 
85
    /**
86
     * Create a new queue work command.
87
     *
88
     * @param  \Illuminate\Queue\Worker  $worker
89
     * @param  \Illuminate\Contracts\Cache\Repository  $cache
90
     * @return void
91
     */
92
    public function __construct(Worker $worker, Cache $cache)
93
    {
94
        parent::__construct();
95
 
96
        $this->cache = $cache;
97
        $this->worker = $worker;
98
    }
99
 
100
    /**
101
     * Execute the console command.
102
     *
103
     * @return int|null
104
     */
105
    public function handle()
106
    {
107
        if ($this->downForMaintenance() && $this->option('once')) {
108
            return $this->worker->sleep($this->option('sleep'));
109
        }
110
 
111
        // We'll listen to the processed and failed events so we can write information
112
        // to the console as jobs are processed, which will let the developer watch
113
        // which jobs are coming through a queue and be informed on its progress.
114
        $this->listenForEvents();
115
 
116
        $connection = $this->argument('connection')
117
                        ?: $this->laravel['config']['queue.default'];
118
 
119
        // We need to get the right queue for the connection which is set in the queue
120
        // configuration file for the application. We will pull it based on the set
121
        // connection being run for the queue operation currently being executed.
122
        $queue = $this->getQueue($connection);
123
 
124
        if (Terminal::hasSttyAvailable()) {
125
            $this->components->info(
126
                sprintf('Processing jobs from the [%s] %s.', $queue, str('queue')->plural(explode(',', $queue)))
127
            );
128
        }
129
 
130
        return $this->runWorker(
131
            $connection, $queue
132
        );
133
    }
134
 
135
    /**
136
     * Run the worker instance.
137
     *
138
     * @param  string  $connection
139
     * @param  string  $queue
140
     * @return int|null
141
     */
142
    protected function runWorker($connection, $queue)
143
    {
144
        return $this->worker
145
            ->setName($this->option('name'))
146
            ->setCache($this->cache)
147
            ->{$this->option('once') ? 'runNextJob' : 'daemon'}(
148
                $connection, $queue, $this->gatherWorkerOptions()
149
            );
150
    }
151
 
152
    /**
153
     * Gather all of the queue worker options as a single object.
154
     *
155
     * @return \Illuminate\Queue\WorkerOptions
156
     */
157
    protected function gatherWorkerOptions()
158
    {
159
        return new WorkerOptions(
160
            $this->option('name'),
161
            max($this->option('backoff'), $this->option('delay')),
162
            $this->option('memory'),
163
            $this->option('timeout'),
164
            $this->option('sleep'),
165
            $this->option('tries'),
166
            $this->option('force'),
167
            $this->option('stop-when-empty'),
168
            $this->option('max-jobs'),
169
            $this->option('max-time'),
170
            $this->option('rest')
171
        );
172
    }
173
 
174
    /**
175
     * Listen for the queue events in order to update the console output.
176
     *
177
     * @return void
178
     */
179
    protected function listenForEvents()
180
    {
181
        $this->laravel['events']->listen(JobProcessing::class, function ($event) {
182
            $this->writeOutput($event->job, 'starting');
183
        });
184
 
185
        $this->laravel['events']->listen(JobProcessed::class, function ($event) {
186
            $this->writeOutput($event->job, 'success');
187
        });
188
 
189
        $this->laravel['events']->listen(JobReleasedAfterException::class, function ($event) {
190
            $this->writeOutput($event->job, 'released_after_exception');
191
        });
192
 
193
        $this->laravel['events']->listen(JobFailed::class, function ($event) {
194
            $this->writeOutput($event->job, 'failed');
195
 
196
            $this->logFailedJob($event);
197
        });
198
    }
199
 
200
    /**
201
     * Write the status output for the queue worker.
202
     *
203
     * @param  \Illuminate\Contracts\Queue\Job  $job
204
     * @param  string  $status
205
     * @return void
206
     */
207
    protected function writeOutput(Job $job, $status)
208
    {
209
        $this->output->write(sprintf(
210
            '  <fg=gray>%s</> %s%s',
399 lars 211
            $this->now()->format('Y-m-d H:i:s'),
148 lars 212
            $job->resolveName(),
213
            $this->output->isVerbose()
214
                ? sprintf(' <fg=gray>%s</>', $job->getJobId())
215
                : ''
216
        ));
217
 
218
        if ($status == 'starting') {
219
            $this->latestStartedAt = microtime(true);
220
 
221
            $dots = max(terminal()->width() - mb_strlen($job->resolveName()) - (
222
                $this->output->isVerbose() ? (mb_strlen($job->getJobId()) + 1) : 0
223
            ) - 33, 0);
224
 
225
            $this->output->write(' '.str_repeat('<fg=gray>.</>', $dots));
226
 
227
            return $this->output->writeln(' <fg=yellow;options=bold>RUNNING</>');
228
        }
229
 
230
        $runTime = number_format((microtime(true) - $this->latestStartedAt) * 1000, 2).'ms';
231
 
232
        $dots = max(terminal()->width() - mb_strlen($job->resolveName()) - (
233
            $this->output->isVerbose() ? (mb_strlen($job->getJobId()) + 1) : 0
234
        ) - mb_strlen($runTime) - 31, 0);
235
 
236
        $this->output->write(' '.str_repeat('<fg=gray>.</>', $dots));
237
        $this->output->write(" <fg=gray>$runTime</>");
238
 
239
        $this->output->writeln(match ($status) {
240
            'success' => ' <fg=green;options=bold>DONE</>',
241
            'released_after_exception' => ' <fg=yellow;options=bold>FAIL</>',
242
            default => ' <fg=red;options=bold>FAIL</>',
243
        });
244
    }
245
 
246
    /**
399 lars 247
     * Get the current date / time.
248
     *
249
     * @return \Illuminate\Support\Carbon
250
     */
251
    protected function now()
252
    {
253
        $queueTimezone = $this->laravel['config']->get('queue.output_timezone');
254
 
255
        if ($queueTimezone &&
256
            $queueTimezone !== $this->laravel['config']->get('app.timezone')) {
257
            return Carbon::now()->setTimezone($queueTimezone);
258
        }
259
 
260
        return Carbon::now();
261
    }
262
 
263
    /**
148 lars 264
     * Store a failed job event.
265
     *
266
     * @param  \Illuminate\Queue\Events\JobFailed  $event
267
     * @return void
268
     */
269
    protected function logFailedJob(JobFailed $event)
270
    {
271
        $this->laravel['queue.failer']->log(
272
            $event->connectionName,
273
            $event->job->getQueue(),
274
            $event->job->getRawBody(),
275
            $event->exception
276
        );
277
    }
278
 
279
    /**
280
     * Get the queue name for the worker.
281
     *
282
     * @param  string  $connection
283
     * @return string
284
     */
285
    protected function getQueue($connection)
286
    {
287
        return $this->option('queue') ?: $this->laravel['config']->get(
288
            "queue.connections.{$connection}.queue", 'default'
289
        );
290
    }
291
 
292
    /**
293
     * Determine if the worker should run in maintenance mode.
294
     *
295
     * @return bool
296
     */
297
    protected function downForMaintenance()
298
    {
299
        return $this->option('force') ? false : $this->laravel->isDownForMaintenance();
300
    }
301
}