Passed
Push — master ( cbb991...62e47c )
by Albert
07:16 queued 05:08
created

HttpServiceProvider::getNewMySqlConnection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SwooleTW\Http;
4
5
use Illuminate\Support\Arr;
6
use SwooleTW\Http\Helpers\FW;
7
use Illuminate\Queue\QueueManager;
8
use Illuminate\Contracts\Http\Kernel;
9
use Swoole\Http\Server as HttpServer;
10
use Illuminate\Support\ServiceProvider;
11
use SwooleTW\Http\Middleware\AccessLog;
12
use SwooleTW\Http\Server\Facades\Server;
13
use Illuminate\Database\DatabaseManager;
14
use SwooleTW\Http\Coroutine\MySqlConnection;
15
use SwooleTW\Http\Commands\HttpServerCommand;
16
use Swoole\Websocket\Server as WebsocketServer;
17
use SwooleTW\Http\Task\Connectors\SwooleTaskConnector;
18
use SwooleTW\Http\Coroutine\Connectors\ConnectorFactory;
19
20
/**
21
 * @codeCoverageIgnore
22
 */
23
abstract class HttpServiceProvider extends ServiceProvider
24
{
25
    /**
26
     * Indicates if loading of the provider is deferred.
27
     *
28
     * @var bool
29
     */
30
    protected $defer = false;
31
32
    /**
33
     * @var boolean
34
     */
35
    protected $isWebsocket = false;
36
37
    /**
38
     * @var \Swoole\Http\Server | \Swoole\Websocket\Server
39
     */
40
    protected static $server;
41
42
    /**
43
     * Register the service provider.
44
     *
45
     * @return void
46
     */
47
    public function register()
48
    {
49
        $this->mergeConfigs();
50
        $this->setIsWebsocket();
51
        $this->registerServer();
52
        $this->registerManager();
53
        $this->registerCommands();
54
        $this->registerDatabaseDriver();
55
        $this->registerSwooleQueueDriver();
56
    }
57
58
    /**
59
     * Register manager.
60
     *
61
     * @return void
62
     */
63
    abstract protected function registerManager();
64
65
    /**
66
     * Boot routes.
67
     *
68
     * @return void
69
     */
70
    abstract protected function bootRoutes();
71
72
    /**
73
     * Boot the service provider.
74
     *
75
     * @return void
76
     */
77
    public function boot()
78
    {
79
        $this->publishes([
80
            __DIR__ . '/../config/swoole_http.php' => base_path('config/swoole_http.php'),
81
            __DIR__ . '/../config/swoole_websocket.php' => base_path('config/swoole_websocket.php'),
82
            __DIR__ . '/../routes/websocket.php' => base_path('routes/websocket.php'),
83
        ], 'laravel-swoole');
84
85
        $config = $this->app->make('config');
86
87
        if ($config->get('swoole_http.websocket.enabled')) {
88
            $this->bootRoutes();
89
        }
90
91
        if ($config->get('swoole_http.server.access_log')) {
92
            $this->app->make(Kernel::class)->pushMiddleware(AccessLog::class);
0 ignored issues
show
Bug introduced by
The method pushMiddleware() does not exist on Illuminate\Contracts\Http\Kernel. ( Ignorable by Annotation )

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

92
            $this->app->make(Kernel::class)->/** @scrutinizer ignore-call */ pushMiddleware(AccessLog::class);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
93
        }
94
    }
95
96
    /**
97
     * Merge configurations.
98
     */
99
    protected function mergeConfigs()
100
    {
101
        $this->mergeConfigFrom(__DIR__ . '/../config/swoole_http.php', 'swoole_http');
102
        $this->mergeConfigFrom(__DIR__ . '/../config/swoole_websocket.php', 'swoole_websocket');
103
    }
104
105
    /**
106
     * Set isWebsocket.
107
     */
108
    protected function setIsWebsocket()
109
    {
110
        $this->isWebsocket = $this->app->make('config')
111
            ->get('swoole_http.websocket.enabled');
112
    }
113
114
    /**
115
     * Register commands.
116
     */
117
    protected function registerCommands()
118
    {
119
        $this->commands([
120
            HttpServerCommand::class,
121
        ]);
122
    }
123
124
    /**
125
     * Create swoole server.
126
     */
127
    protected function createSwooleServer()
128
    {
129
        $server = $this->isWebsocket ? WebsocketServer::class : HttpServer::class;
130
        $config = $this->app->make('config');
131
        $host = $config->get('swoole_http.server.host');
132
        $port = $config->get('swoole_http.server.port');
133
        $socketType = $config->get('swoole_http.server.socket_type', SWOOLE_SOCK_TCP);
134
        $processType = $config->get('swoole.http.server.process_type', SWOOLE_PROCESS);
135
136
        static::$server = new $server($host, $port, $processType, $socketType);
137
    }
138
139
    /**
140
     * Set swoole server configurations.
141
     */
142
    protected function configureSwooleServer()
143
    {
144
        $config = $this->app->make('config');
145
        $options = $config->get('swoole_http.server.options');
146
147
        // only enable task worker in websocket mode and for queue driver
148
        if ($config->get('queue.default') !== 'swoole' && ! $this->isWebsocket) {
149
            unset($config['task_worker_num']);
150
        }
151
152
        static::$server->set($options);
153
    }
154
155
    /**
156
     * Register manager.
157
     *
158
     * @return void
159
     */
160
    protected function registerServer()
161
    {
162
        $this->app->singleton(Server::class, function () {
163
            if (is_null(static::$server)) {
164
                $this->createSwooleServer();
165
                $this->configureSwooleServer();
166
            }
167
168
            return static::$server;
169
        });
170
        $this->app->alias(Server::class, 'swoole.server');
171
    }
172
173
    /**
174
     * Register database driver for coroutine mysql.
175
     */
176
    protected function registerDatabaseDriver()
177
    {
178
        $this->app->extend(DatabaseManager::class, function (DatabaseManager $db) {
179
            $db->extend('mysql-coroutine', function ($config, $name) {
180
                $config = $this->getMergedDatabaseConfig($config, $name);
181
182
                $connection = new MySqlConnection(
183
                    $this->getNewMySqlConnection($config),
184
                    Arr::get($config, 'database'),
185
                    Arr::get($config, 'prefix'),
186
                    $config
187
                );
188
189
                if (Arr::has($config, 'read')) {
190
                    $connection->setReadPdo($this->getNewMySqlConnection($config));
191
                }
192
193
                return $connection;
194
            });
195
196
            return $db;
197
        });
198
    }
199
200
    /**
201
     * Get mereged config for coroutine mysql.
202
     *
203
     * @param array $config
204
     * @param string $name
205
     *
206
     * @return array
207
     */
208
    protected function getMergedDatabaseConfig(array $config, string $name)
209
    {
210
        $newConfig = $config;
211
        $newConfig = Arr::add($newConfig, 'name', $name);
212
        $newConfig = array_merge($newConfig, Arr::get($newConfig, 'read', []));
213
        $newConfig = array_merge($newConfig, Arr::get($newConfig, 'write', []));
214
215
        return $newConfig;
216
    }
217
218
    /**
219
     * Get a new mysql connection.
220
     *
221
     * @param array $config
222
     *
223
     * @return \PDO
224
     */
225
    protected function getNewMySqlConnection(array $config)
226
    {
227
        return ConnectorFactory::make(FW::version())->connect($config);
228
    }
229
230
    /**
231
     * Register queue driver for swoole async task.
232
     */
233
    protected function registerSwooleQueueDriver()
234
    {
235
        $this->app->afterResolving('queue', function (QueueManager $manager) {
236
            $manager->addConnector('swoole', function () {
237
                return new SwooleTaskConnector($this->app->make(Server::class));
0 ignored issues
show
Bug introduced by
$this->app->make(SwooleT...\Facades\Server::class) of type SwooleTW\Http\Server\Facades\Server is incompatible with the type Swoole\Http\Server expected by parameter $swoole of SwooleTW\Http\Task\Conne...onnector::__construct(). ( Ignorable by Annotation )

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

237
                return new SwooleTaskConnector(/** @scrutinizer ignore-type */ $this->app->make(Server::class));
Loading history...
238
            });
239
        });
240
    }
241
}
242