使用scala和play2或spray进行异步回调

时间:2015-03-16 12:06:49

标签: scala asynchronous reactive-programming playframework-2.3 spray

我有一个系统设计挑战,我希望获得一些社区反馈。

基本系统结构:

[客户] --- HTTP-POST - > [REST服务] ---> [队列] ---> [处理器]

  • [客户端]将json发送到[REST服务]进行处理。
  • 根据请求,[Rest Services]将数据发送到各种队列,由各种语言编写,并在不同进程中运行。
  • 工作在每个处理器中并行化,但仍然需要30秒才能处理。处理时间是数据复杂性的一个因素,无法加速。
  • 结果无法在完成后流式传输回客户端,因为最终的后处理步骤只能在完成所有子步骤后才能完成。

关键挑战:完成后期处理后,客户需要:

  • 在客户端等待后发送结果
  • 通知async作业已完成并传递了ID以请求最终结果

设计要求

我不想阻止[REST服务]。它需要接收传入请求,将数据路由到适当的队列以便在其他进程中处理,然后立即可用于下一个传入请求。

通常情况下,我会使用演员和/或期货/承诺,因此在等待后台工作人员完成时不会阻止[REST服务]。这里的挑战是进行后台工作的工作人员在不同的进程/ VM中运行,并以各种技术堆栈编写。为了在异构系统之间传递这些消息并确保请求生命周期的完整性,正在使用持久队列(而不是在内存消息传递或RPC中)。

最后的考虑因素,为了扩展,各个池中有[REST服务]和[处理器]的负载平衡集。因此,由于从[REST服务]到[处理器]的消息需要通过队列异步发送(并且所有操作都是单独的进程),因此无法将后台完成的工作与[处理器]关联起来到其原始调用[REST Service]实例,以便在promise或actor消息中返回最终处理的数据,最后将响应传递回原始客户端。

那么,问题是,如何进行这种关联?完成所有后台处理后,我需要通过漫长的等待响应或通知将结果返回给客户端(我不想使用像UrbanAirship这样的东西,因为大多数客户端都是浏览器或其他服务。< / p>

我希望这很清楚,如果没有,请要求澄清。

编辑:可能的解决方案 - 想法?

我认为我将一个喷射RequestContext传递给任何可以响应客户端的actor(不必是接收HTTP请求的原始actor)。如果是这样,我可以缓存RequestContext,然后在处理完成后使用此缓存的RequestContext将响应异步发送到适当的客户端吗?

1 个答案:

答案 0 :(得分:0)

嗯,这不是最好的,因为它需要您客户的更多工作,但听起来您想要实现webhook。所以,

[客户] --- POST - &gt; [REST服务] ---&gt; [计算] ---&gt; POST [客户]

[客户] --- GET

解释: 客户端向您的服务发送POST请求。然后,您的服务会进行必要的处理。完成后,您的服务将发送HTTP-POST到客户端已设置的URL。通过该POST数据,客户端将获得必要的信息,然后对完成的数据执行GET请求。