streak icon indicating copy to clipboard operation
streak copied to clipboard

Introduce `Correlatable` Interface for Listener Event Correlation

Open alanbem opened this issue 8 months ago • 0 comments

Description:

Problem/Motivation:

Currently, stateful listeners like Process Managers and Sagas often need to be instantiated or identified based on specific data within an incoming event (correlation). This logic, which maps an event to a specific Listener\Id, is crucial but often implemented implicitly within Listener\Factory::createFor methods or via non-standardized static methods on the Listener itself (e.g., a static correlate method).

While the static method pattern works, there's no standard contract within the Streak domain interfaces to represent this capability. This means:

  • Discoverability of how a listener is correlated is lower.
  • Developers might implement this logic in inconsistent ways.
  • Infrastructure components (like generic factories or potential future subscription runners) cannot easily check if a listener can be correlated from an event via a standard interface.

Proposed Solution:

Introduce a new optional interface, potentially named Streak\Domain\Event\Listener\Correlatable (or similar, open to suggestions), that listeners can implement:

<?php

namespace Streak\Domain\Event\Listener;

use Streak\Domain\Event;
use Streak\Domain\Exception\InvalidEventGiven; // Or a more specific CorrelationFailed exception

interface Correlatable
{
    /**
     * Determines the Listener ID associated with the given event envelope.
     * This method encapsulates the correlation logic.
     *
     * @throws InvalidEventGiven If the event cannot be correlated to an ID for this listener type.
     */
    public static function correlate(Event\Envelope $envelope): Id;
}

How it would be used:

  1. Listener classes (especially stateful ones) that can be correlated from events would implement this interface and the static correlate method.
  2. Listener\Factory implementations, specifically in their createFor method, could check if the target listener class implements Correlatable and, if so, call the static correlate method to determine the Listener\Id.
  3. This centralizes the correlation logic within the Listener class itself, making it more explicit and testable.

Benefits:

  • Standardizes Pattern: Provides a clear, documented pattern for event-to-listener correlation.
  • Improved Clarity: Makes the relationship between specific events and listener instances more explicit in the domain model.
  • Encapsulation: Keeps correlation logic closer to the Listener it relates to.
  • Foundation: While not providing automation itself, it lays a potential foundation for future tooling or infrastructure improvements that might leverage this interface.

Note: This proposal focuses on establishing a standard interface and pattern. It does not necessarily imply automating the invocation of createFor or the factory system itself initially, but rather standardizing the correlation logic determination.

alanbem avatar Apr 11 '25 00:04 alanbem