Problem

ServerSideEventSender::sendEvent() makes a synchronous HTTP call to the Piano Analytics collection API. When called during the request lifecycle (e.g. from a middleware or event subscriber), this blocks the response to the client.

For use cases like the pianoanalytics_shorturl module which tracks short URL redirect visits, the PA API call adds latency to every redirect. This is especially problematic for high-traffic short URLs.

Proposed solution

Add a deferred event queue to ServerSideEventSender with a kernel.terminate subscriber that sends queued events after the response is sent to the client.

New API

// Queue an event for deferred sending.
$eventSender->queueEvent($event_name, $properties, $visitor_id, $headers);

// Events are automatically flushed during kernel.terminate.
// No action needed by the caller.

Architecture

  • queueEvent(): stores event data in an in-memory array on the service. Zero overhead during the request.
  • kernel.terminate subscriber: iterates queued events and calls sendEvent() for each. Runs after the response is sent — the user does not wait.
  • sendEvent(): unchanged — still available for synchronous sending when needed.

Benefits

  • Zero impact on response latency for server-side tracking
  • Integration modules (pianoanalytics_shorturl, etc.) call queueEvent() instead of managing their own terminate subscribers
  • Batching potential: future optimization could send multiple events in a single API call
  • Backward compatible: sendEvent() still works synchronously

Impact on pianoanalytics_shorturl

The shorturl integration currently manages its own kernel.terminate subscriber. With this feature, it simplifies to:

public function onVisit(ShortUrlVisitEvent $event): void {
    $this->eventSender->queueEvent(
        $event_name, $properties, $visitor_id, $headers,
    );
    // No onTerminate needed — base module handles it.
}
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mably created an issue. See original summary.

mably’s picture

Status: Active » Needs review

  • mably committed 927f09e3 on 2.x
    feat: #3584548 Add deferred event sending via kernel.terminate for non-...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.