Play 2.2 动作未与 Web 服务响应处理程序并行处理
Posted
技术标签:
【中文标题】Play 2.2 动作未与 Web 服务响应处理程序并行处理【英文标题】:Play 2.2 action not processed in parallel with web service response handler 【发布时间】:2013-11-28 15:17:44 【问题描述】:public class Application extends Controller
@BodyParser.Of(BodyParser.Json.class)
public static Result action1()
WS.url(WS_URL).get().map(new Function<WS.Response, Result>()
public Result apply(WS.Response response)
try
Thread.sleep(10000);
catch (InterruptedException e)
e.printStackTrace();
return null;
);
return ok();
@BodyParser.Of(BodyParser.Json.class)
public static Result action2()
return ok();
客户端首先调用action1()
,然后调用action2()
。但是,Play 似乎在这 10 秒后处理了第二个请求。我认为来自 Web 服务的响应由 Play 在单独的线程中处理,但似乎并非如此。在这种情况下,如果我想休眠或在超时后执行一些代码,而不中断服务器处理其他请求,我该怎么办?
编辑:当客户端调用 action2() 之前来自 WS 的响应到达时,就会发生这种情况。
【问题讨论】:
您确定客户端在调用操作 2 之前不等待操作 1 完成吗?可以显示客户端代码吗? 不,它不会等待。实际上,服务器在向 WS 发送请求后立即从 action1 返回,但似乎来自 WS 的响应是由处理动作的同一线程处理的。我忘了说 WS 的响应是在客户端调用 action2 之前到达的。 【参考方案1】:默认情况下Play分配的线程数与你拥有的CPU核心数相同(虽然注意有多个线程池),所以如果你想做sleep
之类的阻塞操作,请配置它以分配更多线程在处理程序中。
【讨论】:
确实,我找到的解决方案是使用 Akka 系统在单独的线程中进行每个 WS 调用。【参考方案2】:不太确定您要实现什么,但下面的代码将在 WS 调用返回和返回 ok 结果之间插入 10 秒延迟:
public static F.Promise<SimpleResult> action1()
return WS.url(WS_URL).get().flatMap(new Function<WS.Response, F.Promise<WS.Response>>()
public F.Promise<WS.Response> apply(WS.Response response)
return F.Promise.timeout(response, 100000);
).map(new Function<WS.Response, SimpleResult>()
public SimpleResult apply(WS.Response response)
return ok();
;
要了解 Play 的线程池,请阅读以下内容:
http://www.playframework.com/documentation/2.2.x/ThreadPools
要了解 Play 如何使用 Promise,请阅读以下内容:
http://www.playframework.com/documentation/2.2.x/JavaAsync
【讨论】:
当用户点击我网站上的一个按钮时,服务器会完成多个 WS 调用,这些调用返回的响应用于更新对象列表。同时,客户端会定期发送 AJAX 请求以检查列表中的任何对象是否已更新。问题是 AJAX 请求是在 所有 WS 调用返回之后提供的,而不是像我预期的那样并行。我找到的解决方案是使用 Akka 系统在单独的线程中进行每个 WS 调用。 您是否在 WS API 返回的承诺上调用get()
?如果你是,那么基本上你把你的应用程序变成了一个同步阻塞应用程序,你看到的行为是预期的。永远不要在承诺上打电话给get()
。
不,我不打电话给get()
。以上是关于Play 2.2 动作未与 Web 服务响应处理程序并行处理的主要内容,如果未能解决你的问题,请参考以下文章