Skip to content

fix(stream): log supervision Resume/Restart in MapAsync operators#3124

Merged
He-Pin merged 1 commit into
mainfrom
fix/mapasync-supervision-logging-3103
Jun 22, 2026
Merged

fix(stream): log supervision Resume/Restart in MapAsync operators#3124
He-Pin merged 1 commit into
mainfrom
fix/mapasync-supervision-logging-3103

Conversation

@He-Pin

@He-Pin He-Pin commented Jun 22, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds error logging when supervision strategy returns Resume or Restart for failed elements in MapAsync, MapAsyncUnordered, and MapAsyncPartitioned
  • Respects the stage-errors-default-log-level configuration and per-stage LogLevels.onFailure attribute from Add fine-grained stream error logging control #2805
  • Logging placed to avoid double-logging (uses Holder's directive cache to ensure exactly one log per failure)

Changes

  • MapAsync: Added StageLogging mixin, logSupervisionFailure helper, logging in pushNextIfPossible and sync exception handler
  • MapAsyncUnordered: Added StageLogging mixin, logSupervisionFailure helper, logging in futureCompleted and sync exception handler
  • MapAsyncPartitioned: Added StageLogging mixin, logSupervisionFailure helper, logging in both ordered and unordered pushNextIfPossible and sync exception handler

Motivation

MapAsync, MapAsyncUnordered, and MapAsyncPartitioned silently skip failed elements when the supervision strategy returns Resume or Restart. This makes production debugging difficult — users cannot see which elements were dropped or what exceptions occurred.

Modification

  • Mix in StageLogging trait for all three operators
  • Add logSupervisionFailure helper that checks LogLevels.onFailure attribute, falls back to LogLevels.defaultErrorLevel(system), and logs at the configured level
  • For MapAsync and MapAsyncPartitioned, logging is placed in pushNextIfPossible (not in futureCB or the fast path) to avoid double-logging since the Holder caches the supervision directive
  • For MapAsyncUnordered, logging is placed in futureCompleted (no buffer re-processing)
  • Sync exception handlers log directly since they bypass the Holder caching

Result

Supervision Resume/Restart decisions now produce log entries with exception details, enabling users to diagnose dropped elements. Log level can be controlled via pekko.stream.materializer.stage-errors-default-log-level config or per-stage ActorAttributes.logLevels.

Tests

  • FlowMapAsyncSpec: 3 new tests (async future failure logs, sync throw logs, log level Off disables logging)
  • FlowMapAsyncUnorderedSpec: 3 new tests (same pattern)
  • FlowMapAsyncPartitionedSpec: 3 new tests (ordered, unordered, log level Off)
  • All 74 existing + new tests pass

References

Fixes #3103

Motivation:
MapAsync, MapAsyncUnordered, and MapAsyncPartitioned silently skip
failed elements when the supervision strategy returns Resume or
Restart, making production debugging difficult.

Modification:
Add StageLogging mixin and log supervision failures at the configured
error level (respecting stage-errors-default-log-level and per-stage
LogLevels.onFailure attribute) before skipping elements. Logging is
placed in pushNextIfPossible / futureCompleted / onPush sync handler
to avoid double-logging via Holder's directive cache.

Result:
Supervision Resume/Restart decisions now produce log entries with
exception details, enabling users to diagnose dropped elements.

Tests:
- FlowMapAsyncSpec: 3 new log verification tests (async, sync, Off)
- FlowMapAsyncUnorderedSpec: 3 new log verification tests
- FlowMapAsyncPartitionedSpec: 3 new log verification tests (ordered + unordered + Off)
- All 74 existing + new tests pass

References:
Fixes #3103
@He-Pin He-Pin added this to the 2.0.0-M4 milestone Jun 22, 2026
@He-Pin He-Pin added the t:stream Pekko Streams label Jun 22, 2026

@pjfanning pjfanning left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@He-Pin He-Pin merged commit f57cc81 into main Jun 22, 2026
9 checks passed
@He-Pin He-Pin deleted the fix/mapasync-supervision-logging-3103 branch June 22, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t:stream Pekko Streams

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MapAsync and MapAsyncUnordered silently swallow exceptions on supervision Resume/Restart

2 participants