Skip to content

[core] A successful activity writes two byte-identical completion events #262

Description

@gabiudrescu

What happens

Every activity that succeeds writes both events back to back, with the same body:

4  ActivityTaskCompleted   {"activityId":"01a06147-0ea8-…","result":"ch_000000018"}
5  ActivityCompleted       {"activityId":"01a06147-0ea8-…","result":"ch_000000018"}

From Worker/ActivityMessageProcessor.php:127:

$this->eventStore->append(new ActivityTaskCompleted($message->executionId, $message->activityId, $result));
$this->eventStore->append(new ActivityCompleted($message->executionId, $message->activityId, $result));

On the admin timeline they render as two rows a reader cannot tell apart. The first question anyone asks is whether the dashboard is broken.

The distinction is real, and only on the failure path

I traced who reads which:

  • ActivityCompleted - read by EventStoreHistorySource and ActivityEventJournal, i.e. by replay. Load-bearing.
  • ActivityTaskCompleted - read by JournalRunHistoryReader only, i.e. by the dashboard.

On failure they carry different things: ActivityTaskFailed has the attempt number, and the second event carries a retry state, and three failed attempts produce three of the first for one of the second. That asymmetry is worth having.

On success there is exactly one attempt that mattered, so the attempt's result is the settled result, and the pair is a literal duplicate - one row of storage and one row of timeline per activity, carrying nothing.

Ask

Either of:

  1. Skip ActivityTaskCompleted when the activity succeeded on its first attempt, or when its body would equal the settlement. The observational value is the attempt count, and one attempt is already implied.
  2. Keep both and let the dashboard fold them, which needs the phase field (companion issue) so the view can tell a settlement from an attempt result without comparing JSON.

I would not merge the two event types: the failure path uses the split, and losing it would cost the "three attempts, one outcome" reading that makes retries legible.

Workaround in use

The view hides the second row when its payload is identical to the row above, and explains why in the expansion. It works, and it compares serialised JSON to do it - which is not something a view should be deciding.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions