Skip to content

Instantly share code, notes, and snippets.

@rhyskeepence
Last active May 9, 2018 09:40
Show Gist options
  • Save rhyskeepence/b575766c197f179e71c28e767ad490d9 to your computer and use it in GitHub Desktop.
Save rhyskeepence/b575766c197f179e71c28e767ad490d9 to your computer and use it in GitHub Desktop.
Demonstrate client connections are not freed within recursive calls to expect when a non-2xx status code is returned.
import cats.effect.IO
import cats.implicits._
import org.http4s.HttpService
import org.http4s.Method.{GET, POST}
import org.http4s.Uri.uri
import org.http4s.client.blaze.Http1Client
import org.http4s.client.middleware.Logger
import org.http4s.client.dsl.io._
import org.http4s.dsl.io._
import org.http4s.server.blaze.BlazeBuilder
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
object Foo extends App {
private val httpClient = Logger(true, true)(Http1Client[IO]().unsafeRunSync)
private val apiUrl = uri("http://localhost:8080")
private val statusCheckDelay = 1.millis
val apiService = HttpService[IO] {
case POST -> Root / "submit" => Ok("1234")
case GET -> Root / "status" => NotFound("not available yet")
case GET -> Root / "thing" => Ok("the thing")
}
BlazeBuilder[IO]
.bindHttp(8080, "0.0.0.0")
.mountService(apiService)
.serve.compile.last.unsafeRunAsync(_ => ())
fetch.unsafeRunSync()
private def fetch: IO[String] = for {
submitResponse <- submit()
status <- fetchTheThing(submitResponse, 50)
} yield status
private def submit() =
httpClient.expect[String](POST(apiUrl / "submit"))
private def fetchTheThing(submitResponse: String, maxRetries: Int): IO[String] = {
val response = httpClient.expect[String](GET(apiUrl / "status"))
response.attempt.flatMap({
case Right(_) =>
httpClient.expect[String](GET(apiUrl / "thing"))
case Left(_) =>
if (maxRetries > 0) IO(println("error, retrying")) *> IO.sleep(statusCheckDelay) *> fetchTheThing(submitResponse, maxRetries - 1)
else IO.raiseError(new Exception("unable to fetch status"))
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment