ghostdogpr / caliban

Functional GraphQL library for Scala

Home Page:https://ghostdogpr.github.io/caliban/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`@defer` fields not working as expected when backed by `DataSource`s

kyri-petrou opened this issue · comments

As the title says, there seems to be an issue affecting @deferfields under some specific conditions. Let's say we have the following schema:

  case class Bar(
    value: UQuery[String] // Backed by a datasource
  )
  case class Foo(bar: UIO[List[Bar]])
  case class Query(foo: UIO[Foo])

And I want to execute the following query:

foo {
  bar { ... @defer { value } }
}

This works fine as long as no item in the list makes a request to the datasource that requires deduplication. e.g.,

  case class Req(i: Int) extends Request[Nothing, String]
  val ds = DataSource.fromFunctionZIO("ValuesDS") { (_: Req) =>
    ZIO.succeed("value").delay(50.millis)
  }

  def makeBar(i: Int): Bar = Bar(ZQuery.fromRequest(Req(i))(ds))

  val works = Query(ZIO.succeed {
    Foo(bar = ZIO.succeed(List(makeBar(1), makeBar(2), makeBar(3))))
  })

  val broken = Query(ZIO.succeed {
    Foo(bar = ZIO.succeed(List(makeBar(1), makeBar(3), makeBar(3))))
  })

What happens in the "broken" case is that the streamed messages look like this:

{"incremental":[{"data":null,"errors":[{"message":"Effect failure","locations":[{"line":6,"column":36}],"path":["foo","bar",0,"value"]}],"path":["foo","bar",0]}],"hasNext":true}

I managed to trace down the issue to the datasource not completing the requests, dying with the following message:

Data source ValuesDS did not complete request Req(3) ....

Note that if I change my query to this, then it works as expected again:

foo {
  ... @defer { bar { value } }
}