3

在设计我的 GWT/GAE 应用程序时,很明显我的客户端 (GWT) 将生成三种类型的请求:

  • 同步- “现在就回答我!我很重要,需要实时响应!!!”
  • 异步- “尽可能回答我;我需要在某个时候知道答案,但实际上并不是那么紧急。”
  • 命令- “我不需要答案。这不是一个真正的请求,它只是一个在服务器端做某事或处理某事的命令。”

我的游戏计划是实现我的 GWT 代码,以便我可以为每个特定的服务器端请求指定(注意:由于本问题范围之外的原因,我决定使用RequestFactory传统的 GWT-RPC ),哪种类型要求它是:

  • SynchronousRequest- 同步(从上面);发送命令并急切地等待响应,然后以某种方式更新客户端的状态
  • AsynchronousRequest- 异步(从上面);发出初始请求,并以某种方式(通过轮询或 GAE 通道 API)在最终收到响应时得到通知
  • CommandRequest- 命令(从上面);发出服务器端请求并且不等待响应(即使服务器未能或拒绝执行命令)

我想我的意图SynchronousRequest不是产生一个完全阻塞的请求,但它可能会阻止用户与Widget屏幕的特定或部分交互的能力。

这里增加的问题是:GAE 强烈强制其所有前端实例超时(60 秒)。后端实例对超时、线程等有更宽松的约束。所以对我来说很明显,AsynchronousRequests应该CommandRequests路由到后端实例,这样 GAE 超时就不会成为它们的问题。

但是,如果 GAE 表现不佳,或者我们的流量达到峰值,或者我的代码很糟糕,我必须考虑制作 a 的场景SynchronousRequest(它必须通过超时调节的前端实例)并且会超时,除非我的 GAE 服务器代码做一些花哨的事情。我知道 GAE API 中有一个方法,我可以调用它来查看一个请求在它即将超时之前有多少毫秒;但是虽然它的名字现在让我忘记了,但这就是这个“花哨”代码的基础。public static long GAE.timeLeftOnRequestInMillis()为了这个问题,我们称之为。

在这种情况下,我想检测 aSynchronousRequest即将超时,并以某种方式动态地将其转换为 aAsynchronousRequest以便它不会超时。也许这意味着向AboutToTimeoutResponse客户端发送一个回复,并迫使客户端决定是重新发送AsynchronousRequest还是失败。或者也许我们可以将其SynchronousRequest转换为 anAsynchronousRequest并将其推送到一个队列中,后端实例将使用它、处理它并返回响应。在实现方面我没有任何偏好,只要请求不会失败或超时,因为服务器无法足够快地处理它(因为 GAE 强加的规定)。

那么,这就是我在这里真正要问的:

  • 我怎样才能RequestFactory在里面包装一个电话SynchronousRequestAsynchronousRequestCommandRequest以这样一种方式使RequestFactory电话的行为符合他们每个人的预期?换句话说,这样调用要么部分阻塞(同步),要么可以在以后的某个时间通知/更新(异步),还是可以只是触发后忘记(命令)?
  • 如何实现我的要求,让SynchronousRequest绕过 GAE 的 60 秒超时并且仍然得到处理而不会失败?

请注意:超时问题很容易通过将事物重新路由到后端实例来规避,但后端不能/不能扩展。我在这里也需要可扩展性(这就是我首先使用 GAE 的主要原因!) - 所以我需要一个处理可扩展前端实例及其超时的解决方案。提前致谢!

4

1 回答 1

0

如果您希望 GAE 执行的计算需要超过 60 秒,那么在发送响应之前不要等待计算结果。根据您的问题定义,没有办法解决这个问题。相反,客户端应该提交工作订单,并在结果准备好时等待来自服务器的通知。请求将由工作订单组成,可能看起来像这样:

class ComputeDigitsOfPiWorkOrder {
  // parameters for the computation
  int numberOfDigitsToCompute;

  // Used by the GAE app to contact the requester when results are ready.
  ClientId clientId;
}

这样,您的 GAE 应用程序可以在保存工单后立即响应(例如在任务队列中),而不必等到它实际完成十亿位数的 pi 计算后才响应。然后,您的 GWT 客户端使用 Channel API 等待结果。

为了给某些工单更高的优先级,可以使用多个任务队列。如果您希望任务队列工作自动扩展,您将需要使用推送队列。使用推送队列实现优先级有点棘手,但您可以配置高优先级队列以获得更快的馈送速率。

您可以用其他通知解决方案替换 Channel API,但这可能是最直接的。

于 2012-09-27T06:57:19.410 回答