Skip to content

Support arrays for event tags - #923

Merged
DavidBadura merged 1 commit into
4.0.xfrom
event-tag-arrays
Oct 3, 2026
Merged

DavidBadura merged 1 commit into
4.0.xfrom
event-tag-arrays

Conversation

@DavidBadura

Copy link
Copy Markdown
Member

An event that relates to a variable number of entities, like an order with several products, couldn't tag each of them with #[EventTag]. Arrays were rejected as invalid value type, so you had to write a custom EventTagExtractor. The dcb.events dynamic product price example needs exactly this.

If a tagged property is an array, every element now becomes its own tag with the same prefix and hash:

final class ProductsOrdered
{
    /** @param list<ProductId> $productIds */
    public function __construct(
        #[EventTag(prefix: 'product')]
        public readonly array $productIds,
    ) {
    }
}

Elements follow the same rules as single values: null is skipped, duplicates are removed and nested arrays are still invalid.

An event that relates to a variable number of entities, like an order with
several products, had no way to tag each of them with #[EventTag]. Arrays
were rejected as invalid value type.

If a tagged property is an array, every element now becomes its own tag with
the same prefix and hash. Elements follow the same rules as single values:
null is skipped, nested arrays are still invalid.
@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown

Hello 👋

here is the most recent benchmark result:

SplitStreamBench
================

+-------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
|                         | time (kde mode)                                     | memory                                     |
+-------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
| subject                 | Tag: <current>     | Tag: base          | time-diff | Tag: <current>  | Tag: base  | memory-diff |
+-------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
| benchLoad10000Events () | 2.778ms (±0.00%)   | 3.105ms (±0.00%)   | -10.54%   | 35.774mb        | 36.295mb   | -1.43%      |
| benchSave10000Events () | 461.658ms (±0.00%) | 470.021ms (±0.00%) | -1.78%    | 35.909mb        | 35.909mb   | 0.00%       |
+-------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+

SimpleSetupTaggableStoreBench
=============================

+----------------------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
|                                        | time (kde mode)                                     | memory                                     |
+----------------------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
| subject                                | Tag: <current>     | Tag: base          | time-diff | Tag: <current>  | Tag: base  | memory-diff |
+----------------------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
| benchLoad1Event ()                     | 1.217ms (±0.00%)   | 1.205ms (±0.00%)   | +0.99%    | 36.312mb        | 36.312mb   | 0.00%       |
| benchLoad10000Events ()                | 75.141ms (±0.00%)  | 73.897ms (±0.00%)  | +1.68%    | 36.312mb        | 36.312mb   | 0.00%       |
| benchSave1Event ()                     | 1.472ms (±0.00%)   | 1.486ms (±0.00%)   | -0.92%    | 36.312mb        | 36.312mb   | 0.00%       |
| benchSave10000Events ()                | 308.581ms (±0.00%) | 310.592ms (±0.00%) | -0.65%    | 36.312mb        | 36.312mb   | 0.00%       |
| benchSave10000Aggregates ()            | 8.716s (±0.00%)    | 8.689s (±0.00%)    | +0.31%    | 36.312mb        | 36.312mb   | 0.00%       |
| benchSave10000AggregatesTransaction () | 6.110s (±0.00%)    | 6.048s (±0.00%)    | +1.03%    | 36.312mb        | 36.312mb   | 0.00%       |
| benchAppend1Event ()                   | 1.569ms (±0.00%)   | 1.621ms (±0.00%)   | -3.22%    | 36.312mb        | 36.312mb   | 0.00%       |
| benchAppend100Events ()                | 8.172ms (±0.00%)   | 8.160ms (±0.00%)   | +0.15%    | 36.312mb        | 36.312mb   | 0.00%       |
+----------------------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+

SubscriptionEngineBench
=======================

+---------------------------+-----------------+-----------------+-----------+-----------------+------------+-------------+
|                           | time (kde mode)                               | memory                                     |
+---------------------------+-----------------+-----------------+-----------+-----------------+------------+-------------+
| subject                   | Tag: <current>  | Tag: base       | time-diff | Tag: <current>  | Tag: base  | memory-diff |
+---------------------------+-----------------+-----------------+-----------+-----------------+------------+-------------+
| benchHandle10000Events () | 3.350s (±0.00%) | 3.346s (±0.00%) | +0.10%    | 48.301mb        | 48.301mb   | 0.00%       |
+---------------------------+-----------------+-----------------+-----------+-----------------+------------+-------------+

NoopSubscriptionEngineBench
===========================

+---------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
|                           | time (kde mode)                                     | memory                                     |
+---------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
| subject                   | Tag: <current>     | Tag: base          | time-diff | Tag: <current>  | Tag: base  | memory-diff |
+---------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
| benchHandle10000Events () | 101.604ms (±0.00%) | 103.542ms (±0.00%) | -1.87%    | 48.301mb        | 48.301mb   | 0.00%       |
+---------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+

SimpleSetupStreamStoreBench
===========================

+----------------------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
|                                        | time (kde mode)                                     | memory                                     |
+----------------------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
| subject                                | Tag: <current>     | Tag: base          | time-diff | Tag: <current>  | Tag: base  | memory-diff |
+----------------------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
| benchLoad1Event ()                     | 1.379ms (±0.00%)   | 1.389ms (±0.00%)   | -0.67%    | 35.146mb        | 35.146mb   | 0.00%       |
| benchLoad10000Events ()                | 71.796ms (±0.00%)  | 72.420ms (±0.00%)  | -0.86%    | 35.146mb        | 35.146mb   | 0.00%       |
| benchSave1Event ()                     | 1.669ms (±0.00%)   | 1.578ms (±0.00%)   | +5.71%    | 35.146mb        | 35.146mb   | 0.00%       |
| benchSave10000Events ()                | 296.480ms (±0.00%) | 291.994ms (±0.00%) | +1.54%    | 35.146mb        | 35.146mb   | 0.00%       |
| benchSave10000Aggregates ()            | 8.673s (±0.00%)    | 8.529s (±0.00%)    | +1.69%    | 35.146mb        | 35.146mb   | 0.00%       |
| benchSave10000AggregatesTransaction () | 6.073s (±0.00%)    | 6.065s (±0.00%)    | +0.13%    | 35.147mb        | 35.147mb   | 0.00%       |
+----------------------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+

SubscriptionEngineBatchBench
============================

+---------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
|                           | time (kde mode)                                     | memory                                     |
+---------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
| subject                   | Tag: <current>     | Tag: base          | time-diff | Tag: <current>  | Tag: base  | memory-diff |
+---------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
| benchHandle10000Events () | 107.486ms (±0.00%) | 107.375ms (±0.00%) | +0.10%    | 35.726mb        | 35.726mb   | 0.00%       |
+---------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+

PersonalDataBench
=================

+----------------------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
|                                        | time (kde mode)                                     | memory                                     |
+----------------------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
| subject                                | Tag: <current>     | Tag: base          | time-diff | Tag: <current>  | Tag: base  | memory-diff |
+----------------------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+
| benchLoad1Event ()                     | 888.800μs (±0.00%) | 892.300μs (±0.00%) | -0.39%    | 37.008mb        | 37.008mb   | +0.00%      |
| benchLoad10000Events ()                | 172.246ms (±0.00%) | 173.197ms (±0.00%) | -0.55%    | 37.008mb        | 37.008mb   | 0.00%       |
| benchSave1Event ()                     | 2.263ms (±0.00%)   | 2.355ms (±0.00%)   | -3.92%    | 37.008mb        | 37.008mb   | 0.00%       |
| benchSave10000Events ()                | 412.743ms (±0.00%) | 408.217ms (±0.00%) | +1.11%    | 37.063mb        | 37.063mb   | 0.00%       |
| benchSave10000Aggregates ()            | 13.648s (±0.00%)   | 13.776s (±0.00%)   | -0.93%    | 37.008mb        | 37.008mb   | 0.00%       |
| benchSave10000AggregatesTransaction () | 11.234s (±0.00%)   | 11.205s (±0.00%)   | +0.26%    | 37.008mb        | 37.008mb   | 0.00%       |
+----------------------------------------+--------------------+--------------------+-----------+-----------------+------------+-------------+

SnapshotsBench
==============

+----------------------------------------+-------------------+-------------------+-----------+-----------------+------------+-------------+
|                                        | time (kde mode)                                   | memory                                     |
+----------------------------------------+-------------------+-------------------+-----------+-----------------+------------+-------------+
| subject                                | Tag: <current>    | Tag: base         | time-diff | Tag: <current>  | Tag: base  | memory-diff |
+----------------------------------------+-------------------+-------------------+-----------+-----------------+------------+-------------+
| benchLoad10000EventsMissingSnapshot () | 71.933ms (±0.00%) | 74.029ms (±0.00%) | -2.83%    | 35.151mb        | 35.151mb   | 0.00%       |
| benchLoad10000Events ()                | 1.122ms (±0.00%)  | 1.117ms (±0.00%)  | +0.46%    | 35.151mb        | 35.151mb   | 0.00%       |
+----------------------------------------+-------------------+-------------------+-----------+-----------------+------------+-------------+

CommandToQueryBench
===================

+----------------+------------------+------------------+-----------+-----------------+------------+-------------+
|                | time (kde mode)                                 | memory                                     |
+----------------+------------------+------------------+-----------+-----------------+------------+-------------+
| subject        | Tag: <current>   | Tag: base        | time-diff | Tag: <current>  | Tag: base  | memory-diff |
+----------------+------------------+------------------+-----------+-----------------+------------+-------------+
| benchCreate () | 3.853ms (±0.00%) | 3.964ms (±0.00%) | -2.82%    | 5.057mb         | 5.057mb    | 0.00%       |
| benchUpdate () | 5.182ms (±0.00%) | 5.325ms (±0.00%) | -2.69%    | 5.067mb         | 5.067mb    | 0.00%       |
| benchBoth ()   | 9.118ms (±0.00%) | 8.866ms (±0.00%) | +2.84%    | 5.389mb         | 5.389mb    | 0.00%       |
+----------------+------------------+------------------+-----------+-----------------+------------+-------------+

This comment gets update everytime a new commit comes in!

@DavidBadura DavidBadura added the enhancement New feature or request label Oct 3, 2026
@DavidBadura DavidBadura added this to the 4.0.0 milestone Oct 3, 2026
@DavidBadura
DavidBadura merged commit 8df891c into 4.0.x Oct 3, 2026
37 of 39 checks passed
@DavidBadura
DavidBadura deleted the event-tag-arrays branch October 3, 2026 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants