Skip to content

feat: add timeout duration to ReceiveTimeout message - #3399

Open
He-Pin wants to merge 4 commits into
mainfrom
feat/receive-timeout-with-duration
Open

feat: add timeout duration to ReceiveTimeout message#3399
He-Pin wants to merge 4 commits into
mainfrom
feat/receive-timeout-with-duration

Conversation

@He-Pin

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

Copy link
Copy Markdown
Member

Summary

  • Convert ReceiveTimeout from a case object singleton to a final case class ReceiveTimeout(timeout: FiniteDuration) so the message carries the configured timeout duration
  • Users can now access the timeout directly from the message handler: case timeout: ReceiveTimeout => log.info("timeout: {}", timeout.timeout)
  • Closes ReceiveTimeout contains no information #2569

Motivation

Previously ReceiveTimeout was a case object with no information, making it impossible to log or inspect the timeout value without separately accessing context.receiveTimeout. As noted in the issue, this made logging awkward:

case ReceiveTimeout timeout -> {
    log.info("SessionEntity [{}] receive timeout :[{}], will stop itself", timeout, getSelf().path());
    getContext().stop(getSelf());
}

Changes

  • actor/src/main/scala/.../Actor.scala: Convert ReceiveTimeout from case object to final case class with timeout: FiniteDuration field and Java API getTimeout method
  • actor/src/main/scala/.../dungeon/ReceiveTimeout.scala: Scheduler now sends ReceiveTimeout(timeout) instead of the singleton
  • All pattern matches: Updated from stable identifier patterns (case ReceiveTimeout =>) to type patterns (case _: ReceiveTimeout =>)
  • Java API: Updated from matchEquals(ReceiveTimeout.getInstance(), ...) to match(ReceiveTimeout.class, ...)
  • MiMa filters: Added binary compatibility exclusion for 2.0.x
  • Tests: Added new test verifying the timeout duration is carried correctly

Breaking changes (2.0)

  • ReceiveTimeout is no longer a singleton; pattern matches must use type patterns
  • ReceiveTimeout.getInstance() removed; Java users should use .match(ReceiveTimeout.class, ...)

Test plan

  • actor-tests/testOnly *.ReceiveTimeoutSpec — 15 tests pass (including new "carry the configured timeout duration" test)
  • actor-typed-tests/testOnly *.CancelReceiveTimeoutSpec — passes
  • All affected modules compile: actor, actor-typed, cluster, cluster-tools, cluster-sharding, distributed-data, persistence, docs

@He-Pin
He-Pin marked this pull request as draft July 29, 2026 18:28
He-Pin added 3 commits August 4, 2026 13:29
Motivation:
ReceiveTimeout was a case object singleton carrying no information about
the configured timeout duration, making it impossible to log or inspect
the timeout value from the message handler without accessing
context.receiveTimeout separately (#2569).

Modification:
Convert ReceiveTimeout from a case object to a final case class with a
`timeout: FiniteDuration` field. The scheduler now sends
ReceiveTimeout(duration) instead of the singleton. All pattern matches
updated from stable identifier patterns to type patterns. Java API
updated from matchEquals(getInstance()) to match(ReceiveTimeout.class).

Result:
Users can now access the timeout duration directly from the message:
  case timeout: ReceiveTimeout => log.info("timeout: {}", timeout.timeout)
Apply code formatting and update MiMa exclusion filters to match the
exact binary compatibility problems reported by CI.
Motivation:
The Binary Compatibility CI job failed on the Scala 3 lane: converting
ReceiveTimeout from case object to case class produced three unfiltered
problems for pekko-actor_3 (fromProduct result type, productElementNames
and productIterator generic signatures). The new Java API getTimeout also
lacked test coverage.

Modification:
Add the three Scala 3 MiMa exclusion filters reported by CI and assert
getTimeout in the ReceiveTimeoutSpec timeout-duration test.

Result:
MiMa passes on both Scala 2.13 and Scala 3 and the Java API is covered.

Tests:
- sbt "actor-tests / Test / testOnly org.apache.pekko.actor.ReceiveTimeoutSpec" - 15 tests pass
- sbt "++2.13.18!" "actor/mimaReportBinaryIssues" "++3.3.8!" "actor/mimaReportBinaryIssues" - pass
- sbt checkMimaFilterDirectories - pass

References:
Refs #2569
@He-Pin
He-Pin force-pushed the feat/receive-timeout-with-duration branch from e360324 to 1ca0652 Compare August 4, 2026 05:29
@He-Pin
He-Pin marked this pull request as ready for review August 4, 2026 06:18
@He-Pin He-Pin added this to the 2.0.0-M4 milestone Aug 4, 2026
@He-Pin
He-Pin requested a review from pjfanning August 4, 2026 06:19
Comment thread actor/src/main/scala/org/apache/pekko/actor/Actor.scala Outdated
Motivation:
Address review feedback on #3399 to use the standard Scala/Java duration
conversion, and document the ReceiveTimeout breaking change for 2.x users.

Modification:
- Replace java.time.Duration.ofNanos(timeout.toNanos) with timeout.toJava
  via scala.jdk.DurationConverters in Actor.scala
- Add a ReceiveTimeout entry to migration-guide-1.x-2.x.md

Result:
The Java API conversion follows the established codebase convention and
the 2.x migration guide documents the pattern matching and getInstance
breaking changes.

Tests:
- sbt "actor-tests / Test / testOnly org.apache.pekko.actor.ReceiveTimeoutSpec" - 15 tests passed
- sbt "actor-typed-tests / Test / testOnly org.apache.pekko.actor.typed.CancelReceiveTimeoutSpec" - passed
- sbt actor/mimaReportBinaryIssues - no issues
- scalafmt --mode diff-ref=origin/main - no extra changes
- git diff --check - clean

References:
Refs #3399
@He-Pin
He-Pin requested a review from pjfanning August 4, 2026 17:15
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.

ReceiveTimeout contains no information

2 participants