SpeaksBinary
SpeaksBinary

Reputation: 185

How do I timeout a blocking call inside an EJB?

I am in the process of developing an EJB that makes 10+ calls to other components (EJBs, Web services, etc.) as part of it's business logic. In my case, performance is a huge concern. This EJB will be servicing a few million requests a day.

My question is: For each of those 10+ calls, how can I enforce a timeout?

I cannot wait more than 'n' seconds for any one of the calls to return. If a call takes longer than 'n' seconds, I will use a default response for processing.

I would normally use a Executor to solve this problem but, from what I understand, one shouldn't spawn threads from within an EJB as it may potentially interfere with the EJB's lifecycle.

Upvotes: 1

Views: 1335

Answers (2)

Gabriel Aramburu
Gabriel Aramburu

Reputation: 2981

how can I enforce a timeout?

The ejb3.1 specification provides the possibility to set a timeout using @AccessTimeout annotation that applies for serialized client calls that have to wait when an Session Bean instance is busy executing a previous request. Clearly (and explicity described in the specification) this applies to StateFul and Singleton session bean, although it could be implemented for Stateless in the case the bean pool run out of available instances. Notice, once the client-invoked business method is in progress this timeout no applies.

Other possibility that is not part of the specification but, is supported by several servers (see JBoss example) is to define a timeout at the remote client side. If the client invocation takes longer than the configured timeout, the client will be informed, however, the server execution will not be interrupted which it is not good enough.

Set a transaction timeout neither is a good option because there is no guarantee the thread that executes the business logic will be interrupted when the transaction timeout expires.

I would normally use a Executor to solve this problem but, from what I understand, one shouldn't spawn threads from within an EJB..

Instead you could use ManagedExecutorService class that is an Executor extension suitable to use within a EJB Container.

Aditionally, to implement asynchronous call within an EJB, take a look at @Asynchronous annotation, which provides a high level abstraction to solve the multithreding issue you are facing. Cancel() method from Future class, allows you to interrup a thread's execution if you consider that the process has taken too long.

Upvotes: 1

Torsten
Torsten

Reputation: 33

since you are not providing much detail of your environment:

  • use bean managed transactions and set the transaction timeout
  • EE7: provides an managed executor service
  • EE6: custom executor service as a JCA connector

Upvotes: 0

Related Questions