Skip to content

Commit c42937d

Browse files
Better event handling (#18)
# About - Added new events for the pipeline lifecycle.
1 parent 42ad951 commit c42937d

File tree

6 files changed

+116
-27
lines changed

6 files changed

+116
-27
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ Usage of `withTransaction` method will enable a [`manual DB transaction`](https:
8888
Usage of `withEvents` method will enable [`Laravel Events`](https://laravel.com/docs/9.x/events#introduction) throughout the pipeline execution.
8989

9090
#### Available events
91+
- [`PipelineStarted`](https://github.com/michael-rubel/laravel-enhanced-pipeline/blob/main/src/Events/PipelineStarted.php) - fired when the pipeline starts working;
92+
- [`PipelineFinished`](https://github.com/michael-rubel/laravel-enhanced-pipeline/blob/main/src/Events/PipelineFinished.php) - fired when the pipeline finishes its work;
9193
- [`PipeExecutionStarted`](https://github.com/michael-rubel/laravel-enhanced-pipeline/blob/main/src/Events/PipeExecutionStarted.php) - fired **before** execution of the pipe;
9294
- [`PipeExecutionFinished`](https://github.com/michael-rubel/laravel-enhanced-pipeline/blob/main/src/Events/PipeExecutionFinished.php) - fired **after** execution of the pipe.
9395

src/Events/PipelineFinished.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MichaelRubel\EnhancedPipeline\Events;
6+
7+
use Closure;
8+
9+
class PipelineFinished
10+
{
11+
/**
12+
* @param mixed $passable
13+
* @param mixed $result
14+
*/
15+
public function __construct(
16+
public Closure $destination,
17+
public $passable,
18+
public array $pipes,
19+
public bool $useTransaction,
20+
public $result,
21+
) {
22+
//
23+
}
24+
}

src/Events/PipelineStarted.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MichaelRubel\EnhancedPipeline\Events;
6+
7+
use Closure;
8+
9+
class PipelineStarted
10+
{
11+
/**
12+
* @param mixed $passable
13+
*/
14+
public function __construct(
15+
public Closure $destination,
16+
public $passable,
17+
public array $pipes,
18+
public bool $useTransaction,
19+
) {
20+
//
21+
}
22+
}

src/Pipeline.php

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use Illuminate\Support\Traits\Conditionable;
1212
use MichaelRubel\EnhancedPipeline\Events\PipeExecutionFinished;
1313
use MichaelRubel\EnhancedPipeline\Events\PipeExecutionStarted;
14+
use MichaelRubel\EnhancedPipeline\Events\PipelineFinished;
15+
use MichaelRubel\EnhancedPipeline\Events\PipelineStarted;
1416
use MichaelRubel\EnhancedPipeline\Traits\HasDatabaseTransactions;
1517
use MichaelRubel\EnhancedPipeline\Traits\HasEvents;
1618
use RuntimeException;
@@ -137,6 +139,13 @@ public function via($method)
137139
public function then(Closure $destination)
138140
{
139141
try {
142+
$this->fireEvent(PipelineStarted::class,
143+
$destination,
144+
$this->passable,
145+
$this->pipes(),
146+
$this->useTransaction,
147+
);
148+
140149
$this->beginTransaction();
141150

142151
$pipeline = array_reduce(
@@ -145,7 +154,19 @@ public function then(Closure $destination)
145154
$this->prepareDestination($destination)
146155
);
147156

148-
return $pipeline($this->passable);
157+
$result = $pipeline($this->passable);
158+
159+
$this->commitTransaction();
160+
161+
$this->fireEvent(PipelineFinished::class,
162+
$destination,
163+
$this->passable,
164+
$this->pipes(),
165+
$this->useTransaction,
166+
$result,
167+
);
168+
169+
return $result;
149170
} catch (Throwable $e) {
150171
$this->rollbackTransaction();
151172

@@ -252,14 +273,7 @@ protected function parsePipeString($pipe)
252273
*/
253274
protected function pipes()
254275
{
255-
return [
256-
...$this->pipes,
257-
function ($passable, $next) {
258-
$this->commitTransaction();
259-
260-
return $next($passable);
261-
},
262-
];
276+
return $this->pipes;
263277
}
264278

265279
/**
@@ -293,7 +307,6 @@ public function setContainer(Container $container)
293307
/**
294308
* Set callback to be executed on failure pipeline.
295309
*
296-
*
297310
* @return $this
298311
*/
299312
public function onFailure(Closure $callback)

src/Traits/HasEvents.php

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,14 @@ public function withEvents(): static
2424
/**
2525
* Fire the event if enabled.
2626
*
27-
* @param string|callable|mixed $pipe
28-
* @param mixed $passable
27+
* @param mixed ...$params
2928
*/
30-
protected function fireEvent(string $event, $pipe, $passable): void
29+
protected function fireEvent(string $event, ...$params): void
3130
{
3231
if (! $this->useEvents) {
3332
return;
3433
}
3534

36-
if (is_object($pipe)) {
37-
/** @var object $pipe */
38-
$pipe = $pipe::class;
39-
}
40-
41-
event(new $event($pipe, $passable));
35+
event(new $event(...$params));
4236
}
4337
}

tests/PipelineEventsTest.php

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44

55
namespace MichaelRubel\EnhancedPipeline\Tests;
66

7+
use Closure;
78
use Illuminate\Support\Facades\Event;
89
use MichaelRubel\EnhancedPipeline\EnhancedPipelineServiceProvider;
910
use MichaelRubel\EnhancedPipeline\Events\PipeExecutionFinished;
1011
use MichaelRubel\EnhancedPipeline\Events\PipeExecutionStarted;
12+
use MichaelRubel\EnhancedPipeline\Events\PipelineFinished;
13+
use MichaelRubel\EnhancedPipeline\Events\PipelineStarted;
1114
use MichaelRubel\EnhancedPipeline\Pipeline;
1215

1316
class PipelineEventsTest extends TestCase
@@ -19,7 +22,6 @@ public function setUp(): void
1922
Event::fake();
2023
}
2124

22-
/** @test */
2325
public function testMakesSureEventServiceProviderBoots()
2426
{
2527
app()->offsetUnset('events');
@@ -29,8 +31,42 @@ public function testMakesSureEventServiceProviderBoots()
2931
$this->assertTrue(app()->bound('events'));
3032
}
3133

32-
/** @test */
33-
public function testFiresPipeStartedEvents()
34+
public function testFiresPipelineStartedEvent()
35+
{
36+
app(Pipeline::class)
37+
->withEvents()
38+
->send('data')
39+
->thenReturn();
40+
41+
Event::assertDispatched(function (PipelineStarted $event) {
42+
$this->assertInstanceOf(Closure::class, $event->destination);
43+
$this->assertSame('data', $event->passable);
44+
$this->assertSame([], $event->pipes);
45+
$this->assertFalse($event->useTransaction);
46+
47+
return true;
48+
});
49+
}
50+
51+
public function testFiresPipelineFinishedEvent()
52+
{
53+
app(Pipeline::class)
54+
->withEvents()
55+
->send('data')
56+
->thenReturn();
57+
58+
Event::assertDispatched(function (PipelineFinished $event) {
59+
$this->assertInstanceOf(Closure::class, $event->destination);
60+
$this->assertSame('data', $event->passable);
61+
$this->assertSame([], $event->pipes);
62+
$this->assertFalse($event->useTransaction);
63+
$this->assertSame('data', $event->result);
64+
65+
return true;
66+
});
67+
}
68+
69+
public function testFiresPipeExecutionStartedEvent()
3470
{
3571
app(Pipeline::class)
3672
->withEvents()
@@ -49,8 +85,7 @@ public function testFiresPipeStartedEvents()
4985
}, 2);
5086
}
5187

52-
/** @test */
53-
public function testFiresPipeStartedEventsButFailsToPass()
88+
public function testFiresPipeExecutionStartedEventButFailsToFinish()
5489
{
5590
app(Pipeline::class)
5691
->withEvents()
@@ -69,8 +104,7 @@ public function testFiresPipeStartedEventsButFailsToPass()
69104
Event::assertNotDispatched(PipeExecutionFinished::class);
70105
}
71106

72-
/** @test */
73-
public function testFiresPipePassedEvents()
107+
public function testFiresPipeExecutionFinishedEvent()
74108
{
75109
app(Pipeline::class)
76110
->withEvents()
@@ -82,7 +116,7 @@ public function testFiresPipePassedEvents()
82116
->thenReturn();
83117

84118
Event::assertDispatched(function (PipeExecutionFinished $event) {
85-
$this->assertInstanceOf(TestPipe::class, app($event->pipe));
119+
$this->assertInstanceOf(TestPipe::class, $event->pipe);
86120
$this->assertSame('data', $event->passable);
87121

88122
return true;

0 commit comments

Comments
 (0)