3

我正在完成一个 Data Studio 连接器,并注意到 API 调用数量的一些奇怪行为。

在我期望看到单个 API 调用的地方,我看到了多个调用。

在我的应用程序脚本中,我保留了一个简单的计数,每次获取 url 都会增加 1,这给了我期望使用 getData() 看到的正确数字。

但是,在我的 API 监控日志(使用 Runscope)中,我看到对同一个端点的多个 API 请求,以及在单个 getData() 调用中不同端点的不同数量(它们应该都是相同的)。例如

在此处输入图像描述

我无法在此处发布代码(客户端项目),但它与 Google 文档上的数据连接器代码基本相同。我已经实现了缓存和退避。

寻找任何想法或是否有人经历过类似的事情?

谢谢

4

3 回答 3

1

根据this 参考,如果您没有为您的字段明确定义此属性,GDS 还将执行语义类型检测。如果查询是语义类型检测,则请求将特征sampleExtraction: true

当 Data Studio 执行社区连接器的 getData 函数以进行语义检测时,传入的请求将包含一个 sampleExtraction 属性,该属性将设置为 true。

于 2021-07-07T17:17:48.777 回答
0

如果 GDS 报告包含具有不同维度/指标配置的多个小部件,则 GDS 可能会getData为每个小部件触发多个调用。

于 2018-09-03T09:30:20.687 回答
0

有点晚的答案,但这可能会帮助其他面临同样问题的人。

附加到图表的小部件/搜索过滤器会发出自己的 getData 调用。如果您的自定义适配器被构建为通过来自第三方服务的 API 调用来检索数据,这些数据与由 GDS 转发的 request.fields 属性无关 => 那么这些 API 调用乘以 N+1(其中 N =您的报告正在实施的小部件/搜索过滤器)。

我也找不到官方的解决方案,所以我发明了一种使用缓存的解决方法。

图表对 getData 的请求(通常请求比搜索过滤器更多的字段)将是唯一允许查询 API 端点的请求。在开始这样做之前,它将在缓存“cache_{hashOfReportParameters}_building”=> true 中存储一个键。

if (enableCache) {
    cache.putString("cache_{hashOfReportParameters}_building", 'true');
    Logger.log("Cache is being built...");
}

它将检索 API 响应、分页并缓冲结果。

一旦完成,它将删除缓存键“cache_{hashOfReportParameters} building”,并将缓存到目前为止缓冲在“cache {hashOfReportParameters}_final”中的最终合并结果。


当涉及到过滤器时,它们也会调用:getData,但通常最多只有 3 个请求的字段。我们要做的第一件事是确保它们不能在主 getData 调用之前开始执行......所以我们为可能是相同数据集之后的搜索过滤器/小部件添加一点延迟:

    if (enableCache) {
      var countRequestedFields = requestedFields.asArray().length;
      Logger.log("Total Requested fields: " + countRequestedFields);
      if (countRequestedFields <= 3) {
          Logger.log('This seams to be a search filters.');
          Utilities.sleep(1000);
      }
    }

之后,我们计算报告所有移动部分的哈希值(日期范围,加上您设置的所有其他参数,这些参数可能会影响从 API 端点检索到的数据):

现在最好的部分是,只要主图仍在构建缓存,我们就让这些 getData 调用等待:

        while (cache.getString('cache_{hashOfReportParameters}_building') === 'true') {
           Logger.log('A similar request is already executing, please wait...');
           Utilities.sleep(2000);
        }

在这个循环之后,我们尝试检索“cache_{hashOfReportParameters}_final”的内容——如果我们失败了,有一个备份计划总是一个好主意——允许它再次遍历 API。我们在检索缓存的数据时遇到了大约 2% 的错误率......

使用缓存的结果(或缓冲的 API 响应),您只需根据 GDS 需要的模式转换您的响应(这在图和过滤器之间有所不同)。


当您开始实现此功能时,您会注意到另一个问题...... Google 缓存限制为每个密钥最大 100KB。但是,您可以缓存的键的数量没有限制......幸运的是,其他人过去也遇到过类似的需求,并提出了一种智能解决方案,将您需要缓存的一大块拆分为多个缓存键,然后粘合当需要检索时,它们会重新组合成一个对象。

见:https ://github.com/lwbuck01/GASs/blob/b5885e34335d531e00f8d45be4205980d91d976a/EnhancedCacheService/EnhancedCache.gs


我无法与您分享我们实施的最终解决方案,因为它对客户来说太具体了——但我希望这至少能让您对如何解决问题有一个好主意。

如果近实时足以满足您的需求,缓存完整的 API 结果通常是一个好主意,可以避免无缘无故的往返和服务器负载。

于 2020-09-17T16:11:01.893 回答