Skip to content

fix(agent): follow primitive streams and the bridges to them in a parallel pipeline (#1172) - #1225

Merged
PIsberg merged 1 commit into
mainfrom
fix/1172-primitive-stream-pipelines
Nov 8, 2026
Merged

PIsberg merged 1 commit into
mainfrom
fix/1172-primitive-stream-pipelines

Conversation

@PIsberg

@PIsberg PIsberg commented Nov 8, 2026

Copy link
Copy Markdown
Owner

Partly addresses #1172. The forms still not followed stay there (narrowed in a comment on the issue).

Why

#1209 followed a reference Stream's map, filter and peek lambdas to the common pool's workers. A primitive stream's were still unattributed, and so was any lambda behind mapToInt. list.parallelStream().mapToInt(...).sum() is the usual way to total in parallel, and a plain counter inside its lambda was seen only on the caller's own elements, so the race drew nothing reliable.

What changed

  • IntStream, LongStream and DoubleStream get the Stream treatment. map, filter, peek and mapToObj wait in a slot. The terminal operations (forEachOrdered, reduce, collect, the matches, sum, count, average, min, max, summaryStatistics, toArray, the finds) lend the run to every slot while they run. As before, a reduce operator and a collect combiner run as combines.
  • The pipeline map is keyed by BaseStream, so the slots follow a pipeline across Stream.mapToInt/mapToLong/mapToDouble, a primitive stream's mapToObj and boxed. boxed adds no slot of its own and only carries the slots behind it.
  • The three primitive forEach hooks now go through the same parallelTerminal, so a forEach ending a primitive pipeline lends the run to its map lambdas too.
  • 66 new public static hooks on AgentConcurrencyUtilHooks, all additive and tagged @since 1.14.2, with 66 matching rows in CollectionAccessWeaver.

How it was verified

  • Tests first: six new cases in AgentParallelStreamHooksTest failed to compile on the 59 missing hooks. All 19 cases in the class pass now. Turning off the mapToInt hook made two of them fail (aLambdaStaysLentAcrossTheBridges, theCallerIsOrderedAfterAMapToIntLambda), and they passed again once it was restored.
  • The test class now starts a telemetry drain for each test. Without one, the event ring filled after a few thousand helper task events, and every later event waited out the ring's one-second give-up. The class hung for over 15 minutes (thread dump: a pool worker spinning in TelemetryEventBuffer.publish). With the drain it runs in about 17 s.
  • Corpus, through the real agent: four new idioms. parallelIntMap_plainCounter and parallelMapToInt_plainCounter are MUST_FIRE; their locked twins are MUST_STAY_SILENT. The idiom lane passed 86/86 and every other lane is green. The new MUST_FIRE rows were not run against the old jar. Their red-before evidence is the unit test mutation above.
  • Library suite 3963 and agent suite 117 green (-P fast, JDK 26). The static gate chain (mvn install -DskipTests -Djacoco.skip=true) is green.

Docs

docs/CHANGELOG.md (extended the #1172 entry under Unreleased), docs/agent/limitations.md and docs/analysis/corpus-eval-future-improvements.md. All three named primitive map/filter and mapToInt as unfollowed; they now list what is still unfollowed. No VibeTags guardrail was added. The hooks class already carries its contract-frozen rule, which covers the new hooks, and no new external contract or security boundary was introduced.

Checklist

  • A behaviour change ships with a test that fails without the fix
  • A new or changed detector is tested against the buggy code and its correctly synchronized twin (no detector changed; the corpus pairs cover both directions of the feed)
  • Docs the change makes wrong are updated in this same change
  • Nothing was hand-edited between VIBETAGS-START / VIBETAGS-END markers
  • Public API changes are intentional and carry the right version bump: 66 additive hooks, @since 1.14.2
  • Commits an agent authored carry the Co-Authored-By trailer
  • A new dependency was proposed with a reason (none added)
  • CI is green, or the failure is explained below

Still not followed (tracked in #1172)

A stage behind sorted, distinct, limit, skip or flatMap, a pipeline ended by iterator() or in unwoven code, and a Collector's own functions.

🤖 Generated with Claude Code

…allel pipeline (#1172)

#1209 followed a reference Stream's map, filter and peek lambdas to the
common pool's workers, but a primitive stream's were still unattributed,
and so was any lambda behind mapToInt. list.parallelStream().mapToInt(...)
.sum() is the usual way to total in parallel, and a plain counter inside
its lambda was seen only on the caller's own elements.

IntStream, LongStream and DoubleStream now get the Stream treatment: map,
filter, peek and mapToObj wait in a slot, and the terminal operations
(forEachOrdered, reduce, collect, the matches, sum, count, average, min,
max, summaryStatistics, toArray, the finds) lend the run to every slot
while they run. The pipeline map is keyed by BaseStream, so the slots
follow a pipeline across Stream.mapToInt/mapToLong/mapToDouble, mapToObj
and boxed. The three primitive forEach hooks now share parallelTerminal.

Tests first: six new cases in AgentParallelStreamHooksTest failed to
compile on the 59 missing hooks; all 19 pass. Disabling the mapToInt hook
turns two of them red. The class now runs a telemetry drain per test:
without one the ring filled and every later task event waited out the
ring's one-second give-up, which hung the class for over 15 minutes.

Corpus: four idioms, IntStream.map and Stream.mapToInt counters with and
without a lock; idiom lane 86/86, every lane green. Library 3963 and agent
117 tests green, static gate chain green.

Still not followed: a stage behind sorted, distinct, limit, skip or
flatMap, a pipeline ended by iterator(), and a Collector's own functions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Nov 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 79.41176% with 56 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...deversity/asynctest/AgentConcurrencyUtilHooks.java 72.81% 18 Missing and 38 partials ⚠️

📢 Thoughts on this report? Let us know!

@PIsberg
PIsberg merged commit 592a3d2 into main Nov 8, 2026
53 checks passed
@PIsberg
PIsberg deleted the fix/1172-primitive-stream-pipelines branch November 8, 2026 15:47
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.

1 participant