Test Failed
Pull Request — master (#93)
by
unknown
33:08 queued 19s
created

RoadRunnerGrpcApplicationRunner::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

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