从Job内调用Controller动作方法 [英] Call a Controller action method from within a Job

查看:167
本文介绍了从Job内调用Controller动作方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从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,85713: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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆