Skip to content

Commit f993c12

Browse files
authored
Merge pull request #71 from maginepro/container-endpoint-retries
Use `Retry` middleware for `CredentialsProvider.containerEndpoint`
2 parents 4d89ced + 4bb1ad7 commit f993c12

2 files changed

Lines changed: 15 additions & 8 deletions

File tree

build.sbt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ inThisBuild(
4040
ProblemFilters.exclude[DirectMissingMethodProblem]("com.magine.http4s.aws.AwsPresigning.apply"),
4141
ProblemFilters.exclude[DirectMissingMethodProblem]("com.magine.http4s.aws.AwsSigning.signRequest"),
4242
ProblemFilters.exclude[IncompatibleMethTypeProblem]("com.magine.http4s.aws.CredentialsProvider.credentialsFile"),
43-
ProblemFilters.exclude[IncompatibleMethTypeProblem]("com.magine.http4s.aws.TokenCodeProvider.default")
43+
ProblemFilters.exclude[IncompatibleMethTypeProblem]("com.magine.http4s.aws.TokenCodeProvider.default"),
44+
ProblemFilters.exclude[DirectMissingMethodProblem]("com.magine.http4s.aws.CredentialsProvider.com$magine$http4s$aws$CredentialsProvider$$requestCredentials$default$2$1"),
45+
ProblemFilters.exclude[DirectMissingMethodProblem]("com.magine.http4s.aws.CredentialsProvider.com$magine$http4s$aws$CredentialsProvider$$$_$requestCredentials$default$2$1")
4446
// format: on
4547
)
4648
},

modules/core/shared/src/main/scala/com/magine/http4s/aws/CredentialsProvider.scala

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ import org.http4s.Method
4949
import org.http4s.Request
5050
import org.http4s.Uri
5151
import org.http4s.client.Client
52+
import org.http4s.client.middleware.Retry
53+
import org.http4s.client.middleware.RetryPolicy
5254
import org.typelevel.ci.*
5355
import scala.annotation.nowarn
5456
import scala.concurrent.duration.*
@@ -147,8 +149,14 @@ object CredentialsProvider {
147149
* active credentials available, it will continue to return the
148150
* active credentials while trying to refresh, until the
149151
* credentials expire in 1 minute or less.
152+
*
153+
* There is a retry policy in place to avoid intermittent
154+
* issues when requesting credentials.
150155
*/
151156
def containerEndpoint[F[_]: Async](client: Client[F]): Resource[F, CredentialsProvider[F]] = {
157+
val retryClient: Client[F] =
158+
Retry(RetryPolicy(RetryPolicy.exponentialBackoff(maxWait = 3.seconds, maxRetry = 5)))(client)
159+
152160
def credentialsUri: F[Uri] =
153161
for {
154162
path <- ContainerCredentialsRelativeUri[F].read
@@ -173,7 +181,7 @@ object CredentialsProvider {
173181
.map(_.trim)
174182
.map(Header.Raw(ci"Authorization", _))
175183

176-
def requestCredentials(retryAttempts: Int = 0, maxRetries: Int = 5): F[ExpiringCredentials] =
184+
def requestCredentials: F[ExpiringCredentials] =
177185
for {
178186
uri <- credentialsUri
179187
authorizationTokenFile <- ContainerAuthorizationTokenFile[F].read
@@ -182,10 +190,7 @@ object CredentialsProvider {
182190
authorizationToken = ContainerAuthorizationToken[F].read
183191
authorization <- authorizationTokenFile.getOrElse(authorizationToken)
184192
request = Request[F](Method.GET, uri).withHeaders(authorization)
185-
expiring <- client.expect[ExpiringCredentials](request).recoverWith {
186-
case _ if retryAttempts < maxRetries =>
187-
requestCredentials(retryAttempts + 1)
188-
}
193+
expiring <- retryClient.expect[ExpiringCredentials](request)
189194
} yield expiring
190195

191196
def sleepUntilRefresh(ref: Ref[F, Either[Throwable, ExpiringCredentials]]): F[Unit] =
@@ -203,7 +208,7 @@ object CredentialsProvider {
203208
def refreshCredentials(ref: Ref[F, Either[Throwable, ExpiringCredentials]]): F[Unit] =
204209
for {
205210
_ <- sleepUntilRefresh(ref)
206-
credentials <- requestCredentials().attempt
211+
credentials <- requestCredentials.attempt
207212
now <- Async[F].realTime.map(d => Instant.EPOCH.plusNanos(d.toNanos))
208213
_ <- ref.update {
209214
case right @ Right(existing) if credentials.isLeft && existing.isFresh(now) => right
@@ -212,7 +217,7 @@ object CredentialsProvider {
212217
} yield ()
213218

214219
for {
215-
credentials <- requestCredentials().attempt.toResource
220+
credentials <- requestCredentials.attempt.toResource
216221
ref <- Ref[F].of(credentials).toResource
217222
_ <- refreshCredentials(ref).foreverM[Unit].background
218223
} yield new CredentialsProvider[F] {

0 commit comments

Comments
 (0)