Skip to content

Commit 0d1858c

Browse files
committed
fix: CachingResolver falls back to stale addresses when refresh fails
The stale-while-revalidate logic in CachingResolver#resolve discarded previousAddresses when the refresh promise completed with a failure, propagating UnknownHostException instead of returning the cached addresses. Use orElseSucceed to fall back to the previous addresses when the refreshed resolution fails.
1 parent f9b8d36 commit 0d1858c

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

zio-http/jvm/src/test/scala/zio/http/DnsResolverSpec.scala

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,38 @@ object DnsResolverSpec extends ZIOHttpSpec {
130130
implementation = TestResolver(),
131131
),
132132
),
133+
test("resolve returns previous addresses when refresh fails") {
134+
for {
135+
failing <- Ref.make(false)
136+
failSignal <- Promise.make[Nothing, Unit]
137+
result <- {
138+
val impl = new DnsResolver {
139+
override def resolve(host: String)(implicit trace: Trace): ZIO[Any, UnknownHostException, Chunk[InetAddress]] =
140+
failing.get.flatMap {
141+
case true => failSignal.succeed(()) *> ZIO.fail(new UnknownHostException(host))
142+
case false => ZIO.succeed(Chunk(InetAddress.getByAddress(Array(127, 0, 0, host.stripPrefix("host").toByte))))
143+
}
144+
}
145+
(for {
146+
_ <- DnsResolver.resolve("host1")
147+
_ <- failing.set(true)
148+
_ <- TestClock.adjust(15.seconds)
149+
_ <- failSignal.await
150+
result <- DnsResolver.resolve("host1")
151+
} yield result).provide(
152+
DnsResolver.explicit(
153+
ttl = 10.seconds,
154+
unknownHostTtl = 10.seconds,
155+
refreshRate = 1.second,
156+
expireAction = ExpireAction.Refresh,
157+
implementation = impl,
158+
),
159+
)
160+
}
161+
} yield assertTrue(
162+
result.map(_.toString) == Chunk("/127.0.0.1"),
163+
)
164+
},
133165
)
134166

135167
private def stringSnapshot(): ZIO[DnsResolver, Nothing, Set[String]] =

zio-http/shared/src/main/scala/zio/http/DnsResolver.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ object DnsResolver {
8383
case Some(previous) =>
8484
(
8585
ZIO.ifZIO(entry.resolvedAddresses.isDone)(
86-
onTrue = entry.resolvedAddresses.await,
86+
onTrue = entry.resolvedAddresses.await.orElseSucceed(previous),
8787
onFalse = ZIO.succeed(previous),
8888
),
8989
entries,

0 commit comments

Comments
 (0)