【问题标题】:AWS AppSync wait for DynamoDB Streams Lambda function before resolving sub-resourceAWS AppSync 在解析子资源之前等待 DynamoDB Streams Lambda 函数
【发布时间】:2023-03-18 12:18:01
【问题描述】:

我有类似于以下的 GraphQL 架构。一个 Bravo 中有多个 Alpha,每个 Alpha 都相互引用。 (Bravo 可以得到它的 Alpha,而 Alpha 可以得到它的 Bravo。)

type Alpha {
  id: ID!
  value: Int!
  bravo: Bravo!
}

type Bravo {
  value: Int!
  alphas: [Alpha!]!
}

input InputAlpha {
  value: Int!
}

type Mutation {
  putAlpha(alpha: InputAlpha): Alpha!
}

schema {
  mutation: Mutation
}

如您所知,这两种类型都有一个值。 Alpha 的值是任意的,但 Bravo 的值是其相关 Alpha 的总和。出于性能(和成本)的原因,Bravo 的值缓存在 DynamoDB 表中,并在 Alpha 更新时进行修改。

Alpha 使用简单的 AppSync DynamoDB PutItem 解析器进行更新,目的是通过监视表流的 Lambda 函数更新其 Bravo 的值。这在大多数情况下效果很好。我可以给 Alpha 加上随机值,我可以得到他们 Bravo 的值。

当我尝试在同一个请求中请求 Bravo 的值时,就会出现问题。 (Lambda 函数需要一些时间从流中更新它。)

mutation putAlpha {
  putAlpha(alpha: {
      value: 10
  }) {
    id
    value
    bravo {
      value
    }
  }
}

这自然会返回 bravo 的旧缓存 value,因为在解决 Bravo 时尚未运行 Lambda 函数。

有什么方法可以等到 DynamoDB 流的 Lambda 函数触发后再解析 bravo 或者让 PutItem 操作同步?

我能想到的唯一选择是将 putAlpha 解析器设为 Lambda 函数而不是简单的解析器,并在其中执行 Bravo 更新逻辑。

这种Lambda不断更新缓存值正常吗,还是我做错了什么?

【问题讨论】:

    标签: aws-lambda amazon-dynamodb graphql amazon-dynamodb-streams aws-appsync


    【解决方案1】:

    我认为您的客户应该知道 Bravo 的价值是在后台计算的。 如果这不是您可以做出的权衡,请考虑将 Bravo 的更新逻辑移动到 putAlpha 突变。 (为避免竞争条件,您可以使用 UpdateExpression 的 ADD 操作。)

    一种方法是通过流中的 API 更新 Bravo 的值,并在客户端中订阅 Bravo 的更新。尽管您需要提供 window、xhr 等,但可以在 Lambda 中运行 aws-appsync。

    其他几种方式:

    1. 您可以增加 Bravo 在客户端缓存中的值,而不是从 putAlpha 的响应中获取它。
    2. Bravo 的值在更新后即可检索。 (它可能会在几秒钟后更新。也许您有办法验证此 Alpha 是否应用于 Bravo,将上次 Alpha 的更新时间存储到 Bravo 可以工作。)

    【讨论】:

    • 谢谢,我认为在 Lambda 函数的 putAlpha 突变中进行更新是可行的方法。
    【解决方案2】:

    如果您在运行 updateAlpha 时知道 Bravo 的下一个值应该是什么(例如,您不需要读取其他 Alpha),则可以使用 BatchPutItem 更新两个表。

    如果不是,我不相信 AppSync 现在完全支持这个用例。

    要使其正常工作,您需要等待 Bravo 记录更新后再阅读。我认为目前最简单的方法是使用 Lambda 函数。

    你可以尝试一些其他的东西(它们有点老套):

    1. 让 putAlpha 变异解析器循环旋转指定的时间,直到流更新 Bravo 记录。
    2. 在 Alpha.bravo 上添加一个解析器,它在从表中读取之前等待请求映射模板中的 X 个数量。
    3. 在 Bravo.value 上添加一个解析器,用于查询所有 Alpha,对它们的值求和,然后返回求和值。这种做法违背了在 Bravo 上存储价值的目的。

    我认为你不能在解析器中使用睡眠,但你可以使用循环:https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-programming-guide.html#loops

    希望这会有所帮助!

    【讨论】:

    • 谢谢!我决定使用处理 Bravo 更新的putAlpha Lambda 函数解析器。不过这里有一些有趣的想法。
    猜你喜欢
    • 2019-12-12
    • 2019-07-27
    • 2019-04-16
    • 1970-01-01
    • 2021-07-18
    • 2016-12-26
    • 2019-02-06
    • 1970-01-01
    • 2018-10-29
    相关资源
    最近更新 更多