从Job内调用Controller动作方法 [英] Call a Controller action method from within a Job
问题描述
我试图从Job
子类调用由String
指定的任意控制器动作.
I am trying to call arbitrary controller actions, specified by a String
, from a Job
subclass.
我已经尝试过接受这个问题的答案,但是发现它对我不起作用... WS.url("http://www.yahoo.com/").get();
可以工作,但是WS.url("http://localhost/foo/bar").get()
会阻塞并最终在60秒后超时.
I have tried the accepted answer to this question, but found that it doesn't work for me... WS.url("http://www.yahoo.com/").get();
works, but WS.url("http://localhost/foo/bar").get()
blocks and eventually times out after 60 seconds.
I have also tried increasing the play.pool
value in application.conf
, as recommended in this answer, but it made no difference.
这是我的代码:
# Execution pool
# ~~~~~
# Default to 1 thread in DEV mode or (nb processors + 1) threads in PROD mode.
# Try to keep a low as possible. 1 thread will serialize all requests (very useful for debugging purpose)
play.pool=3
路线:
PUT /jobs/invokejob Jobs.invokeTestJob
GET /jobs/sampleAction Jobs.sampleControllerAction
Jobs.java:
public static void invokeTestJob()
{
Logger.warn("Jobs.invokeTestJob() called");
new SampleJob("Jobs.sampleControllerAction").in(1);
Logger.warn("Finished scheduling SampleJob");
listJobs();
}
public static void sampleControllerAction()
{
Logger.warn("Jobs.sampleControllerAction() called");
renderText("OK");
}
SampleJob.java:
public class SampleJob extends QJob
{
public final String action;
public SampleJob(String actionSpec)
{
this.action = actionSpec;
}
@Override
public void doJob()
{
Logger.warn("SampleJob.doJob() called");
final ActionDefinition actionDefinition = Router.reverse(action);
actionDefinition.absolute();
final WSRequest URL = WS.url(actionDefinition.url);
HttpResponse response = null;
switch(actionDefinition.method)
{
case "GET":
{
Logger.warn("GETting %s", URL.url);
response = URL.get();
break;
}
case "POST":
{
Logger.warn("POSTting %s", URL.url);
response = URL.post();
break;
}
case "PUT":
{
Logger.warn("PUTting %s", URL.url);
response = URL.put();
break;
}
case "DELETE":
{
Logger.warn("DELETEing %s", URL.url);
response = URL.delete();
break;
}
}
Logger.warn("response=%s", response.getString());
}
}
日志输出:
13:22:50,783 WARN [play-thread-1] ~ Jobs.invokeTestJob() called
13:22:50,786 WARN [play-thread-1] ~ Finished scheduling SampleJob
13:22:51,804 WARN [jobs-thread-1] ~ SampleJob.doJob() called
13:22:51,857 WARN [jobs-thread-1] ~ GETting http://localhost/quattro/jobs/sampleAction
13:23:51,886 ERROR [jobs-thread-1] ~
@6fe61pf2p
Error during job execution (jobs.SampleJob)
Execution exception (In {module:quattro}/app/jobs/SampleJob.java around line 36)
RuntimeException occured : java.util.concurrent.ExecutionException: java.util.concurrent.TimeoutException: No response received after 60000
play.exceptions.JavaExecutionException: java.util.concurrent.ExecutionException: java.util.concurrent.TimeoutException: No response received after 60000
at play.jobs.Job.call(Job.java:155)
at play.jobs.Job$2.call(Job.java:94)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.util.concurrent.TimeoutException: No response received after 60000
at play.libs.ws.WSAsync$WSAsyncRequest.get(WSAsync.java:223)
at jobs.SampleJob.doJob(SampleJob.java:36)
at play.jobs.Job.doJobWithResult(Job.java:50)
at play.jobs.Job.call(Job.java:146)
... 8 more
Caused by: java.util.concurrent.ExecutionException: java.util.concurrent.TimeoutException: No response received after 60000
at com.ning.http.client.providers.netty.NettyResponseFuture.get(NettyResponseFuture.java:223)
at com.ning.http.client.providers.netty.NettyResponseFuture.get(NettyResponseFuture.java:187)
at play.libs.ws.WSAsync$WSAsyncRequest.get(WSAsync.java:221)
... 11 more
Caused by: java.util.concurrent.TimeoutException: No response received after 60000
at com.ning.http.client.providers.netty.NettyResponseFuture.get(NettyResponseFuture.java:215)
... 13 more
请注意13:22:51,857
和13:23:51,886
之间的时间间隔-这是60秒的超时时间.
Note the time gap between 13:22:51,857
and 13:23:51,886
-- that's the 60-second timeout.
你知道怎么了吗?
就目前而言,我只是想让这个简单的案例开始工作.稍后,我需要在请求中提供cookie等.
For now, I'm just trying to get this simple case to work. Later, I'll need to supply cookies, etc. with the request.
此外,我对使用WS
的想法不太满意,因为我并没有真正尝试访问另一台主机上的Web服务.我正在尝试调用我自己的应用程序中的一些代码,因此不得不向我自己生成实际的HTTP请求似乎有点愚蠢.没有办法在内部构造请求的内容并直接调用action方法吗?
Also, I'm not super comfortable with the idea of using WS
for this, since I'm not really trying to access a web service on another host; I'm trying to invoke some code which is in my own app, so it seems a bit silly to have to generate an actual HTTP request back to myself. Isn't there a way to construct the contents of a request internally and just invoke the action method directly?
如上所述,此操作的预期目的是允许将任意控制器操作安排为系统中的作业.我想避免每次我们需要安排工作来完成某些控制器代码已经完成的工作时都必须编写代码.
As mentioned above, the intended purpose of this is to allow arbitrary controller actions to be scheduled as jobs in my system. I want to avoid having to write code every time we need to schedule a job to do something that some controller code already does.
推荐答案
我发现了问题.我的请求已被重定向.实际上,它被重定向了两次:一次是因为我正在使用安全模块,该模块重定向到登录页面,甚至在此之前,我的公司似乎已经安装了一些网络安全性,它会localhost
请求到本地网络IP.地址.
I found the problem. My request was being redirected. It was being redirected twice, actually: once because I'm using the Secure module, which redirects to the login page, and even before that, it seems my company has some network security thingy installed which localhost
requests to the local network IP address.
我确实将我的WSRequest
对象的followRedirects
属性设置为true,但似乎不起作用,并导致其挂起.一旦我将其关闭,便会看到重定向的发生,然后我做出了一些变通办法来避免重定向,因此现在可以使用了.
I did have my WSRequest
object's followRedirects
property set to true, but it seems that doesn't work, and causes it to hang. Once I turned that off, I saw the redirects happening, and then I made some workarounds to avoid the redirects, so now it works.
这篇关于从Job内调用Controller动作方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!