Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread.sleep() in an EJB

Tags:

I know that messing with threads inside an EJB is a big no-no, but I would just like to ask for advice on how handle this case. My EJB is calling an external Web service which may sometimes return a "busy" status. When that happens, I would like to wait for a while and then resubmit the request using the same data as before.

What would be the best way to implement this?

like image 639
Ariod Avatar asked Nov 20 '11 15:11

Ariod


People also ask

What's thread sleep () in threading?

Thread. sleep() method can be used to pause the execution of current thread for specified time in milliseconds. The argument value for milliseconds can't be negative, else it throws IllegalArgumentException .

What does sleep () do in thread Java?

Thread. sleep causes the current thread to suspend execution for a specified period. This is an efficient means of making processor time available to the other threads of an application or other applications that might be running on a computer system.

Can sleep () method causes another thread to sleep?

Note that sleep is a static method, which means that it always affects the current thread (the one that is executing the sleep method). A common mistake is to call t. sleep() where t is a different thread; even then, it is the current thread that will sleep, not the t thread.

Is it safe to use thread sleep in Java?

Thread. sleep is bad! It blocks the current thread and renders it unusable for further work.


1 Answers

EJB 3.1 brought a new @Asynchronous feature that you can take advantage of:

@Asynchronous
@TransactionAttribute(NOT_SUPPORTED)
public Future<WebServiceResult> callWebService(int retries) {
    WebServiceResult result = webService.call();

    if (!result.equals(BUSY)) {
        return result;
    }

    if (retries <= 0) {
        throw new TooBusyException();
    }

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }

    return callWebService(retries - 1);
}

Then simply call you web service with:

Future<WebServiceResult> result = yourEJB.callWebService(1);

// Can do some interesting stuff here.
// ...
// ...

result.get(2, SECONDS);  // Block for up to 2 seconds.

As you can see you get configurable number of retries and timeout for free.

How does this differ from just calling Thread.sleep()? Returning Future is more explicit and manageable. Also I don't think Thread.sleep() is that harmful. The only problem is that this EJB instance can now longer be reused by other clients. With Future asynchronous invocation happens inside some other EJB and thread pool. As to importance of Thread#interrupt() inside the catch block, refer Why invoke Thread.currentThread.interrupt() when catch any InterruptException?

Another idea: use aspect around calling web service, catch BusyException once and retry.

like image 86
Tomasz Nurkiewicz Avatar answered Sep 18 '22 18:09

Tomasz Nurkiewicz