Skip to content

Instantly share code, notes, and snippets.

@gatorcse
Last active July 1, 2020 22:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gatorcse/b39cfa6ae70551ccd197fea1d581cdb5 to your computer and use it in GitHub Desktop.
Save gatorcse/b39cfa6ae70551ccd197fea1d581cdb5 to your computer and use it in GitHub Desktop.
Ember combined with Natchez hangs on large responses.
package emberbroken
import cats._
import cats.data.Kleisli
import cats.implicits._
import cats.effect._
import cats.effect.implicits._
import natchez.{EntryPoint, Span, Trace}
import org.http4s._
import org.http4s.client.blaze.BlazeClientBuilder
import org.http4s.implicits._
//import org.http4s.client.blaze.BlazeClientBuilder
import org.http4s.ember.client.EmberClientBuilder
import scala.concurrent.ExecutionContext
object EmberBroken extends IOApp {
// This one will work fine
// override def run(args: List[String]): IO[ExitCode] = runIO
// This one will log all of the response text, but then hang at the end
override def run(args: List[String]): IO[ExitCode] = runTraced
def runIO = runF[IO]
def runTraced = entryPoint[IO].use { ep =>
ep.root("Testing Ember App").use { root =>
runF[Kleisli[IO, Span[IO], *]].run(root)
}
}
def runF[F[_]: Concurrent: Timer: ContextShift]: F[ExitCode] =
EmberClientBuilder.default[F].build
.use { c =>
c.get((uri"https://baconipsum.com/api/")
.withQueryParam("type", "meat-and-filler")
.withQueryParam("paras", "100") // Set this to something small and it works
.withQueryParam("format", "text")
) {
res => Sync[F].delay { println("Got a response") } *>
res.bodyText.evalTap(text => Sync[F].delay { println(s"Got Some text: $text")}).compile.drain // The entire response is processed, every time.
}
.flatTap(_ => Sync[F].delay { println("fetched") }) // This is never reached when using tracing AND a the response body is more than one chunk.
.as(ExitCode.Success)
}
def entryPoint[F[_]: Sync]: Resource[F, EntryPoint[F]] = {
import natchez.jaeger.Jaeger
import io.jaegertracing.Configuration.SamplerConfiguration
import io.jaegertracing.Configuration.ReporterConfiguration
Jaeger.entryPoint[F]("natchez-example") { c =>
Sync[F].delay {
c.withSampler(SamplerConfiguration.fromEnv)
.withReporter(ReporterConfiguration.fromEnv)
.getTracer
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment