This is an automated email from the ASF dual-hosted git repository.
He-Pin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko.git
The following commit(s) were added to refs/heads/main by this push:
new 83e6875962 test: cover clearing of failed in-flight DNS requests so
they can be retried (#3549)
83e6875962 is described below
commit 83e68759626f7d32feac8d31dd41e28898533283
Author: PJ Fanning <[email protected]>
AuthorDate: Fri Oct 9 08:38:39 2026 +0100
test: cover clearing of failed in-flight DNS requests so they can be
retried (#3549)
Motivation:
Port of the test from akka/akka-core#32114 (backport of akka/akka#32110),
which covers `AsyncDnsResolver` clearing a failed resolution from its in-flight
map so that a later resolve of the same name is retried rather than blocked.
Pekko's resolver already behaves this way - the `ResolutionAnswer` handler
fans a failure out to every waiter and removes the in-flight entry - so no
main-code change is needed, but this scenario had no regression test.
Modification:
Add an `AsyncDnsResolverSpec` case: two senders resolve the same name, the
second joins the in-flight resolution (no second question is sent), the DNS
client replies with a failure, both senders receive `Status.Failure`, and a
subsequent resolve from both senders is sent to the client again and succeeds.
The Akka test relies on a 1 ms `resolve-timeout` and an autopilot that
ignores the first question. This port drives the client `TestProbe` explicitly
instead (same style as the existing "reuse in-progress resolutions" case) so it
has no timing dependency.
Result:
The retry-after-failure behaviour of `AsyncDnsResolver` is covered by a
test. No main-code change.
Tests:
- `sbt "actor-tests/testOnly
org.apache.pekko.io.dns.internal.AsyncDnsResolverSpec"` - 22 passed, run 3 times
- native scalafmt run on the changed file
References:
None - port of the test from akka/akka-core#32114. Akka source is
Apache-2.0 licensed as of 2023-09-20.
---
.../io/dns/internal/AsyncDnsResolverSpec.scala | 42 ++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git
a/actor-tests/src/test/scala/org/apache/pekko/io/dns/internal/AsyncDnsResolverSpec.scala
b/actor-tests/src/test/scala/org/apache/pekko/io/dns/internal/AsyncDnsResolverSpec.scala
index 1f520a6d65..997410d031 100644
---
a/actor-tests/src/test/scala/org/apache/pekko/io/dns/internal/AsyncDnsResolverSpec.scala
+++
b/actor-tests/src/test/scala/org/apache/pekko/io/dns/internal/AsyncDnsResolverSpec.scala
@@ -446,6 +446,48 @@ class AsyncDnsResolverSpec extends PekkoSpec("""
asker1.expectMsg(Resolved("cats.com", im.Seq.empty))
asker2.expectMsg(Resolved("cats.com", im.Seq.empty))
}
+
+ "clear failed in-flight requests so they can be retried" in new Setup {
+ val firstSender = TestProbe()
+ val secondSender = TestProbe()
+
+ val ipv4Record = ARecord("cats.com", Ttl.fromPositive(1.minute),
InetAddress.getByName("127.0.0.1"))
+
+ override val r = resolver(List(dnsClient1.ref), defaultConfig)
+
+ def requestFrom(sendingProbe: TestProbe): Unit =
+ r.tell(Resolve(ipv4Record.name, Ip(ipv4 = true, ipv6 = false)),
sendingProbe.ref)
+
+ requestFrom(firstSender)
+ requestFrom(secondSender)
+
+ val firstQuestion = dnsClient1.expectMsgPF() {
+ case q: Question4 if q.name == ipv4Record.name => q
+ }
+ // the second resolve joins the in-flight one, so no second question is
sent
+ dnsClient1.expectNoMessage(50.millis)
+ dnsClient1.reply(Failure(new RuntimeException("Nope")))
+
+ firstSender.expectMsgType[Failure]
+ secondSender.expectMsgType[Failure]
+
+ dnsClient1.expectMsgPF() {
+ case DropRequest(dropped) if dropped == firstQuestion =>
+ }
+ dnsClient1.reply(Dropped(firstQuestion.id))
+
+ // if at first you don't succeed...
+ requestFrom(firstSender)
+ requestFrom(secondSender)
+
+ val secondQuestion = dnsClient1.expectMsgPF() {
+ case q: Question4 if q.name == ipv4Record.name => q
+ }
+ dnsClient1.reply(Answer(secondQuestion.id, im.Seq(ipv4Record)))
+
+ firstSender.expectMsg(Resolved(ipv4Record.name, im.Seq(ipv4Record)))
+ secondSender.expectMsg(Resolved(ipv4Record.name, im.Seq(ipv4Record)))
+ }
}
private def deterministicIds(ids: Short*): IdGenerator = new IdGenerator {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]