Last active
May 9, 2018 09:40
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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