Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rename handle to subscribe #448

Merged
merged 1 commit into from
Dec 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/pages/event_bus.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,16 @@ final class WelcomeListener implements Listener
## Subscriber

A `Subscriber` is a listener, except that it has implemented the invoke method itself.
Instead, you can define your own and multiple methods and listen for specific events with the attribute `Handle`.
Instead, you can define your own and multiple methods and listen for specific events with the attribute `Subscribe`.

```php
use Patchlevel\EventSourcing\Attribute\Handle;
use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\EventBus\Listener;
use Patchlevel\EventSourcing\EventBus\Message;

final class WelcomeSubscriber extends Subscriber
{
#[Handle(ProfileCreated::class)]
#[Subscribe(ProfileCreated::class)]
public function onProfileCreated(Message $message): void
{
echo 'Welcome!';
Expand Down
12 changes: 6 additions & 6 deletions docs/pages/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ Each projector is then responsible for a specific projection and version.
use Doctrine\DBAL\Connection;
use Patchlevel\EventSourcing\Attribute\Create;
use Patchlevel\EventSourcing\Attribute\Drop;
use Patchlevel\EventSourcing\Attribute\Handle;
use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\EventBus\Message;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionId;
use Patchlevel\EventSourcing\Projection\Projector\Projector;
Expand All @@ -181,7 +181,7 @@ final class HotelProjection implements Projector
return $this->db->fetchAllAssociative('SELECT id, name, guests FROM hotel;')
}

#[Handle(HotelCreated::class)]
#[Subscribe(HotelCreated::class)]
public function handleHotelCreated(Message $message): void
{
$event = $message->event();
Expand All @@ -196,7 +196,7 @@ final class HotelProjection implements Projector
);
}

#[Handle(GuestIsCheckedIn::class)]
#[Subscribe(GuestIsCheckedIn::class)]
public function handleGuestIsCheckedIn(Message $message): void
{
$this->db->executeStatement(
Expand All @@ -205,7 +205,7 @@ final class HotelProjection implements Projector
);
}

#[Handle(GuestIsCheckedOut::class)]
#[Subscribe(GuestIsCheckedOut::class)]
public function handleGuestIsCheckedOut(Message $message): void
{
$this->db->executeStatement(
Expand Down Expand Up @@ -237,7 +237,7 @@ final class HotelProjection implements Projector
In our example we also want to send an email to the head office as soon as a guest is checked in.

```php
use Patchlevel\EventSourcing\Attribute\Handle;
use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\EventBus\Message;
use Patchlevel\EventSourcing\EventBus\Subscriber;

Expand All @@ -248,7 +248,7 @@ final class SendCheckInEmailProcessor extends Subscriber
) {
}

#[Handle(GuestIsCheckedIn::class)]
#[Subscribe(GuestIsCheckedIn::class)]
public function onGuestIsCheckedIn(Message $message): void
{
$this->mailer->send(
Expand Down
4 changes: 2 additions & 2 deletions docs/pages/processor.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ final class SendEmailProcessor implements Listener
You can also create the whole thing as a subscriber too.

```php
use Patchlevel\EventSourcing\Attribute\Handle;
use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\EventBus\Message;
use Patchlevel\EventSourcing\EventBus\Subscriber;

Expand All @@ -61,7 +61,7 @@ final class SendEmailProcessor extends Subscriber
) {
}

#[Handle(ProfileCreated::class)]
#[Subscribe(ProfileCreated::class)]
public function onProfileCreated(Message $message): void
{
$this->mailer->send(
Expand Down
8 changes: 4 additions & 4 deletions docs/pages/projection.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ In this example we always create a new data set in a relational database when a
use Doctrine\DBAL\Connection;
use Patchlevel\EventSourcing\Attribute\Create;
use Patchlevel\EventSourcing\Attribute\Drop;
use Patchlevel\EventSourcing\Attribute\Handle;
use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\EventBus\Message;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionId;
use Patchlevel\EventSourcing\Projection\Projector\Projector;
Expand Down Expand Up @@ -63,7 +63,7 @@ final class ProfileProjection implements Projector
);
}

#[Handle(ProfileCreated::class)]
#[Subscribe(ProfileCreated::class)]
public function handleProfileCreated(Message $message): void
{
$profileCreated = $message->event();
Expand Down Expand Up @@ -97,8 +97,8 @@ Projectors can have one `create` and `drop` method that is executed when the pro
In some cases it may be that no schema has to be created for the projection, as the target does it automatically.
To do this, you must add either the `Create` or `Drop` attribute to the method. The method name itself doesn't matter.

Otherwise, a projector can have any number of handle methods that are called for certain defined events.
In order to say which method is responsible for which event, you need the `Handle` attribute.
Otherwise, a projector can subscribe any number of events.
In order to say which method is responsible for which event, you need the `Subscribe` attribute.
As the first parameter, you must pass the event class to which the reaction should then take place.
The method itself must expect a `Message`, which then contains the event. The method name itself doesn't matter.

Expand Down
2 changes: 1 addition & 1 deletion src/Attribute/Handle.php → src/Attribute/Subscribe.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Attribute;

#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
final class Handle
final class Subscribe
{
/** @param class-string $eventClass */
public function __construct(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use function sprintf;

final class DuplicateHandleMethod extends EventBusException
final class DuplicateSubscribeMethod extends EventBusException
{
/**
* @param class-string<Subscriber> $subscriber
Expand All @@ -16,7 +16,7 @@ public function __construct(string $subscriber, string $event, string $fistMetho
{
parent::__construct(
sprintf(
'Two methods "%s" and "%s" on the subscriber "%s" want to handle the same event "%s". Only one method can handle an event.',
'Two methods "%s" and "%s" on the subscriber "%s" want to subscribe the same event "%s". Only one method can subscribe an event.',
$fistMethod,
$secondMethod,
$subscriber,
Expand Down
20 changes: 10 additions & 10 deletions src/EventBus/Subscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@

namespace Patchlevel\EventSourcing\EventBus;

use Patchlevel\EventSourcing\Attribute\Handle;
use Patchlevel\EventSourcing\Attribute\Subscribe;
use ReflectionClass;

use function array_key_exists;

abstract class Subscriber implements Listener
{
/** @var array<class-string, string>|null */
private array|null $handleMethods = null;
private array|null $subscribeMethods = null;

final public function __invoke(Message $message): void
{
if ($this->handleMethods === null) {
if ($this->subscribeMethods === null) {
$this->init();
}

$method = $this->handleMethods[$message->event()::class] ?? null;
$method = $this->subscribeMethods[$message->event()::class] ?? null;

if (!$method) {
return;
Expand All @@ -34,25 +34,25 @@ private function init(): void
$reflection = new ReflectionClass(static::class);
$methods = $reflection->getMethods();

$this->handleMethods = [];
$this->subscribeMethods = [];

foreach ($methods as $method) {
$attributes = $method->getAttributes(Handle::class);
$attributes = $method->getAttributes(Subscribe::class);

foreach ($attributes as $attribute) {
$instance = $attribute->newInstance();
$eventClass = $instance->eventClass();

if (array_key_exists($eventClass, $this->handleMethods)) {
throw new DuplicateHandleMethod(
if (array_key_exists($eventClass, $this->subscribeMethods)) {
throw new DuplicateSubscribeMethod(
static::class,
$eventClass,
$this->handleMethods[$eventClass],
$this->subscribeMethods[$eventClass],
$method->getName(),
);
}

$this->handleMethods[$eventClass] = $method->getName();
$this->subscribeMethods[$eventClass] = $method->getName();
}
}
}
Expand Down
16 changes: 8 additions & 8 deletions src/Metadata/Projector/AttributeProjectorMetadataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Patchlevel\EventSourcing\Attribute\Create;
use Patchlevel\EventSourcing\Attribute\Drop;
use Patchlevel\EventSourcing\Attribute\Handle;
use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\Projection\Projector\Projector;
use ReflectionClass;

Expand All @@ -28,27 +28,27 @@ public function metadata(string $projector): ProjectorMetadata

$methods = $reflector->getMethods();

$handleMethods = [];
$subscribeMethods = [];
$createMethod = null;
$dropMethod = null;

foreach ($methods as $method) {
$attributes = $method->getAttributes(Handle::class);
$attributes = $method->getAttributes(Subscribe::class);

foreach ($attributes as $attribute) {
$instance = $attribute->newInstance();
$eventClass = $instance->eventClass();

if (array_key_exists($eventClass, $handleMethods)) {
throw new DuplicateHandleMethod(
if (array_key_exists($eventClass, $subscribeMethods)) {
throw new DuplicateSubscribeMethod(
$projector,
$eventClass,
$handleMethods[$eventClass],
$subscribeMethods[$eventClass],
$method->getName(),
);
}

$handleMethods[$eventClass] = $method->getName();
$subscribeMethods[$eventClass] = $method->getName();
}

if ($method->getAttributes(Create::class)) {
Expand Down Expand Up @@ -79,7 +79,7 @@ public function metadata(string $projector): ProjectorMetadata
}

$metadata = new ProjectorMetadata(
$handleMethods,
$subscribeMethods,
$createMethod,
$dropMethod,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

use function sprintf;

final class DuplicateHandleMethod extends MetadataException
final class DuplicateSubscribeMethod extends MetadataException
{
/**
* @param class-string<Projector> $projector
Expand All @@ -19,7 +19,7 @@ public function __construct(string $projector, string $event, string $fistMethod
{
parent::__construct(
sprintf(
'Two methods "%s" and "%s" on the projection "%s" want to handle the same event "%s". Only one method can handle an event.',
'Two methods "%s" and "%s" on the projection "%s" want to subscribe the same event "%s". Only one method can subscribe an event.',
$fistMethod,
$secondMethod,
$projector,
Expand Down
2 changes: 1 addition & 1 deletion src/Metadata/Projector/ProjectorMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ final class ProjectorMetadata
{
public function __construct(
/** @var array<class-string, string> */
public readonly array $handleMethods = [],
public readonly array $subscribeMethods = [],
public readonly string|null $createMethod = null,
public readonly string|null $dropMethod = null,
) {
Expand Down
6 changes: 3 additions & 3 deletions src/Projection/Projectionist/DefaultProjectionist.php
Original file line number Diff line number Diff line change
Expand Up @@ -376,11 +376,11 @@ private function handleMessage(Message $message, Projection $projection, bool $t
throw ProjectorNotFound::forProjectionId($projection->id());
}

$handleMethod = $this->projectorResolver->resolveHandleMethod($projector, $message);
$subscribeMethod = $this->projectorResolver->resolveSubscribeMethod($projector, $message);

if ($handleMethod) {
if ($subscribeMethod) {
try {
$handleMethod($message);
$subscribeMethod($message);

$this->logger?->debug(
sprintf(
Expand Down
8 changes: 4 additions & 4 deletions src/Projection/Projector/MetadataProjectorResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ public function resolveDropMethod(Projector $projector): Closure|null
return $projector->$method(...);
}

public function resolveHandleMethod(Projector $projector, Message $message): Closure|null
public function resolveSubscribeMethod(Projector $projector, Message $message): Closure|null
{
$event = $message->event();
$metadata = $this->metadataFactory->metadata($projector::class);

if (!array_key_exists($event::class, $metadata->handleMethods)) {
if (!array_key_exists($event::class, $metadata->subscribeMethods)) {
return null;
}

$handleMethod = $metadata->handleMethods[$event::class];
$subscribeMethod = $metadata->subscribeMethods[$event::class];

return $projector->$handleMethod(...);
return $projector->$subscribeMethod(...);
}
}
6 changes: 3 additions & 3 deletions src/Projection/Projector/ProjectorHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ public function __construct(
public function handleMessage(Message $message, Projector ...$projectors): void
{
foreach ($projectors as $projector) {
$handleMethod = $this->projectorResolver->resolveHandleMethod($projector, $message);
$subscribeMethod = $this->projectorResolver->resolveSubscribeMethod($projector, $message);

if (!$handleMethod) {
if (!$subscribeMethod) {
continue;
}

$handleMethod($message);
$subscribeMethod($message);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Projection/Projector/ProjectorResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ public function resolveCreateMethod(Projector $projector): Closure|null;

public function resolveDropMethod(Projector $projector): Closure|null;

public function resolveHandleMethod(Projector $projector, Message $message): Closure|null;
public function resolveSubscribeMethod(Projector $projector, Message $message): Closure|null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

namespace Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Processor;

use Patchlevel\EventSourcing\Attribute\Handle;
use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\EventBus\Message;
use Patchlevel\EventSourcing\EventBus\Subscriber;
use Patchlevel\EventSourcing\Tests\Integration\BasicImplementation\Events\ProfileCreated;
use Patchlevel\EventSourcing\Tests\Integration\BasicImplementation\SendEmailMock;

final class SendEmailProcessor extends Subscriber
{
#[Handle(ProfileCreated::class)]
#[Subscribe(ProfileCreated::class)]
public function onProfileCreated(Message $message): void
{
SendEmailMock::send();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Doctrine\DBAL\Connection;
use Patchlevel\EventSourcing\Attribute\Create;
use Patchlevel\EventSourcing\Attribute\Drop;
use Patchlevel\EventSourcing\Attribute\Handle;
use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\EventBus\Message;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionId;
use Patchlevel\EventSourcing\Projection\Projector\Projector;
Expand Down Expand Up @@ -39,7 +39,7 @@ public function drop(): void
$this->connection->executeStatement('DROP TABLE IF EXISTS projection_profile;');
}

#[Handle(ProfileCreated::class)]
#[Subscribe(ProfileCreated::class)]
public function handleProfileCreated(Message $message): void
{
$profileCreated = $message->event();
Expand Down
Loading
Loading