Passed
Pull Request — master (#190)
by Dmitriy
02:42
created

Worker::process()   B

Complexity

Conditions 7
Paths 24

Size

Total Lines 43
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 12.0452

Importance

Changes 0
Metric Value
cc 7
eloc 31
nc 24
nop 2
dl 0
loc 43
ccs 17
cts 32
cp 0.5313
crap 12.0452
rs 8.4906
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Queue\Worker;
6
7
use Closure;
8
use Psr\Container\ContainerInterface;
9
use Psr\Log\LoggerInterface;
10
use RuntimeException;
11
use Throwable;
12
use Yiisoft\Injector\Injector;
13
use Yiisoft\Queue\Exception\JobFailureException;
14
use Yiisoft\Queue\Message\HandlerEnvelope;
15
use Yiisoft\Queue\Message\MessageHandlerInterface;
16
use Yiisoft\Queue\Message\MessageInterface;
17
use Yiisoft\Queue\Middleware\ConsumeFinalHandler;
18
use Yiisoft\Queue\Middleware\FailureFinalHandler;
19
use Yiisoft\Queue\Middleware\MiddlewareDispatcher;
20
use Yiisoft\Queue\Middleware\Request;
21
use Yiisoft\Queue\QueueInterface;
22
use Yiisoft\Queue\Message\IdEnvelope;
23
24
final class Worker implements WorkerInterface
25
{
26 19
    public function __construct(
27
        private LoggerInterface $logger,
28
        private Injector $injector,
29
        private ContainerInterface $container,
30
        private MiddlewareDispatcher $consumeMiddlewareDispatcher,
31
        private MiddlewareDispatcher $failureMiddlewareDispatcher,
32
    ) {
33 19
    }
34
35
    /**
36
     * @throws Throwable
37
     */
38 10
    public function process(MessageInterface $message, QueueInterface $queue): MessageInterface
39
    {
40 10
        $this->logger->info('Processing message #{message}.', ['message' => $message->getMetadata()[IdEnvelope::MESSAGE_ID_KEY] ?? 'null']);
41
42 10
        $handlerClass = $message instanceof HandlerEnvelope ? $message->getHandler() : null;
43
44 10
        if (!is_subclass_of($handlerClass, MessageHandlerInterface::class, true)) {
45
            throw new RuntimeException(sprintf(
46
                'Message handler "%s" for "%s" must implement "%s".',
47
                $handlerClass,
48
                $message::class,
49
                MessageHandlerInterface::class,
50
            ));
51
        }
52 10
        $handler = $this->container->get($handlerClass);
0 ignored issues
show
Bug introduced by
It seems like $handlerClass can also be of type null; however, parameter $id of Psr\Container\ContainerInterface::get() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

52
        $handler = $this->container->get(/** @scrutinizer ignore-type */ $handlerClass);
Loading history...
53 10
        if ($handler === null) {
54
            throw new RuntimeException(sprintf('Queue handler with name "%s" does not exist', $handlerClass));
55
        }
56
57 10
        if (!$handler instanceof MessageHandlerInterface) {
58
            throw new RuntimeException(sprintf(
59
                'Message handler "%s" for "%s" must implement "%s".',
60
                $handlerClass,
61
                $message::class,
62
                MessageHandlerInterface::class,
63
            ));
64
        }
65
66 10
        $request = new Request($message, $queue);
67 10
        $closure = fn (MessageInterface $message): mixed => $this->injector->invoke([$handler, 'handle'], [$message]);
68
        try {
69 10
            $result = $this->consumeMiddlewareDispatcher->dispatch($request, new ConsumeFinalHandler($closure));
70 9
            return $result->getMessage();
71 1
        } catch (Throwable $exception) {
72
            try {
73 1
                $result = $this->failureMiddlewareDispatcher->dispatch($request, new FailureFinalHandler($exception));
74
                $this->logger->info($exception);
75
76
                return $result->getMessage();
77 1
            } catch (Throwable $exception) {
78 1
                $exception = new JobFailureException($message, $exception);
79 1
                $this->logger->error($exception);
80 1
                throw $exception;
81
            }
82
        }
83
    }
84
}
85