This is an automated email from the ASF dual-hosted git repository. He-Pin pushed a commit to branch fix/actor-selection-queue-distribution in repository https://gitbox.apache.org/repos/asf/pekko.git
commit 0fb44b4ba7985ea552b310ae582328967f42ce8a Author: 虎鸣 <[email protected]> AuthorDate: Fri Jun 19 20:17:58 2026 +0800 fix(artery): distribute ActorSelection messages across outbound lanes by target path Motivation: The ActorSelection send-consistency test flakes on CI: 4 sender actors each drive 1000 round-trips via ActorSelection. With multi-lane artery config (outbound-lanes > 1), all ActorSelection messages are routed to the same outbound queue because selectQueue uses the anchor's UID (root guardian, which is always 0) as the distribution key. This concentrates all ActorSelection traffic on a single lane while other lanes sit idle, creating a throughput bottleneck that causes timeouts under CI load. Modification: Add a dedicated case for ActorSelectionMessage (non-PriorityMessage) in Association.send that computes the queue index from the selection's target path elements hash instead of the anchor's UID. This distributes ActorSelection messages across lanes by their target path, while preserving per-path message ordering (same target path always hashes to the same lane). Result: ActorSelection messages are now distributed across all outbound lanes based on target path, eliminating the single-lane bottleneck. The existing ActorRef-based test and PriorityMessage (heartbeat) routing are unaffected. Tests: - sbt "remote / Test / compile" — compile check - CI will exercise the artery variants References: Refs #3041 (previous timeout widening), supersedes #3090 --- .../scala/org/apache/pekko/remote/artery/Association.scala | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/remote/src/main/scala/org/apache/pekko/remote/artery/Association.scala b/remote/src/main/scala/org/apache/pekko/remote/artery/Association.scala index eb9bf1176a..8082ef718d 100644 --- a/remote/src/main/scala/org/apache/pekko/remote/artery/Association.scala +++ b/remote/src/main/scala/org/apache/pekko/remote/artery/Association.scala @@ -436,6 +436,17 @@ private[remote] class Association( // so that the first message can be delivered after the remote actor has been created. if (!controlQueue.offer(outboundEnvelope)) dropped(ControlQueueIndex, controlQueueSize, outboundEnvelope) + case sel: ActorSelectionMessage => + // Distribute ActorSelection messages across lanes based on the target + // path hash rather than the anchor's (typically root guardian, UID=0). + // Without this, all ActorSelection messages concentrate on a single + // outbound lane, creating a throughput bottleneck. + val queueIndex = + if (outboundLanes == 1) OrdinaryQueueIndex + else OrdinaryQueueIndex + (math.abs(sel.elements.hashCode()) % outboundLanes) + val queue = queues(queueIndex) + if (!queue.offer(outboundEnvelope)) + dropped(queueIndex, queueSize, outboundEnvelope) case _ => val queueIndex = selectQueue(recipient) val queue = queues(queueIndex) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
