Skip to content

[#4796] Resolve the reset converter only when there is a reset context - #4806

Open
schananas wants to merge 1 commit into
mainfrom
bug/4796/reset-tokens-no-converter-when-no-context
Open

[#4796] Resolve the reset converter only when there is a reset context#4806
schananas wants to merge 1 commit into
mainfrom
bug/4796/reset-tokens-no-converter-when-no-context

Conversation

@schananas

@schananas schananas commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Fixes #4796

What changed

resetTokens() resolved a GeneralConverter from the processing context unconditionally, once per segment, so a processor whose unit-of-work factory supplies no components could not be reset at all. It failed with UnsupportedOperationException: EmptyApplicationContext does not provide any components, an error naming neither resets nor converters.

The converter is now resolved once, and only when a reset context actually needs converting. convertedResetContext returns an empty array immediately for a null reset context, and the resulting byte[] is computed once in fetchSegmentsWithTokens and passed down.

Tests

New: PooledStreamingEventProcessorTest.ResetSupportTest.resetTokensWithoutResetContextDoesNotRequireAConverter, using SimpleUnitOfWorkFactory(EmptyApplicationContext.INSTANCE). It fails on unfixed code with the exception above. Full messaging module: green.

For the reviewer

Two effects of one change. Hoisting the conversion out of the per-segment lambda means a genuine missing-converter failure now surfaces once per reset instead of once per segment. Short-circuiting on a null reset context means the component lookup never happens at all for the common resetTokens() case. fetchTokenForSegment consequently loses its <R> type parameter and takes the already-converted byte[].

For a reset that carries a context the produced bytes are unchanged: every in-tree converter returns null for a null input, so the old null ? new byte[0] produced exactly what the short-circuit produces.

One behaviour does change, on zero initialized segments. Because the conversion moved ahead of fetchSegments, it now runs even when the per-segment lambda never would. A context-carrying reset on a processor whose tokens were never initialized used to succeed and invoke reset handlers; it now fails. Generalises to any ConversionException on an unserializable context with zero segments. Fail-fast is the better behaviour -- a reset that cannot serialize its context should not report success -- but it is a change, not a no-op.

Second effect: one byte[] instance is now shared by every segment's ReplayToken. Bytes are equal, so equality, storage and serialization are unaffected, but ReplayToken.resetContext():352 hands out the internal array, so a caller mutating it perturbs every segment's token in that reset rather than one. Pre-existing leak, newly wider; no mutation site exists in the tree.

@schananas
schananas requested a review from a team as a code owner July 29, 2026 11:30
@schananas
schananas requested review from MateuszNaKodach, hjohn and zambrovski and removed request for a team July 29, 2026 11:30
@schananas schananas self-assigned this Jul 29, 2026
`resetTokens()` resolved a `GeneralConverter` from the processing context unconditionally, once
per segment, so a processor whose unit-of-work factory supplies no components could not be reset
at all -- and failed with an error naming neither resets nor converters.

The converter is now resolved once, and only when a reset context actually needs converting, so
the no-context reset needs no components and a genuine missing-converter failure surfaces once
instead of once per segment.

Fixes #4796
@schananas
schananas force-pushed the bug/4796/reset-tokens-no-converter-when-no-context branch from 30e215e to a3517ed Compare July 29, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resetting a PooledStreamingEventProcessor requires a converter even when there is no reset context

1 participant