Skip to content

Instantly share code, notes, and snippets.

@ChristopherDavenport
Created August 11, 2021 23:12
Show Gist options
  • Save ChristopherDavenport/c089f842952aac10fd5f3f555e43b499 to your computer and use it in GitHub Desktop.
Save ChristopherDavenport/c089f842952aac10fd5f3f555e43b499 to your computer and use it in GitHub Desktop.
This is what we can use to fix EndOfStream errors for ember
object EmberRetryFix {
import cats.syntax.all._
import scala.concurrent.duration._
import org.http4s._
import org.http4s.client._
import org.http4s.ember.core.EmberException
import org.http4s.client.middleware._
import org.http4s.headers.`Idempotency-Key`
def fixIt[F[_]: Temporal](emberClient: Client[F]): Client[F] = Retry(retryUntilFresh)(emberClient)
private val retryNow = 0.seconds.some
def retryUntilFresh[F[_]]: RetryPolicy[F] = {(req, result, retries) =>
if (emberDeadFromPoolPolicy(req, result)) retryNow
else None
}
def emberDeadFromPoolPolicy[F[_]](req: Request[F], result: Either[Throwable, Response[F]]): Boolean =
(req.method.isIdempotent || req.headers.get[`Idempotency-Key`].isDefined) &&
isEmptyStreamError(result)
def isEmptyStreamError[F[_]](result: Either[Throwable, Response[F]]): Boolean =
result match {
case Right(resp) => false
// case Left(EmberException.EmptyStream()) => true // Next version
case Left(org.http4s.ember.core.Parser.MessageP.EndOfStreamError()) => true
case _ => false
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment