Skip to content

Commit 3c8dd3d

Browse files
committed
- Implement event to fire when file changes
- Implement listener to capture aformentioned event and invoke pipeline - Implement 1 default pipeline step: restarting queue workers - Test case asserting pipeline is invoked - Test case asserting queue restart initiated
1 parent 15b01f5 commit 3c8dd3d

File tree

8 files changed

+153
-0
lines changed

8 files changed

+153
-0
lines changed

config/nativephp.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,8 @@
122122
'timeout' => 60,
123123
],
124124
],
125+
126+
'on_php_file_change' => [
127+
\Native\Laravel\Pipelines\ProjectFileChanged\RestartQueueWorkers::class,
128+
],
125129
];

src/Events/App/ProjectFileChanged.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Native\Laravel\Events\App;
4+
5+
use Illuminate\Broadcasting\Channel;
6+
use Illuminate\Broadcasting\InteractsWithSockets;
7+
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
8+
use Illuminate\Foundation\Events\Dispatchable;
9+
10+
class ProjectFileChanged implements ShouldBroadcastNow
11+
{
12+
use Dispatchable, InteractsWithSockets;
13+
14+
public function __construct(public readonly string $relativePath) {}
15+
16+
public function broadcastOn()
17+
{
18+
return [
19+
new Channel('nativephp'),
20+
];
21+
}
22+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Native\Laravel\Listeners;
4+
5+
use Illuminate\Support\Facades\Pipeline;
6+
use Native\Laravel\Events\App\ProjectFileChanged;
7+
use Webmozart\Assert\Assert;
8+
9+
class ProjectFileChangedListener
10+
{
11+
public function handle(ProjectFileChanged $event): void
12+
{
13+
foreach ($pipelines = config('nativephp.on_php_file_change') as $class) {
14+
Assert::classExists($class, "Class {$class} does not exist");
15+
}
16+
17+
Pipeline::send($event)->through($pipelines)->thenReturn();
18+
}
19+
}

src/NativeServiceProvider.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Native\Laravel;
44

55
use Illuminate\Console\Application;
6+
use Illuminate\Contracts\Events\Dispatcher;
67
use Illuminate\Foundation\Application as Foundation;
78
use Illuminate\Support\Arr;
89
use Illuminate\Support\Facades\Artisan;
@@ -20,9 +21,11 @@
2021
use Native\Laravel\Contracts\QueueWorker as QueueWorkerContract;
2122
use Native\Laravel\Contracts\WindowManager as WindowManagerContract;
2223
use Native\Laravel\DTOs\QueueConfig;
24+
use Native\Laravel\Events\App\ProjectFileChanged;
2325
use Native\Laravel\Events\EventWatcher;
2426
use Native\Laravel\Exceptions\Handler;
2527
use Native\Laravel\GlobalShortcut as GlobalShortcutImplementation;
28+
use Native\Laravel\Listeners\ProjectFileChangedListener;
2629
use Native\Laravel\Logging\LogWatcher;
2730
use Native\Laravel\PowerMonitor as PowerMonitorImplementation;
2831
use Native\Laravel\Windows\WindowManager as WindowManagerImplementation;
@@ -99,6 +102,8 @@ public function packageRegistered()
99102

100103
public function bootingPackage()
101104
{
105+
$this->app->make(Dispatcher::class)->listen(ProjectFileChanged::class, ProjectFileChangedListener::class);
106+
102107
if (config('nativephp-internal.running')) {
103108
$this->rewriteDatabase();
104109
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Native\Laravel\Pipelines\ProjectFileChanged;
4+
5+
use Closure;
6+
use Native\Laravel\Contracts\QueueWorker;
7+
use Native\Laravel\DTOs\QueueConfig;
8+
use Native\Laravel\Events\App\ProjectFileChanged;
9+
10+
class RestartQueueWorkers
11+
{
12+
public function __construct(
13+
private readonly QueueWorker $queueWorker,
14+
) {}
15+
16+
public function __invoke(ProjectFileChanged $event, Closure $next): ProjectFileChanged
17+
{
18+
$queueConfigs = QueueConfig::fromConfigArray(config('nativephp.queue_workers'));
19+
20+
foreach ($queueConfigs as $queueConfig) {
21+
$this->queueWorker->down($queueConfig->alias);
22+
}
23+
24+
return $next($event);
25+
}
26+
}

tests/Fixtures/Fakes/FakePipeline.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Native\Laravel\Tests\Fixtures\Fakes;
4+
5+
use Closure;
6+
7+
class FakePipeline
8+
{
9+
public bool $handled = false;
10+
11+
public mixed $carry;
12+
13+
public function handle(mixed $carry, Closure $next)
14+
{
15+
$this->handled = true;
16+
$this->carry = $carry;
17+
18+
return $next($carry);
19+
}
20+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
use Illuminate\Contracts\Events\Dispatcher;
4+
use Native\Laravel\Events\App\ProjectFileChanged;
5+
use Native\Laravel\Tests\Fixtures\Fakes\FakePipeline;
6+
use Webmozart\Assert\InvalidArgumentException as WebmozartInvalidArgumentException;
7+
8+
it('listens for the project file changed event and runs configured pipelines', function () {
9+
app()->singleton(FakePipeline::class, fn () => $fake = new FakePipeline);
10+
11+
config(['nativephp.on_php_file_change' => [
12+
FakePipeline::class,
13+
]]);
14+
15+
app(Dispatcher::class)->dispatch(new ProjectFileChanged('some/file.php'));
16+
17+
expect(app(FakePipeline::class)->handled)->toBeTrue();
18+
expect(app(FakePipeline::class)->carry)->toBeInstanceOf(ProjectFileChanged::class);
19+
});
20+
21+
it('rejects nonexistent classes', function () {
22+
config(['nativephp.on_php_file_change' => [
23+
'definitely-not-a-class-fqcn',
24+
]]);
25+
26+
try {
27+
app(Dispatcher::class)->dispatch(new ProjectFileChanged('some/file.php'));
28+
} catch (WebmozartInvalidArgumentException $e) {
29+
expect($e->getMessage())->toBe('Class definitely-not-a-class-fqcn does not exist');
30+
31+
return;
32+
}
33+
34+
$this->fail('Expected an exception to be thrown');
35+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
use Illuminate\Support\Facades\Pipeline;
4+
use Native\Laravel\Events\App\ProjectFileChanged;
5+
use Native\Laravel\Facades\QueueWorker;
6+
use Native\Laravel\Pipelines\ProjectFileChanged\RestartQueueWorkers;
7+
8+
it('restarts configured queue workers', function () {
9+
QueueWorker::fake();
10+
11+
config(['nativephp.queue_workers' => [
12+
'something' => [],
13+
'another' => [],
14+
]]);
15+
16+
Pipeline::send(new ProjectFileChanged('some/file.php'))
17+
->through([RestartQueueWorkers::class])
18+
->thenReturn();
19+
20+
QueueWorker::assertDown('something');
21+
QueueWorker::assertDown('another');
22+
});

0 commit comments

Comments
 (0)