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

Worker   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 61
Duplicated Lines 0 %

Test Coverage

Coverage 58.06%

Importance

Changes 0
Metric Value
eloc 28
dl 0
loc 61
ccs 18
cts 31
cp 0.5806
rs 10
c 0
b 0
f 0
wmc 9

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A createFailureHandler() 0 3 1
B process() 0 35 6
A createConsumeHandler() 0 3 1
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\FailureHandling\FailureFinalHandler;
19
use Yiisoft\Queue\Middleware\FailureHandling\FailureHandlingRequest;
20
use Yiisoft\Queue\Middleware\FailureHandling\FailureMiddlewareDispatcher;
21
use Yiisoft\Queue\Middleware\MiddlewareDispatcher;
22
use Yiisoft\Queue\Middleware\Request;
23
use Yiisoft\Queue\QueueInterface;
24
use Yiisoft\Queue\Message\IdEnvelope;
25
26
final class Worker implements WorkerInterface
27
{
28 19
    public function __construct(
29
        private LoggerInterface $logger,
30
        private Injector $injector,
31
        private ContainerInterface $container,
32
        private MiddlewareDispatcher $consumeMiddlewareDispatcher,
33
        private FailureMiddlewareDispatcher $failureMiddlewareDispatcher,
34
    ) {
35 19
    }
36
37
    /**
38
     * @throws Throwable
39
     */
40 10
    public function process(MessageInterface $message, QueueInterface $queue): MessageInterface
41
    {
42 10
        $this->logger->info('Processing message #{message}.', ['message' => $message->getMetadata()[IdEnvelope::MESSAGE_ID_KEY] ?? 'null']);
43
44 10
        $handlerClass = $message instanceof HandlerEnvelope ? $message->getHandler() : null;
45
46 10
        if (!is_subclass_of($handlerClass, MessageHandlerInterface::class, true)) {
47
            throw new RuntimeException(sprintf(
48
                'Message handler "%s" for "%s" must implement "%s".',
49
                $handlerClass,
50
                $message::class,
51
                MessageHandlerInterface::class,
52
            ));
53
        }
54 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

54
        $handler = $this->container->get(/** @scrutinizer ignore-type */ $handlerClass);
Loading history...
55 10
        if ($handler === null) {
56
            throw new RuntimeException(sprintf('Queue handler with name "%s" does not exist', $handlerClass));
57
        }
58
59 10
        $request = new Request($message, $queue->getAdapter());
60 10
        $closure = fn (MessageInterface $message): mixed => $this->injector->invoke([$handler, 'handle'], [$message]);
61
        try {
62 10
            return $this->consumeMiddlewareDispatcher->dispatch($request, new ConsumeFinalHandler($closure))->getMessage();
63 1
        } catch (Throwable $exception) {
64 1
            $request = new FailureHandlingRequest($request->getMessage(), $exception, $queue);
65
66
            try {
67 1
                $result = $this->failureMiddlewareDispatcher->dispatch($request, new FailureFinalHandler());
68
                $this->logger->info($exception->getMessage());
69
70
                return $result->getMessage();
71 1
            } catch (Throwable $exception) {
72 1
                $exception = new JobFailureException($message, $exception);
73 1
                $this->logger->error($exception->getMessage());
74 1
                throw $exception;
75
            }
76
        }
77
    }
78
79
    private function createConsumeHandler(Closure $handler): MessageHandlerConsumeInterface
0 ignored issues
show
Bug introduced by
The type Yiisoft\Queue\Worker\Mes...HandlerConsumeInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Unused Code introduced by
The method createConsumeHandler() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
80
    {
81
        return new ConsumeFinalHandler($handler);
0 ignored issues
show
Bug Best Practice introduced by
The expression return new Yiisoft\Queue...eFinalHandler($handler) returns the type Yiisoft\Queue\Middleware\ConsumeFinalHandler which is incompatible with the type-hinted return Yiisoft\Queue\Worker\Mes...HandlerConsumeInterface.
Loading history...
82
    }
83
84
    private function createFailureHandler(): MessageFailureHandlerInterface
0 ignored issues
show
Unused Code introduced by
The method createFailureHandler() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
Bug introduced by
The type Yiisoft\Queue\Worker\Mes...FailureHandlerInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
85
    {
86
        return new FailureFinalHandler();
0 ignored issues
show
Bug Best Practice introduced by
The expression return new Yiisoft\Queue...g\FailureFinalHandler() returns the type Yiisoft\Queue\Middleware...ing\FailureFinalHandler which is incompatible with the type-hinted return Yiisoft\Queue\Worker\Mes...FailureHandlerInterface.
Loading history...
87
    }
88
}
89