0

I am developing a web application where I need to run a thread for 60 seconds which needs to check for response coming from a webservice. If the response arrives within 60 seconds I will forward to success othewise I will forward to a time out page after 60 seconds. I am using JSF 2.0? I have thought of using the Timer but not sure whenther I can run the timer for sprcefic amount of time only.

Is there any smart solution for this ??

user1220373
  • 363
  • 1
  • 9
  • 19

3 Answers3

6

Yes, youre able to create a timer which expires after a certain amount of time. See this link http://docs.oracle.com/javaee/1.4/api/javax/ejb/TimerService.html.

Java < vers. 6

  1. Create Session- or MessageDriven-Bean
  2. Inject TimerService

    @Ressource
    TimerService ts;
    
  3. Create Timer

    ...
    // create Timer which starts after 10s every 10s
    Timer timer = ts.createTimer(10000, 10000, "Test-Timer");
    ...
    

    Important: Timer Interval has to be >7sec, see Java Specs

  4. Create Method to be executed when timer fires

    @Timeout //marks Method to be executed by Timer
    public void timerFired(Timer timer) {
      // your code here
    }
    

Java > vers. 6

Much comfortable with the @Schedule-Annotation

    @Schedule(second="*/45", minute="*", hour="*", persistent="false")
    public void scheduler() {
      // your code here
    }

The above code implements a timer which gets fired every 45s of every minute of every hour. Have a look at wikipedia for more information about cron syntax.

Both methods implement the Serializable-Interface, so they are both thread-safe.

if you would like to extend this rudimental functionality you should take a look at Quartz.

Hope this helped! Have Fun!

SimonSez
  • 6,539
  • 1
  • 28
  • 33
  • This is not exactly what the OP is asking. It has to happen in the HTTP request thread (how else would you forward/redirect afterwards?) – BalusC Mar 08 '12 at 19:01
1

Do absolutely not use Timer for this! It's funny for one-time-run desktop applications, but it has severe potential problems when used in a lifetime long running Java EE web application.

Rather use the executors from the java.util.concurrent package. Here's a kickoff example:

ExecutorService executor = Executors.newSingleThreadExecutor(); // An application wide thread pool executor is better.

Callable<InputStream> task = new Callable<InputStream>() {
    @Override
    public InputStream call() throws Exception {
        // Do here your webservice call job.
        return new URL("http://stackoverflow.com").openStream();
    }
};

try {
    InputStream input = executor.invokeAny(Arrays.asList(task), 60, TimeUnit.SECONDS);
    // Successful! Forward to success page here.
} catch (TimeoutException e) {
    // Timeout occurred. Forward to timeout page here.
}
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • Thank you very much for your help – user1220373 Mar 12 '12 at 04:05
  • But in this approach the user have to wait 60 seconds all the time even though the response has come earlier. – user1220373 Mar 12 '12 at 05:42
  • Huh!?! But.. if you google "EE" and "Threads", you pretty much come up with dozens (hundreds?) of pages saying "DON'T USE THREADS WITH EE/EJB!". Why did you recommend the Executor framework over the TimerService? What am I missing here? – Marco Feb 21 '13 at 14:50
  • @Marco: you should interpret it as "don't use **unmanaged** threads". So, as in `new Thread().start()` and so on. The new Java 1.5 util concurrent `ExecutorService` manages them perfectly. See also this related answer: http://stackoverflow.com/a/8328113 and then specifically this one for `Timer` vs `ExecutorService`: http://stackoverflow.com/a/7499769/ – BalusC Feb 21 '13 at 14:52
  • @BalusC Thanks! Unfortunately, a colleague of mine reminded me why threads are a bad idea in a EE environment: transactions. That is, until EE 7 comes out with the new [ManagedExecutorService](http://concurrency-ee-spec.java.net/javadoc/javax/enterprise/concurrent/ManagedExecutorService.html)! – Marco Feb 27 '13 at 12:04
0

It sounds like you should just sit in a loop for 60 seconds and sleep for a second between checks. Once 60 seconds has passed or the request came in let the code continue and forward the user to the appropriate page.

This is the simplest way. You could also use an ajax polling system which would be more user friendly because you can update the user interface with a countdown.

        long startTime = System.currentTimeMillis();
        boolean success = false;
        while (System.currentTimeMillis() < startTime + 60000) {
            // do check
            success = checkSucceeds();
            if (success) break;

            try {
                Thread.sleep(1000);
            } catch (InterruptedException interruptedException) {
                // ignore
            }
        }
        if (success)
            // forward to success page
            ;
        else
            // forward to error page
            ;
Sarel Botha
  • 11,739
  • 7
  • 51
  • 55