Skip to content

Commit 144e632

Browse files
authored
[v5] Worker&config refactoring (#44)
1 parent cdef0a1 commit 144e632

25 files changed

+677
-241
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog][keepachangelog] and this project adheres to [Semantic Versioning][semver].
66

7+
## UNRELEASED (v5.x.x)
8+
9+
### Added
10+
11+
- Listener `RebindDatabaseSessionHandlerListener` for the database session driver container rebinding [[octane#300](https://github.com/laravel/octane/issues/300)]
12+
- Listener `WarmInstancesListener` for instances pre-resolving
13+
14+
### Changed
15+
16+
- Most important configuration values (such as event listeners) now defined in `Spiral\RoadRunnerLaravel\Defaults` class and used by the package configuration file (in the future, you will not need to update your config file manually when new "core" listeners will be added)
17+
- Dependency `laminas/laminas-diactoros` replaced with [`nyholm/psr7`](https://github.com/Nyholm/psr7) (lightweight PSR-7 implementation, strict and fast)
18+
- Config option `pre_resolving` replaced with `warm`
19+
- Config option `clear_instances` replaced with `clear`
20+
- Worker code refactored
21+
722
## v4.1.0
823

924
### Added

README.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@ $ php ./artisan vendor:publish --provider='Spiral\RoadRunnerLaravel\ServiceProvi
3333

3434
**Important**: despite the fact that worker allows you to refresh application instance on each HTTP request _(if worker started with option `--refresh-app`, eg.: `php ./vendor/bin/rr-worker start --refresh-app`)_, we strongly recommend avoiding this for performance reasons. Large applications can be hard to integrate with RoadRunner _(you must decide which of service providers must be reloaded on each request, avoid "static optimization" in some cases)_, but it's worth it.
3535

36-
### Upgrading guide (`v3.x` → `v4.x`)
36+
### Upgrading guide
37+
38+
#### **v4.x** → **v5.x**
39+
40+
- Update package configuration file (`roadrunner.php`; take a look for actual example in current repository)
41+
42+
#### **v3.x** → **v4.x**
3743

3844
- Update current package in your application:
3945
- `composer remove spiral/roadrunner-laravel`
@@ -42,8 +48,8 @@ $ php ./artisan vendor:publish --provider='Spiral\RoadRunnerLaravel\ServiceProvi
4248
- Optionally change relay to socket or TCP port:
4349
> ```yaml
4450
> server:
45-
> command: "php ./vendor/bin/rr-worker start --relay-dsn unix:///var/run/rr-rpc.sock"
46-
> relay: "unix:///var/run/rr-rpc.sock"
51+
> command: "php ./vendor/bin/rr-worker start --relay-dsn unix:///var/run/rr-relay.sock"
52+
> relay: "unix:///var/run/rr-relay.sock"
4753
> ```
4854
- Update RR binary file (using [`roadrunner-cli`][roadrunner-cli] or download from [binary releases][roadrunner-binary-releases] page) up to `v2.x`
4955
- Update RoadRunner starting (`rr serve ...`) flags - `-v` and `-d` must be not used anymore
@@ -69,12 +75,12 @@ Simple `.rr.yaml` config example ([full example can be found here][roadrunner_co
6975
7076
```yaml
7177
server:
72-
command: "php ./vendor/bin/rr-worker start --relay-dsn unix:///var/run/rr-rpc.sock"
73-
relay: "unix:///var/run/rr-rpc.sock"
78+
command: "php ./vendor/bin/rr-worker start --relay-dsn unix:///var/run/rr-relay.sock"
79+
relay: "unix:///var/run/rr-relay.sock"
7480
7581
http:
7682
address: 0.0.0.0:8080
77-
middleware: ["headers", "static", "gzip"]
83+
middleware: ["headers", "gzip"]
7884
pool:
7985
max_jobs: 64 # feel free to change this
8086
supervisor:

bin/rr-worker

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ foreach (['../../../..', '../../..', '../..', '..', '../vendor/laravel/laravel']
6666

6767
$app = new \Symfony\Component\Console\Application(
6868
'RoadRunner worker',
69-
\Composer\InstalledVersions::getPrettyVersion('spiral/roadrunner-laravel')
69+
\Composer\InstalledVersions::getPrettyVersion('spiral/roadrunner-laravel') ?? 'unknown'
7070
);
7171

7272
$app->add(new \Spiral\RoadRunnerLaravel\Console\Commands\StartCommand(

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"illuminate/translation": "~6.0 || ~7.0 || ~8.0",
3535
"illuminate/validation": "~6.0 || ~7.0 || ~8.0",
3636
"illuminate/view": "~6.0 || ~7.0 || ~8.0",
37-
"laminas/laminas-diactoros": "^2",
37+
"nyholm/psr7": "^1.2",
3838
"spiral/roadrunner-http": "^2.0",
3939
"spiral/roadrunner-worker": "^2.0",
4040
"symfony/console": "^4.3.4 || ^5.0",

config/roadrunner.php

Lines changed: 33 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
use Spiral\RoadRunnerLaravel\Events;
4+
use Spiral\RoadRunnerLaravel\Defaults;
45
use Spiral\RoadRunnerLaravel\Listeners;
56

67
return [
@@ -10,123 +11,80 @@
1011
|--------------------------------------------------------------------------
1112
|
1213
| Set this value to `true` if your application uses HTTPS (required for
13-
| example for correct links generation).
14+
| correct links generation, for example).
1415
|
1516
*/
1617

1718
'force_https' => (bool) env('APP_FORCE_HTTPS', false),
1819

19-
/*
20-
|--------------------------------------------------------------------------
21-
| Containers Pre Resolving
22-
|--------------------------------------------------------------------------
23-
|
24-
| Declared here abstractions will be resolved before events loop will be
25-
| started.
26-
|
27-
*/
28-
29-
'pre_resolving' => [
30-
'auth',
31-
'cache',
32-
'cache.store',
33-
'config',
34-
'cookie',
35-
'db',
36-
'db.factory',
37-
'encrypter',
38-
'files',
39-
'hash',
40-
'log',
41-
'router',
42-
'routes',
43-
'session',
44-
'session.store',
45-
'translator',
46-
'url',
47-
'view',
48-
],
49-
5020
/*
5121
|--------------------------------------------------------------------------
5222
| Event Listeners
5323
|--------------------------------------------------------------------------
5424
|
5525
| Worker provided by this package allows to interacts with request
56-
| processing loop using application events. Feel free to add your own event
57-
| listeners.
26+
| processing loop using application events.
27+
|
28+
| Feel free to add your own event listeners.
5829
|
5930
*/
6031

6132
'listeners' => [
6233
Events\BeforeLoopStartedEvent::class => [
63-
Listeners\FixSymfonyFileValidationListener::class,
34+
...Defaults::beforeLoopStarted(),
6435
],
6536

6637
Events\BeforeLoopIterationEvent::class => [
67-
Listeners\EnableHttpMethodParameterOverrideListener::class,
68-
Listeners\RebindHttpKernelListener::class, // Laravel 7 issue: <https://git.io/JvPpf>
69-
Listeners\RebindViewListener::class,
70-
Listeners\RebindAuthorizationGateListener::class,
71-
Listeners\RebindBroadcastManagerListener::class,
72-
Listeners\RebindDatabaseManagerListener::class,
73-
Listeners\RebindMailManagerListener::class,
74-
Listeners\RebindNotificationChannelManagerListener::class,
75-
Listeners\RebindPipelineHubListener::class,
76-
Listeners\RebindQueueManagerListener::class,
77-
Listeners\RebindValidationFactoryListener::class,
78-
Listeners\CloneConfigListener::class,
79-
Listeners\UnqueueCookiesListener::class,
80-
Listeners\FlushAuthenticationStateListener::class,
81-
Listeners\ResetSessionListener::class,
82-
Listeners\ResetProvidersListener::class,
83-
Listeners\ResetLocaleStateListener::class,
84-
85-
// Listeners\ResetLaravelScoutListener::class, // for 'laravel/scout' package
86-
// Listeners\ResetLaravelSocialiteListener::class, // for 'laravel/socialite' package
87-
// Listeners\ResetInertiaListener::class, // for 'inertiajs/inertia-laravel' package
38+
...Defaults::beforeLoopIteration(),
39+
// Listeners\ResetLaravelScoutListener::class, // for <https://github.com/laravel/scout>
40+
// Listeners\ResetLaravelSocialiteListener::class, // for <https://github.com/laravel/socialite>
41+
// Listeners\ResetInertiaListener::class, // for <https://github.com/inertiajs/inertia-laravel>
8842
],
8943

9044
Events\BeforeRequestHandlingEvent::class => [
91-
Listeners\RebindRouterListener::class,
45+
...Defaults::beforeRequestHandling(),
9246
Listeners\InjectStatsIntoRequestListener::class,
93-
Listeners\BindRequestListener::class,
94-
Listeners\ForceHttpsListener::class,
95-
Listeners\SetServerPortListener::class,
9647
],
9748

9849
Events\AfterRequestHandlingEvent::class => [
99-
//
50+
...Defaults::afterRequestHandling(),
10051
],
10152

10253
Events\AfterLoopIterationEvent::class => [
103-
Listeners\FlushArrayCacheListener::class,
104-
Listeners\ResetDatabaseRecordModificationStateListener::class,
105-
Listeners\ClearInstancesListener::class,
106-
Listeners\RunGarbageCollectorListener::class,
54+
...Defaults::afterLoopIteration(),
55+
Listeners\RunGarbageCollectorListener::class, // keep the memory usage low
10756
],
10857

10958
Events\AfterLoopStoppedEvent::class => [
110-
//
59+
...Defaults::afterLoopStopped(),
11160
],
11261

11362
Events\LoopErrorOccurredEvent::class => [
63+
...Defaults::loopErrorOccurred(),
11464
Listeners\SendExceptionToStderrListener::class,
11565
Listeners\StopWorkerListener::class,
11666
],
11767
],
11868

11969
/*
12070
|--------------------------------------------------------------------------
121-
| Instances Clearing
71+
| Containers Pre Resolving / Clearing
12272
|--------------------------------------------------------------------------
12373
|
124-
| Instances described here will be cleared on every request (if
125-
| `ClearInstancesListener` is enabled).
74+
| The bindings listed below will be resolved before the events loop
75+
| starting. Clearing a binding will force the container to resolve that
76+
| binding again when asked.
77+
|
78+
| Feel free to add your own bindings here.
12679
|
12780
*/
12881

129-
'clear_instances' => [
82+
'warm' => [
83+
...Defaults::servicesToWarm(),
84+
],
85+
86+
'clear' => [
87+
...Defaults::servicesToClear(),
13088
'auth', // is not required for Laravel >= v8.35
13189
],
13290

@@ -135,14 +93,15 @@
13593
| Reset Providers
13694
|--------------------------------------------------------------------------
13795
|
138-
| Providers that will be registered on every request (if
139-
| `ResetProvidersListener` is enabled).
96+
| Providers that will be registered on every request.
97+
|
98+
| Feel free to add your service-providers here.
14099
|
141100
*/
142101

143102
'reset_providers' => [
144-
Illuminate\Auth\AuthServiceProvider::class, // is not required for Laravel >= v8.35
145-
// App\Your\Custom\AuthServiceProvider::class,
103+
...Defaults::providersToReset(),
104+
Illuminate\Auth\AuthServiceProvider::class, // is not required for Laravel >= v8.35
146105
Illuminate\Pagination\PaginationServiceProvider::class, // is not required for Laravel >= v8.35
147106
],
148107
];

phpstan.neon.dist

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ parameters:
77
- helpers
88
- src
99
reportUnmatchedIgnoredErrors: true
10+
ignoreErrors:
11+
- message: '#Call to protected method bootstrappers\(\) of class.+Kernel#'
12+
paths: [src/Application/Factory.php]

src/Application/Factory.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Spiral\RoadRunnerLaravel\Application;
6+
7+
use Illuminate\Foundation\Http\Kernel as HttpKernel;
8+
use Illuminate\Foundation\Bootstrap\RegisterProviders;
9+
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
10+
use Illuminate\Foundation\Bootstrap\SetRequestForConsole;
11+
use Illuminate\Contracts\Http\Kernel as HttpKernelContract;
12+
use Illuminate\Contracts\Container\BindingResolutionException;
13+
use Illuminate\Contracts\Foundation\Application as ApplicationContract;
14+
15+
/**
16+
* @internal
17+
*/
18+
final class Factory implements FactoryInterface
19+
{
20+
/**
21+
* @param string $base_path
22+
* @param bool $boostrap_app
23+
*
24+
* @return ApplicationContract
25+
* @throws BindingResolutionException
26+
*/
27+
public function create(string $base_path, bool $boostrap_app = true): ApplicationContract
28+
{
29+
$path = \implode(\DIRECTORY_SEPARATOR, [\rtrim($base_path, \DIRECTORY_SEPARATOR), 'bootstrap', 'app.php']);
30+
31+
if (!\is_file($path)) {
32+
throw new \InvalidArgumentException("Application bootstrap file was not found in [{$path}]");
33+
}
34+
35+
/** @var ApplicationContract $app */
36+
$app = require $path;
37+
38+
if ($boostrap_app) {
39+
$this->bootstrap($app);
40+
}
41+
42+
return $app;
43+
}
44+
45+
/**
46+
* @param ApplicationContract $app
47+
*
48+
* @throws BindingResolutionException
49+
*/
50+
protected function bootstrap(ApplicationContract $app): void
51+
{
52+
/** @var HttpKernel $http_kernel */
53+
$http_kernel = $app->make(HttpKernelContract::class);
54+
55+
$bootstrappers = $this->getKernelBootstrappers($http_kernel);
56+
57+
// insert `SetRequestForConsole` bootstrapper before `RegisterProviders` if it does not exists
58+
if (!\in_array(SetRequestForConsole::class, $bootstrappers, true)) {
59+
$register_index = \array_search(RegisterProviders::class, $bootstrappers, true);
60+
61+
if (\is_int($register_index)) {
62+
\array_splice($bootstrappers, $register_index, 0, [SetRequestForConsole::class]);
63+
}
64+
}
65+
66+
$app->bootstrapWith($bootstrappers);
67+
}
68+
69+
/**
70+
* Get HTTP or Console kernel bootstrappers.
71+
*
72+
* @param HttpKernel|ConsoleKernel $kernel
73+
*
74+
* @return array<class-string> Bootstrappers class names
75+
*/
76+
protected function getKernelBootstrappers($kernel): array
77+
{
78+
$bootstrappers = [];
79+
80+
\Closure::fromCallable(function () use (&$bootstrappers): void {
81+
/**
82+
* @see HttpKernel::bootstrappers()
83+
* @see ConsoleKernel::bootstrappers()
84+
*
85+
* @var HttpKernel|ConsoleKernel $this
86+
*/
87+
\array_push($bootstrappers, ...$this->bootstrappers());
88+
})->bindTo($kernel, $kernel)();
89+
90+
return $bootstrappers;
91+
}
92+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Spiral\RoadRunnerLaravel\Application;
4+
5+
use Illuminate\Contracts\Foundation\Application as ApplicationContract;
6+
7+
interface FactoryInterface
8+
{
9+
/**
10+
* Create a new application instance.
11+
*
12+
* @param string $base_path
13+
*
14+
* @return ApplicationContract
15+
*/
16+
public function create(string $base_path): ApplicationContract;
17+
}

src/Console/Commands/StartCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ protected function configure(): void
7070
InputOption::VALUE_REQUIRED,
7171
'Relay DSN (eg.: <comment>' . \implode(
7272
'</comment>, <comment>',
73-
['pipes', 'tcp://localhost:6001', 'unix:///tmp/rpc.sock']
73+
['pipes', 'tcp://localhost:6001', 'unix:///tmp/relay.sock']
7474
) . '</comment>)',
7575
'pipes'
7676
);

0 commit comments

Comments
 (0)