【问题标题】:Is GraphQL cancelling data fetching in case of a failure?GraphQL 是否会在失败时取消数据获取?
【发布时间】:2019-11-06 18:07:38
【问题描述】:

我试图了解 GraphQL 的 (Java) 实现是否足够智能,如果在执行其中一个提取器期间引发异常,则可以取消计划的数据提取?

例如,我运行一个查询来检索客户的所有订单。假设客户有 100 个订单。这意味着 GraphQL 应该进行 100 次调用以检索每个订单的详细信息,但在执行过程中,其中一个调用失败 - 49 个请求已经成功,第 50 个失败,还有 50 个请求要执行。 GraphQL 将中断正在执行的查询,并立即向客户端返回错误。但它会打剩下的 50 个电话吗?

【问题讨论】:

    标签: graphql graphql-java


    【解决方案1】:

    这意味着 GraphQL 应该进行 100 次调用以检索每个订单的详细信息

    它必须调用解析器函数 100 次,但这是否意味着 100 次网络调用取决于你。没有什么能阻止您批量加载所有 100 合 1 网络请求(如果 API 允许的话)。

    GraphQL 将中断正在执行的查询,并立即向客户端返回错误。

    只有当你抛出 AbortExecutionException 时才会发生这种情况,否则下一个节点将正常处理。部分结果是 GraphQL 中的常态。一个错误的列表元素不会阻止所有其他元素的解析。正如Ken Chan noted,规范描述了这种行为。

    查询的执行方式在很大程度上掌握在您的手中。如果它都是同步的,并且您使用AbortExecutionException 中断执行,则不会进行进一步的调用。如果您调度异步请求(通过返回 CompletionStage,例如 CompletableFuture),Java 中没有通用机制来中断这些任务。当您取消CompletableFuture 时,它会does not interrupt the underlying thread。更疯狂的是,它甚至无法将取消传播到之前的CompletionStages。这是一个 Java 问题,根本不是 GraphQL 或 graphql-java 特有的。你必须想出非平凡的机器来实现这一点。一种方法可能是使用Tascalate Concurrent,因为它允许取消传播和线程中断。您仍然需要以一种对中断做出实际反应的方式来执行您的任务。所以大部分工作都在你身上。

    【讨论】:

      【解决方案2】:

      不,它将继续进行剩余的 50 次调用,因为规范 here 要求它,第 3c 点:

      返回一个列表,其中每个列表项都是调用的结果 CompleteValue(innerType, fields, resultItem, variableValues),其中 resultItem 是结果中的每一项。

      但它会向您报告订单50失败及其失败原因。最后,您将获得类似于以下内容的 JSON 响应:

      {
         "data" : {
           "orders" : [
               {"id" : 1 , ..... } , 
               {"id" : 2 , ..... } , 
               {"id" : 3 , ..... } , 
               ......
            ]
         },
         "errors" : [
            {
               "message" : "Fail to get this order details due to blablab..." , 
               "path" : [ "orders", 50 ]  
            }
         ]
      }
      

      【讨论】:

      • 可能我没有正确表达我的问题。如果 GQL 对整体响应没有任何影响,为什么还要进行剩余的 50 次调用?这些调用只会浪费资源。我看不出与规范的冲突。只是为了确保我清楚:查询是“获取 customerId=123 的所有订单”。它不是“获取所有 orderIds=[1,2,3,4,...] 的详细信息”。
      猜你喜欢
      • 2018-06-30
      • 2019-12-10
      • 1970-01-01
      • 2011-04-23
      • 2015-08-16
      • 2022-08-17
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      相关资源
      最近更新 更多