Skip to content

Avoid receive timeout type pollution#3332

Open
He-Pin wants to merge 4 commits into
apache:mainfrom
He-Pin:perf/1668-actor-receive-timeout
Open

Avoid receive timeout type pollution#3332
He-Pin wants to merge 4 commits into
apache:mainfrom
He-Pin:perf/1668-actor-receive-timeout

Conversation

@He-Pin

@He-Pin He-Pin commented Jul 11, 2026

Copy link
Copy Markdown
Member

Motivation

Identify implements both AutoReceivedMessage and NotInfluenceReceiveTimeout. On JVMs affected by JDK-8180450, alternating successful checks against those two secondary supertypes makes the same concrete Klass secondary-super cache ping-pong between marker types. The checks occur on the Actor receive-timeout path and can contend across actor-dispatcher threads.

The receive path also classified the same message against NotInfluenceReceiveTimeout twice.

Modification

  • Classify final Identify with a concrete-class guard before the NotInfluenceReceiveTimeout marker check.
  • Return the pre-cancellation timeout state and infer the post-receive reschedule decision from the state transition, removing the second marker check.
  • Add focused classification coverage.
  • Add a 12-thread JMH benchmark for the polluted, concrete-guarded, and final production-shaped paths.

Result

Receive-timeout behavior remains unchanged, while Identify no longer alternates the concrete class secondary-super cache between its two marker interfaces. The final path also performs one classification instead of two.

JMH throughput (ops/us, 12 threads, 3 forks, 5 x 1 s warmup and measurement iterations):

Runtime Polluted path Concrete guard Final path Final / polluted
JDK 17.0.17 824.700 +/- 10.066 1633.766 +/- 53.719 2205.529 +/- 92.313 2.67x
JDK 21.0.8 1125.827 +/- 16.496 1609.084 +/- 31.694 2158.924 +/- 36.895 1.92x
JDK 25.0.2 1717.703 +/- 77.349 1841.141 +/- 53.279 2467.700 +/- 262.562 1.44x

JDK 21.0.8 and JDK 25 contain the JVM fix, so their remaining gain primarily measures the removed classification/call rather than secondary-super-cache contention. The JDK 25 result was noisier than the other runs.

References

Refs #1668

@He-Pin He-Pin added this to the 2.0.0-M4 milestone Jul 12, 2026
@He-Pin
He-Pin requested a review from pjfanning July 12, 2026 04:42
@He-Pin
He-Pin force-pushed the perf/1668-actor-receive-timeout branch 2 times, most recently from 3838449 to 8ce7dbc Compare July 14, 2026 04:11
@He-Pin He-Pin modified the milestone: 2.0.0-M4 Jul 14, 2026
import scala.concurrent.Await
import scala.concurrent.duration._

import org.apache.pekko.actor.dungeon.{ ReceiveTimeout => ReceiveTimeoutSupport }

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.

can you rebase and fix the imports to be pekko.?

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.

I pushed a fix for this


// Identify is also an AutoReceivedMessage. Checking its concrete class first avoids polluting its secondary
// supertype cache on JDKs affected by JDK-8180450 when actor runtime code also checks the AutoReceivedMessage marker.
@inline def isNotInfluenceReceiveTimeout(message: Any): Boolean =

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.

@inline doesn't work for Scala 3. You might need to create a Scala 2 and Scala 3 file with just this method. Better than copy/pasting this whole scala file.

He-Pin added 2 commits July 20, 2026 11:39
Motivation:
The ActorCell receive timeout path allocates on every message
and misclassifies timer messages, causing unnecessary timeout
rescheduling and state churn.

Modification:
- Avoid type pollution in the receive timeout hot path
- Guard timer receive timeout classification

Result:
Reduced allocations and correct timeout behavior for actors
using receive timeouts.

Tests:
- Existing ActorCellReceiveTimeoutSpec

References:
Refs apache#1668
Motivation:
The @inline annotation does not work for Scala 3. The JVM JIT will inline
this small method regardless of the annotation.

Modification:
Remove the @inline annotation from isNotInfluenceReceiveTimeout method.

Result:
Code compiles cleanly on both Scala 2.13 and Scala 3. Performance is
unaffected as the JIT compiler will still inline the method.

Tests:
Not run - annotation removal only, no behavior change

References:
Refs apache#3332
@He-Pin
He-Pin force-pushed the perf/1668-actor-receive-timeout branch from 3495f33 to 944ff2e Compare July 20, 2026 03:59
He-Pin added 2 commits July 20, 2026 12:58
Motivation:
The @inline annotation does not work for Scala 3. Reviewer requested
splitting the method into version-specific files to preserve the inline
optimization for Scala 2 while supporting Scala 3.

Modification:
- Create ReceiveTimeoutCompat object in scala-2.13 with @inline annotation
- Create ReceiveTimeoutCompat object in scala-3 with inline keyword
- Move isNotInfluenceReceiveTimeout method from ReceiveTimeout to ReceiveTimeoutCompat
- Update all call sites to use ReceiveTimeoutCompat

Result:
Code compiles cleanly on both Scala 2.13 and Scala 3 with appropriate
inline optimizations for each version.

Tests:
sbt "actor-tests/Test/testOnly org.apache.pekko.actor.ReceiveTimeoutSpec"
All 14 tests passed.

References:
Refs apache#3332
Motivation:
The isNotInfluenceReceiveTimeout method was moved from ReceiveTimeout to
ReceiveTimeoutCompat in the version-specific files, but two call sites
still referenced the old location, causing compilation failures across
all CI jobs.

Modification:
Update TimerSchedulerImpl (actor-typed) and ReceiveTimeoutTypePollutionBenchmark
(bench-jmh) to reference ReceiveTimeoutCompat.isNotInfluenceReceiveTimeout.

Result:
All modules compile successfully on both Scala 2.13 and Scala 3.

Tests:
- sbt "actor-typed / Compile / compileIncremental" (Scala 2.13) - success
- sbt "++3.3.8; actor-typed / Compile / compileIncremental" - success

References:
Refs apache#3332
@He-Pin
He-Pin requested a review from pjfanning July 20, 2026 06:24
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.

2 participants