Skip to content

Commit

Permalink
add debug performance possibilities
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidBadura committed Oct 8, 2023
1 parent 5ce6710 commit 5e1b140
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 0 deletions.
70 changes: 70 additions & 0 deletions src/Debug/ProfileData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Debug;

use Patchlevel\EventSourcing\Aggregate\AggregateRoot;

use function microtime;

final class ProfileData
{
private float|null $start = null;
private float|null $duration = null;

private function __construct(
private readonly string $type,
/** @var class-string<AggregateRoot> */
private readonly string $aggregateClass,
private readonly string $aggregateId,
) {
}

public function start(): void
{
$this->start = microtime(true);
}

public function stop(): void
{
if ($this->start === null) {
return;
}

$this->duration = microtime(true) - $this->start;
}

public function type(): string
{
return $this->type;
}

/** @return class-string<AggregateRoot> */
public function aggregateClass(): string
{
return $this->aggregateClass;
}

public function aggregateId(): string
{
return $this->aggregateId;
}

public function duration(): float|null
{
return $this->duration;
}

/** @param class-string<AggregateRoot> $aggregateClass */
public static function load(string $aggregateClass, string $aggregateId): self
{
return new ProfileData('load', $aggregateClass, $aggregateId);
}

/** @param class-string<AggregateRoot> $aggregateClass */
public static function save(string $aggregateClass, string $aggregateId): self
{
return new ProfileData('save', $aggregateClass, $aggregateId);
}
}
27 changes: 27 additions & 0 deletions src/Debug/ProfileDataHolder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Debug;

final class ProfileDataHolder
{
/** @var ProfileData[] */
private array $data = [];

public function addData(ProfileData $data): void
{
$this->data[] = $data;
}

/** @return ProfileData[] */
public function getData(): array
{
return $this->data;
}

public function reset(): void
{
$this->data = [];
}
}
60 changes: 60 additions & 0 deletions src/Debug/TraceableRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Debug;

use Patchlevel\EventSourcing\Aggregate\AggregateRoot;
use Patchlevel\EventSourcing\Repository\Repository;
use Symfony\Component\Stopwatch\Stopwatch;

/**
* @template T of AggregateRoot
* @implements Repository<T>
*/
final class TraceableRepository implements Repository
{
public function __construct(
/** @var Repository<T> */
private readonly Repository $repository,
/** @var class-string<T> */
private readonly string $aggregateClass,
private readonly ProfileDataHolder $dataHolder,
private readonly Stopwatch|null $stopwatch = null,
) {
}

/** @return T */
public function load(string $id): AggregateRoot
{
$data = ProfileData::load($this->aggregateClass, $id);

$this->dataHolder->addData($data);
$event = $this->stopwatch?->start('event_sourcing', 'event_sourcing');
$data->start();

try {
$aggregate = $this->repository->load($id);
} finally {
$data->stop();
$event?->stop();
}

return $aggregate;
}

public function has(string $id): bool
{
return $this->repository->has($id);
}

/** @param T $aggregate */
public function save(AggregateRoot $aggregate): void
{
$event = $this->stopwatch?->start('event_sourcing', 'event_sourcing');

$this->repository->save($aggregate);

$event?->stop();
}
}
37 changes: 37 additions & 0 deletions src/Debug/TraceableRepositoryManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Debug;

use Patchlevel\EventSourcing\Aggregate\AggregateRoot;
use Patchlevel\EventSourcing\Repository\Repository;
use Patchlevel\EventSourcing\Repository\RepositoryManager;
use Symfony\Component\Stopwatch\Stopwatch;

final class TraceableRepositoryManager implements RepositoryManager
{
public function __construct(
private RepositoryManager $repositoryManager,
private readonly ProfileDataHolder $dataHolder,
private readonly Stopwatch|null $stopwatch = null,
) {
}

/**
* @param class-string<T> $aggregateClass
*
* @return Repository<T>
*
* @template T of AggregateRoot
*/
public function get(string $aggregateClass): Repository
{
return new TraceableRepository(
$this->repositoryManager->get($aggregateClass),
$aggregateClass,
$this->dataHolder,
$this->stopwatch,
);
}
}

0 comments on commit 5e1b140

Please sign in to comment.