-
-
Notifications
You must be signed in to change notification settings - Fork 250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Connection leak with http4s websocket subscriptions #2123
Comments
Hi @enriquerodbe, thanks for reporting this issue! I'm guessing since that you used |
Thanks for the quick response! I'm testing manually with a UI client so I can try both. I just realized I was using a legacy protocol, but it seems that the outcome is the same. Just to be sure, the way to use the new protocol is to send header |
Confirmed with the newer protocol using |
@enriquerodbe Yeap that's the correct way. OK I'll take a look at what might be happening. Just to make sure that I replicate it correctly, do you use some specific automated / semi-automated way to identify that the connections aren't being closed or do you just open a bunch and close them manually? |
My method is pretty rudimentary 😆 I just set blaze server |
@enriquerodbe I think the issue you're facing might be related to this recent fix in "dev.zio" %% "zio-interop-cats" % "2.1.0.1" |
Re-opening until fix is confirmed |
It did not work for me. I notice you consistently write |
I minimized my problem to this: package ws_test
import caliban.*
import caliban.interop.cats.implicits.*
import caliban.interop.tapir.WebSocketInterpreter
import caliban.schema.Schema
import cats.effect.std.Dispatcher
import cats.effect.{IO, IOApp, Resource}
import org.http4s.blaze.server.BlazeServerBuilder
import org.http4s.server.{Router, Server}
import sttp.tapir.json.circe.*
import zio.Runtime
import zio.stream.interop.fs2z.*
import zio.stream.{Stream, ZStream}
object Main extends IOApp.Simple {
private final case class Subscription(test: Stream[Throwable, String])
private final case class Query(test: String = "test query")
private final case class Mutation(test: String = "test mutation")
override def run: IO[Unit] = {
given Runtime[Any] = Runtime.default
val resource = for {
given Dispatcher[IO] <- Dispatcher.parallel[IO]
interpreter <- Resource.eval(buildInterpreter)
server <- buildBlazeServer(interpreter)
} yield server
resource.useForever
}
private def buildInterpreter(using Runtime[Any]): IO[GraphQLInterpreter[Any, CalibanError]] = {
given Schema[Any, Subscription] = Schema.gen
given Schema[Any, Query] = Schema.gen
given Schema[Any, Mutation] = Schema.gen
val query = Query()
val mutation = Mutation()
val subscription = Subscription(ZStream("test1", "test2"))
graphQL(RootResolver(query, mutation, subscription)).interpreterAsync[IO]
}
private def buildBlazeServer(
interpreter: GraphQLInterpreter[Any, CalibanError]
)(using Dispatcher[IO], Runtime[Any]): Resource[IO, Server] =
BlazeServerBuilder[IO]
.bindHttp(port = 8088, host = "0.0.0.0")
.withHttpWebSocketApp { wsBuilder =>
Router(
"ws" -> Http4sAdapter.makeWebSocketServiceF(wsBuilder, WebSocketInterpreter(interpreter))
).orNotFound
}
.withMaxConnections(1)
.resource
} And this name := "blaze-caliban"
scalaVersion := "3.3.1"
fork := true
libraryDependencies ++= Seq(
"org.http4s" %% "http4s-blaze-server" % "0.23.16",
"com.github.ghostdogpr" %% "caliban-http4s" % "2.5.2",
"com.softwaremill.sttp.tapir" %% "tapir-json-circe" % "1.9.6",
"ch.qos.logback" % "logback-classic" % "1.4.14"
)
dependencyOverrides += "dev.zio" %% "zio-interop-cats" % "23.1.0.1" To reproduce the steps are:
|
My workaround was to switch to ember. It seems to be an issue with blaze. |
Since it works with Ember, it is likely to be an issue with Blaze so I'm closing this. |
Hi!
I have a cats-effect app with http4s blaze server and Caliban. This is a simplified version of how I instantiate the server:
Everything more or less like it's described in the documentation.
The problem is that when a client subscribes using a websocket connection, then the connection resource is never released, even when the client sends a
"type": "stop"
graphql message and a close message to the websocket channel.When the server accepts enough connections and reaches the
maxConnections
limit, it stops accepting more connections, even when the rest are all idle (and even when clients explicitly tried to close the connection).The text was updated successfully, but these errors were encountered: