从Job中调用Controller操作方法

时间:2013-08-30 04:32:29

标签: java playframework playframework-1.x

我试图从String子类调用由Job指定的任意控制器操作。

我已尝试接受this question的答案,但发现它对我不起作用... WS.url("http://www.yahoo.com/").get();有效,但WS.url("http://localhost/foo/bar").get()阻止并最终在60秒后超时

我也尝试按this answer中的建议增加play.pool中的application.conf值,但没有区别。

这是我的代码:

application.conf:

# 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,85713:23:51,886之间的时间差 - 这是60秒超时。

知道什么是错的吗?

目前,我只是想让这个简单的案例发挥作用。之后,我需要提供cookie等请求。

另外,我对使用WS的想法并不十分满意,因为我并没有真正尝试访问另一台主机上的Web服务;我正在尝试调用我自己的应用程序中的一些代码,因此向自己生成实际的HTTP请求似乎有点愚蠢。是不是有办法在内部构造请求的内容,只是直接调用action方法?

如上所述,其目的是允许将任意控制器操作安排为系统中的作业。我希望每次我们需要安排一份工作来执行某些控制器代码已经完成的工作时,都要避免编写代码。

1 个答案:

答案 0 :(得分:2)

我发现了问题。我的请求被重定向。实际上它被重定向了两次:一次是因为我使用的是安全模块,它重定向到登录页面,甚至在此之前,似乎我的公司安装了一些网络安全设备localhost向本地请求网络IP地址。

我确实将WSRequest对象的followRedirects属性设置为true,但它似乎不起作用,并导致它挂起。一旦我关闭它,我看到重定向发生,然后我做了一些变通方法以避免重定向,所以现在它工作。