2012-09-08 67 views
3

在设计我的GWT/GAE应用程序同步,异步和命令客户端请求,它已成为明显,我认为我的客户端(GWT)会产生三种类型的请求:与GWT和GAE

  • 同步 - “回答我现在我很重要,并且需要实时响应!”!
  • 异步 - “回答我时,你可以;我需要知道在某个时刻的答案,但它确实不是所有的根特大学”
  • 命令 - 。“我不需要回答这是不是一个真正的请求时,它只是一个命令做某件事,或者加工的东西在服务器端”

比赛计划是实现我的GWT代码,这样我可以指定,对于每个特定的服务器端请求(注:我已经决定与RequestFactory走过去传统的GWT-RPC原因这个问题的范围),它是哪一种类型的请求外:

  • SynchronousRequest - 同步(从上面);发送一个命令和热切期待它然后使用它来更新客户端的状态以某种方式
  • AsynchronousRequest的响应 - 异步(从上面);做出初始请求并以某种方式 - 无论是通过轮询或GAE通道API当响应最后接收
  • CommandRequest,被通知 - 命令(从上面);使得服务器端的请求,不等待响应(即使服务器失败,或拒绝,迫使命令)

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

这里加入起脚是这样的:GAE强烈强制对所有前端实例(60秒)的超时。后端实例有超时,线程等更为宽松的约束所以很明显,我认为AsynchronousRequestsCommandRequests应该被路由到后端实例,以便GAE超时不会成为一个问题他们。但是,如果GAE表现不佳,或者如果我们碰到高峰流量,或者我的代码太简陋了,我必须考虑制作SynchronousRequest的场景(必须经历超时调节的前端实例),并且会超时,除非我的GAE服务器代码做了一些奇特的事情。我知道GAE API中有一种方法可以调用,以查看请求在其超时之前有多少毫秒的时间;但尽管现在它的名字让我感到惋惜,但这就是这个“花哨”的代码所基于的。为了这个问题,我们称之为public static long GAE.timeLeftOnRequestInMillis()

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

那么,这里就是我其实是问在这里:

  • 我怎么能以这样的方式使RequestFactory呼叫表现他们每个人的方式包裹内SynchronousRequestAsynchronousRequestCommandRequest一个RequestFactory通话打算?换句话说,这样的调用或者部分阻塞(同步),可以在路上的某个点通知/更新(异步),或者可以只是开火和忘记(命令)?
  • 我该如何实现我的要求,让SynchronousRequest跳过GAE的60秒超时,并且仍然无故障地处理?

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

回答

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等待结果。

为了赋予某些工单更高的优先级,可以使用多个任务队列。如果您希望Task Queue工作自动扩展,则需要使用推送队列。使用推送队列来实现优先级有点棘手,但您可以使用更快的进纸速率configure high priority queues

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