Skip to content

Commit

Permalink
Better event handling (#18)
Browse files Browse the repository at this point in the history
# About
- Added new events for the pipeline lifecycle.
  • Loading branch information
michael-rubel authored Mar 17, 2024
1 parent 42ad951 commit c42937d
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 27 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ Usage of `withTransaction` method will enable a [`manual DB transaction`](https:
Usage of `withEvents` method will enable [`Laravel Events`](https://laravel.com/docs/9.x/events#introduction) throughout the pipeline execution.

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

Expand Down
24 changes: 24 additions & 0 deletions src/Events/PipelineFinished.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace MichaelRubel\EnhancedPipeline\Events;

use Closure;

class PipelineFinished
{
/**
* @param mixed $passable
* @param mixed $result
*/
public function __construct(
public Closure $destination,
public $passable,
public array $pipes,
public bool $useTransaction,
public $result,
) {
//
}
}
22 changes: 22 additions & 0 deletions src/Events/PipelineStarted.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace MichaelRubel\EnhancedPipeline\Events;

use Closure;

class PipelineStarted
{
/**
* @param mixed $passable
*/
public function __construct(
public Closure $destination,
public $passable,
public array $pipes,
public bool $useTransaction,
) {
//
}
}
33 changes: 23 additions & 10 deletions src/Pipeline.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use Illuminate\Support\Traits\Conditionable;
use MichaelRubel\EnhancedPipeline\Events\PipeExecutionFinished;
use MichaelRubel\EnhancedPipeline\Events\PipeExecutionStarted;
use MichaelRubel\EnhancedPipeline\Events\PipelineFinished;
use MichaelRubel\EnhancedPipeline\Events\PipelineStarted;
use MichaelRubel\EnhancedPipeline\Traits\HasDatabaseTransactions;
use MichaelRubel\EnhancedPipeline\Traits\HasEvents;
use RuntimeException;
Expand Down Expand Up @@ -137,6 +139,13 @@ public function via($method)
public function then(Closure $destination)
{
try {
$this->fireEvent(PipelineStarted::class,
$destination,
$this->passable,
$this->pipes(),
$this->useTransaction,
);

$this->beginTransaction();

$pipeline = array_reduce(
Expand All @@ -145,7 +154,19 @@ public function then(Closure $destination)
$this->prepareDestination($destination)
);

return $pipeline($this->passable);
$result = $pipeline($this->passable);

$this->commitTransaction();

$this->fireEvent(PipelineFinished::class,
$destination,
$this->passable,
$this->pipes(),
$this->useTransaction,
$result,
);

return $result;
} catch (Throwable $e) {
$this->rollbackTransaction();

Expand Down Expand Up @@ -252,14 +273,7 @@ protected function parsePipeString($pipe)
*/
protected function pipes()
{
return [
...$this->pipes,
function ($passable, $next) {
$this->commitTransaction();

return $next($passable);
},
];
return $this->pipes;
}

/**
Expand Down Expand Up @@ -293,7 +307,6 @@ public function setContainer(Container $container)
/**
* Set callback to be executed on failure pipeline.
*
*
* @return $this
*/
public function onFailure(Closure $callback)
Expand Down
12 changes: 3 additions & 9 deletions src/Traits/HasEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,14 @@ public function withEvents(): static
/**
* Fire the event if enabled.
*
* @param string|callable|mixed $pipe
* @param mixed $passable
* @param mixed ...$params
*/
protected function fireEvent(string $event, $pipe, $passable): void
protected function fireEvent(string $event, ...$params): void
{
if (! $this->useEvents) {
return;
}

if (is_object($pipe)) {
/** @var object $pipe */
$pipe = $pipe::class;
}

event(new $event($pipe, $passable));
event(new $event(...$params));
}
}
50 changes: 42 additions & 8 deletions tests/PipelineEventsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

namespace MichaelRubel\EnhancedPipeline\Tests;

use Closure;
use Illuminate\Support\Facades\Event;
use MichaelRubel\EnhancedPipeline\EnhancedPipelineServiceProvider;
use MichaelRubel\EnhancedPipeline\Events\PipeExecutionFinished;
use MichaelRubel\EnhancedPipeline\Events\PipeExecutionStarted;
use MichaelRubel\EnhancedPipeline\Events\PipelineFinished;
use MichaelRubel\EnhancedPipeline\Events\PipelineStarted;
use MichaelRubel\EnhancedPipeline\Pipeline;

class PipelineEventsTest extends TestCase
Expand All @@ -19,7 +22,6 @@ public function setUp(): void
Event::fake();
}

/** @test */
public function testMakesSureEventServiceProviderBoots()
{
app()->offsetUnset('events');
Expand All @@ -29,8 +31,42 @@ public function testMakesSureEventServiceProviderBoots()
$this->assertTrue(app()->bound('events'));
}

/** @test */
public function testFiresPipeStartedEvents()
public function testFiresPipelineStartedEvent()
{
app(Pipeline::class)
->withEvents()
->send('data')
->thenReturn();

Event::assertDispatched(function (PipelineStarted $event) {
$this->assertInstanceOf(Closure::class, $event->destination);
$this->assertSame('data', $event->passable);
$this->assertSame([], $event->pipes);
$this->assertFalse($event->useTransaction);

return true;
});
}

public function testFiresPipelineFinishedEvent()
{
app(Pipeline::class)
->withEvents()
->send('data')
->thenReturn();

Event::assertDispatched(function (PipelineFinished $event) {
$this->assertInstanceOf(Closure::class, $event->destination);
$this->assertSame('data', $event->passable);
$this->assertSame([], $event->pipes);
$this->assertFalse($event->useTransaction);
$this->assertSame('data', $event->result);

return true;
});
}

public function testFiresPipeExecutionStartedEvent()
{
app(Pipeline::class)
->withEvents()
Expand All @@ -49,8 +85,7 @@ public function testFiresPipeStartedEvents()
}, 2);
}

/** @test */
public function testFiresPipeStartedEventsButFailsToPass()
public function testFiresPipeExecutionStartedEventButFailsToFinish()
{
app(Pipeline::class)
->withEvents()
Expand All @@ -69,8 +104,7 @@ public function testFiresPipeStartedEventsButFailsToPass()
Event::assertNotDispatched(PipeExecutionFinished::class);
}

/** @test */
public function testFiresPipePassedEvents()
public function testFiresPipeExecutionFinishedEvent()
{
app(Pipeline::class)
->withEvents()
Expand All @@ -82,7 +116,7 @@ public function testFiresPipePassedEvents()
->thenReturn();

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

return true;
Expand Down

0 comments on commit c42937d

Please sign in to comment.