Test Failed
Pull Request — master (#93)
by
unknown
22:27
created

RoadRunnerGrpcApplicationRunner::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 14
c 1
b 0
f 0
dl 0
loc 29
ccs 18
cts 18
cp 1
rs 9.7998
cc 1
nc 1
nop 13
crap 1

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Runner\RoadRunner;
6
7
use Psr\Container\ContainerExceptionInterface;
8
use Psr\Container\ContainerInterface;
9
use Psr\Container\NotFoundExceptionInterface;
10
use Spiral\RoadRunner\GRPC\Invoker;
11
use Spiral\RoadRunner\GRPC\InvokerInterface;
12
use Spiral\RoadRunner\GRPC\Server;
13
use Spiral\RoadRunner\GRPC\ServiceInterface;
14
use Spiral\RoadRunner\Worker;
15
use Yiisoft\Definitions\Exception\InvalidConfigException;
16
use Yiisoft\Di\NotFoundException;
17
use Yiisoft\Di\StateResetter;
18
use Yiisoft\ErrorHandler\ErrorHandler;
0 ignored issues
show
Bug introduced by
The type Yiisoft\ErrorHandler\ErrorHandler 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...
19
use Yiisoft\ErrorHandler\Exception\ErrorException;
20
use Yiisoft\ErrorHandler\Renderer\PlainTextRenderer;
21
use Yiisoft\Log\Logger;
22
use Yiisoft\Log\Target\File\FileTarget;
23
use Yiisoft\Yii\Runner\ApplicationRunner;
24
25
/**
26
 * `RoadRunnerGrpcApplicationRunner` runs the Yii gRPC application using RoadRunner.
27
 */
28
final class RoadRunnerGrpcApplicationRunner extends ApplicationRunner
29
{
30
    private ?ErrorHandler $temporaryErrorHandler = null;
31
    private ?InvokerInterface $invoker = null;
32
    private array $services = [];
33
    private ?Worker $worker = null;
34
35
    /**
36
     * @param string $rootPath The absolute path to the project root.
37
     * @param bool $debug Whether the debug mode is enabled.
38
     * @param bool $checkEvents Whether to check events' configuration.
39
     * @param string|null $environment The environment name.
40
     * @param string $bootstrapGroup The bootstrap configuration group name.
41
     * @param string $eventsGroup The events' configuration group name.
42
     * @param string $diGroup The container definitions' configuration group name.
43 2
     * @param string $diProvidersGroup The container providers' configuration group name.
44
     * @param string $diDelegatesGroup The container delegates' configuration group name.
45
     * @param string $diTagsGroup The container tags' configuration group name.
46
     * @param string $paramsGroup The configuration parameters group name.
47
     * @param array $nestedParamsGroups Configuration group names that are included into configuration parameters group.
48
     * This is needed for recursive merging of parameters.
49
     * @param array $nestedEventsGroups Configuration group names that are included into events' configuration group.
50
     * This is needed for reverse and recursive merge of events' configurations.
51
     *
52
     * @psalm-param list<string> $nestedParamsGroups
53
     * @psalm-param list<string> $nestedEventsGroups
54
     */
55
    public function __construct(
56
        string $rootPath,
57
        bool $debug = false,
58 2
        bool $checkEvents = false,
59 2
        ?string $environment = null,
60 2
        string $bootstrapGroup = 'bootstrap-grpc',
61 2
        string $eventsGroup = 'events-grpc',
62 2
        string $diGroup = 'di-grpc',
63 2
        string $diProvidersGroup = 'di-providers-grpc',
64 2
        string $diDelegatesGroup = 'di-delegates-grpc',
65 2
        string $diTagsGroup = 'di-tags-grpc',
66 2
        string $paramsGroup = 'params-grpc',
67 2
        array $nestedParamsGroups = ['params'],
68 2
        array $nestedEventsGroups = ['events'],
69 2
    ) {
70 2
        parent::__construct(
71 2
            $rootPath,
72 2
            $debug,
73
            $checkEvents,
74
            $environment,
75 1
            $bootstrapGroup,
76
            $eventsGroup,
77 1
            $diGroup,
78
            $diProvidersGroup,
79
            $diDelegatesGroup,
80
            $diTagsGroup,
81
            $paramsGroup,
82
            $nestedParamsGroups,
83 1
            $nestedEventsGroups,
84 1
        );
85
    }
86
87 1
    /**
88 1
     * @return void
89 1
     * @throws ContainerExceptionInterface
90
     * @throws ErrorException
91
     * @throws NotFoundExceptionInterface
92
     * @throws \ErrorException
93
     * @throws InvalidConfigException
94
     */
95
    public function run(): void
96
    {
97 1
        // Register temporary error handler to catch error while container is building.
98
        $temporaryErrorHandler = $this->createTemporaryErrorHandler();
99 1
        $this->registerErrorHandler($temporaryErrorHandler);
100 1
101
        $container = $this->getContainer();
102 1
103
        // Register error handler with real container-configured dependencies.
104
        /** @var ErrorHandler $actualErrorHandler */
105
        $actualErrorHandler = $container->get(ErrorHandler::class);
106
        $this->registerErrorHandler($actualErrorHandler, $temporaryErrorHandler);
107
108
        $this->runBootstrap();
109
        $this->checkEvents();
110
111
        $server = new Server($this->getInvoker(), ['debug' => $this->debug]);
112
113
        /**
114
         * @var class-string<ServiceInterface> $interface
115
         */
116
        foreach ($this->getServices() as $interface) {
117 2
            try {
118
                $server->registerService($interface, $container->get($interface));
119 2
            } catch (NotFoundException $exception) {
120
                $actualErrorHandler->handle($exception);
121 2
                throw  $exception;
122
            }
123
        }
124 2
125
        $server->serve($this->getWorker(), finalize: function () use ($container) {
126 2
            $this->afterRespond($container);
127
        });
128
    }
129 1
130
    /**
131 1
     * @return ErrorHandler
132
     */
133
    private function createTemporaryErrorHandler(): ErrorHandler {
134 1
        if ($this->temporaryErrorHandler !== null) {
135
            return $this->temporaryErrorHandler;
136 1
        }
137
138
        $logger = new Logger([new FileTarget("$this->rootPath/runtime/logs/grpc.log")]);
139
        return new ErrorHandler($logger, new PlainTextRenderer());
140
    }
141
142
    /**
143
     * @throws ErrorException
144
     */
145
    private function registerErrorHandler(ErrorHandler $registered, ErrorHandler $unregistered = null): void {
146
        $unregistered?->unregister();
147
148
        if ($this->debug) {
149
            $registered->debug();
150
        }
151
152
        $registered->register();
153
    }
154
155
    /**
156
     * @param ContainerInterface $container
157
     * @return void
158
     * @throws ContainerExceptionInterface
159
     * @throws NotFoundExceptionInterface
160
     */
161
    private function afterRespond(ContainerInterface $container): void {
162
        /** @psalm-suppress MixedMethodCall */
163
        $container->get(StateResetter::class)->reset();
164
        gc_collect_cycles();
165
    }
166
167
    /**
168
     * Returns a new instance with the specified gRPC worker instance
169
     *
170
     * @return $this
171
     */
172
    public function withWorker(Worker $worker): self
173
    {
174
        $instance = clone $this;
175
        $instance->worker = $worker;
176
177
        return $instance;
178
    }
179
180
    /**
181
     * Transmitted services for registration gRPC server
182
     *
183
     * @param array $services Services array (key-value pairs)
184
     * ```php
185
     * [
186
     *      ServiceInterface::class
187
     * ]
188
     * ```
189
     *
190
     * @return $this
191
     */
192
    public function setServices(array $services): self
193
    {
194
        $this->services = $services;
195
196
        return $this;
197
    }
198
199
    public function getServices(): array
200
    {
201
        return $this->services;
202
    }
203
204
    public function getWorker(): Worker
205
    {
206
        return $this->worker ?? Worker::create();
207
    }
208
209
    public function getInvoker(): InvokerInterface
210
    {
211
        return $this->invoker ?? new Invoker();
212
    }
213
}
214