Skip to content

Commit

Permalink
Feat: Multiple next tick callbacks (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
bpolaszek authored Nov 12, 2023
1 parent eb16e95 commit 2adb322
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 16 deletions.
7 changes: 3 additions & 4 deletions src/EtlExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,10 @@ public function process(mixed $source = null, mixed $destination = null, array $

private function consumeNextTick(EtlState $state): void
{
if (null === $state->nextTickCallback) {
return;
foreach ($state->nextTickCallbacks as $callback) {
($callback)($state);
$state->nextTickCallbacks->detach($callback);
}

($state->nextTickCallback)($state);
}

/**
Expand Down
19 changes: 7 additions & 12 deletions src/EtlState.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@
use BenTools\ETL\Internal\ClonableTrait;
use Closure;
use DateTimeImmutable;
use SplObjectStorage;

final class EtlState
{
use ClonableTrait;

/**
* @internal
*
* @var SplObjectStorage<Closure, Closure>
*/
public ?Closure $nextTickCallback = null;
public SplObjectStorage $nextTickCallbacks;

private int $nbLoadedItemsSinceLastFlush = 0;
private bool $earlyFlush = false;
Expand All @@ -39,20 +42,12 @@ public function __construct(
public readonly ?DateTimeImmutable $endedAt = null,
public readonly mixed $output = null,
) {
$this->nextTickCallbacks ??= new SplObjectStorage();
}

public function nextTick(?callable $callback): void
public function nextTick(callable $callback): void
{
if (null === $callback) {
$this->nextTickCallback = null;

return;
}

$this->nextTickCallback = static function (EtlState $state) use ($callback) {
$callback($state);
$state->nextTick(null);
};
$this->nextTickCallbacks->attach(static fn (EtlState $state) => $callback($state));
}

/**
Expand Down
20 changes: 20 additions & 0 deletions tests/Behavior/NextTickTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

namespace BenTools\ETL\Tests\Behavior;

use ArrayObject;
use BenTools\ETL\EtlConfiguration;
use BenTools\ETL\EtlExecutor;
use BenTools\ETL\EtlState;
use BenTools\ETL\EventDispatcher\Event\ExtractEvent;
use BenTools\ETL\EventDispatcher\Event\LoadEvent;
use BenTools\ETL\Tests\InMemoryLoader;

use function expect;
Expand Down Expand Up @@ -35,3 +37,21 @@
->and($report->output[0])->toBe(['banana', 'apple'])
->and($report->output[1])->toBe(['strawberry', 'raspberry', 'peach']);
});

it('can trigger several callbacks, which are called only once', function () {
// Given
$bucket = new ArrayObject();
$etl = (new EtlExecutor())
->onLoad(function (LoadEvent $event) use ($bucket) {
if ('apple' === $event->item) {
$event->state->nextTick(fn (EtlState $state) => $bucket->append('apple'));
$event->state->nextTick(fn (EtlState $state) => $bucket->append('APPLE'));
}
});

// When
$report = $etl->process(['banana', 'apple', 'strawberry', 'raspberry', 'peach']);

// Then
expect([...$bucket])->toBe(['apple', 'APPLE']);
});

0 comments on commit 2adb322

Please sign in to comment.