2

I need to stream fs2.Queue - some events to single http client.

import cats.effect._
import org.http4s._
import org.http4s.dsl.io._
import org.http4s.server.Router
import org.http4s.server.blaze.BlazeServerBuilder
import org.http4s.syntax.kleisli._

import scala.concurrent.ExecutionContext
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt

object StreamingHttp4sFs2Server2 extends App {

  implicit val timer: Timer[IO] = IO.timer(global)
  implicit val cs: ContextShift[IO] = IO.contextShift(global)

  (for {
    queue <- fs2.concurrent.Queue.unbounded[IO, Long]
    _ <- IO {
      fs2.Stream.awakeEvery[IO](1.seconds).map(_.toSeconds)
        .through(queue.enqueue)
        .compile.drain
        .unsafeRunAsyncAndForget()
    }
    _ <- BlazeServerBuilder[IO](ExecutionContext.global)
      .bindHttp(8080, "localhost")
      .withHttpApp(Router("/" -> HttpRoutes.of[IO] {
        case GET -> Root => Ok(queue.dequeue.map(_.toString + "\n"))
      }).orNotFound)
      .serve
      .compile
      .drain
  } yield ()).unsafeRunAsyncAndForget()
}

Sometimes client disconnects, and some events loosing with error Error writing body.

You can reproduce problem with curl:

curl --no-buffer -X GET http://localhost:8080/
1
2
3
4
5
^C //hit ctrl+c, 
curl --no-buffer -X GET http://localhost:8080/
8
9
10

How to implement something without loosing events when client disconnects?

zella
  • 4,645
  • 6
  • 35
  • 60

0 Answers0