-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add an item writer that dispatch events before and after writing (#89)
- Loading branch information
1 parent
d526418
commit 5e7857f
Showing
7 changed files
with
146 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yokai\Batch\Event; | ||
|
||
use Yokai\Batch\Job\Item\ItemJob; | ||
use Yokai\Batch\Job\Item\ItemWriterInterface; | ||
use Yokai\Batch\Job\Item\Writer\DispatchEventsWriter; | ||
|
||
/** | ||
* This event is triggered by {@see DispatchEventsWriter} | ||
* whenever an {@see ItemJob} is calling the {@see ItemWriterInterface} to write | ||
* after actual write is performed. | ||
*/ | ||
final class PostWriteEvent extends JobEvent | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yokai\Batch\Event; | ||
|
||
use Yokai\Batch\Job\Item\ItemJob; | ||
use Yokai\Batch\Job\Item\ItemWriterInterface; | ||
use Yokai\Batch\Job\Item\Writer\DispatchEventsWriter; | ||
|
||
/** | ||
* This event is triggered by {@see DispatchEventsWriter} | ||
* whenever an {@see ItemJob} is calling the {@see ItemWriterInterface} to write | ||
* before actual write is performed. | ||
*/ | ||
final class PreWriteEvent extends JobEvent | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yokai\Batch\Job\Item\Writer; | ||
|
||
use Psr\EventDispatcher\EventDispatcherInterface; | ||
use Yokai\Batch\Event\PostWriteEvent; | ||
use Yokai\Batch\Event\PreWriteEvent; | ||
use Yokai\Batch\Job\Item\AbstractElementDecorator; | ||
use Yokai\Batch\Job\Item\ItemWriterInterface; | ||
|
||
/** | ||
* This {@see ItemWriterInterface} act as decorator, | ||
* and will dispatch {@see PreWriteEvent} before, and {@see PostWriteEvent} after. | ||
*/ | ||
final class DispatchEventsWriter extends AbstractElementDecorator implements ItemWriterInterface | ||
{ | ||
public function __construct( | ||
private EventDispatcherInterface $eventDispatcher, | ||
private ItemWriterInterface $writer, | ||
) { | ||
} | ||
|
||
public function write(iterable $items): void | ||
{ | ||
$this->dispatch(new PreWriteEvent($this->getJobExecution())); | ||
|
||
$this->writer->write($items); | ||
|
||
$this->dispatch(new PostWriteEvent($this->getJobExecution())); | ||
} | ||
|
||
protected function getDecoratedElements(): iterable | ||
{ | ||
return [$this->writer]; | ||
} | ||
|
||
private function dispatch(object $event): void | ||
{ | ||
try { | ||
$this->eventDispatcher->dispatch($event); | ||
} catch (\Throwable $error) { | ||
$this->getJobExecution()->getLogger()->error( | ||
'An error occurred while dispatching event.', | ||
['event' => $event::class, 'error' => (string)$error], | ||
); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yokai\Batch\Tests\Job\Item\Writer; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use Yokai\Batch\Event\PostWriteEvent; | ||
use Yokai\Batch\Event\PreWriteEvent; | ||
use Yokai\Batch\Job\Item\Writer\DispatchEventsWriter; | ||
use Yokai\Batch\Job\Item\Writer\NullWriter; | ||
use Yokai\Batch\JobExecution; | ||
use Yokai\Batch\Test\Job\Item\Writer\TestDebugWriter; | ||
use Yokai\Batch\Tests\Dummy\DebugEventDispatcher; | ||
|
||
class DispatchEventsWriterTest extends TestCase | ||
{ | ||
public function test(): void | ||
{ | ||
$writer = new DispatchEventsWriter( | ||
$dispatcher = new DebugEventDispatcher(), | ||
$decorated = new TestDebugWriter(new NullWriter()), | ||
); | ||
$dispatcher->addListener(PostWriteEvent::class, function () { | ||
throw new \RuntimeException('Test exception'); | ||
}); | ||
|
||
$writer->setJobExecution($execution = JobExecution::createRoot('123', 'foo')); | ||
$writer->initialize(); | ||
$writer->write(['irrelevant']); | ||
$writer->flush(); | ||
|
||
$decorated->assertWasConfigured(); | ||
$decorated->assertWasUsed(); | ||
$events = $dispatcher->getEvents(); | ||
self::assertCount(2, $events); | ||
self::assertInstanceOf(PreWriteEvent::class, $events[0] ?? null); | ||
self::assertInstanceOf(PostWriteEvent::class, $events[1] ?? null); | ||
self::assertStringContainsString( | ||
'ERROR: An error occurred while dispatching event. {"event":"Yokai\\\\Batch\\\\Event\\\\PostWriteEvent","error":"RuntimeException: Test exception', | ||
(string)$execution->getLogs(), | ||
); | ||
} | ||
} |