Bug 4327

Summary: Remove InterruptedException from stop processing and require stop() on Batchlet.
Product: jbatch Reporter: kmukher
Component: sourceAssignee: cvignola
Status: CLOSED FIXED    
Severity: normal CC: issues
Priority: P5    
Version: 1   
Target Milestone: ---   
Hardware: All   
OS: All   

Description kmukher 2012-11-16 14:34:07 UTC
In section 8.11 (Stop Processing) it states, "The batch runtime then interrupts the batchlet thread, which results in java.lang.InterruptedException."

This implies that the batch container guarantees that we can stop a Batchlet through an interrupt even if a Batchlet does not implement the stop method. Once the batch container gives up control to a Batchlet there is no way to force it to return unless we enforce the best practice of implementing a stop() or release() type method. This is how most threadpool implementations like ExecutorService and WorkManager handle this problem.

The only time InterruptedException will be thrown on a Thread.interrupt() is in a wait(), sleep(), or blocking IO call which throws InterruptedException. Since InterruptedException is a checked exception it could still be caught and ignored by the Batchlet anyway. And if the batchlet it not waiting, sleeping, or in a blocking IO call the Thread.interrupt() will not have any effect unless the batchlet implementation performs period checks to see if the thread has been interrupted.

Another point of ambiguity is that we can't enforce how the underlying threadpool implements stop processing for work that it is executing. For example, Java's ExecutorService requires that all Work implement a release() method, and typical implementations only issue a Thread.interrupt when the entire ExecutorService is shut down, but this is not true for other WorkManagers. (From the ExecutorService javadoc: "There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.")

So my main point is that we should probably not mention anything in the spec about interrupting threads or InterruptedExceptions, and just require that a stop method is implemented on all Batchlets(change section 6.1.2). This will help to enforce the programming guideline: "A well designed batchlet stops gracefully when the JobOperator.stop operation is invoked." (which is already in the spec).
Comment 1 cvignola 2012-11-17 19:39:26 UTC
You are correct InterruptedException can be caught and ignored.  The batchlet implementor (forced to implement stop) can also implement stop as a no-op.  So you can't win :)  

I was under the mistaken impression InterruptedException was thrown unconditionally, which I thought made improved its usefulness.  

The debate within the EG that lead to this dual approach of an optional stop method and an InterruptedException is strong opinion that the stop method should not be required.  If not required, it tends to be ignored.  If ignored, you have the operational problem of a poorly behaved batchlet.  

Unfortunately Java doesn't have an ABTERM function like z/OS - kills threads on contact :)   

I originally proposed a required stop method and no InterruptedException.  The EG then talked me out of that, leading to what we see in the public draft.  

I will discuss with the EG and attempt to achieve concensus on required stop. If concensus is not achieved, I will likely leave the spec as is,  because afterall, the InterruptedException doesn't hurt anything.
Comment 2 kmukher 2012-11-26 18:51:41 UTC
Thanks Chris, looks like we agree on this. However, by even mentioning InterruptedException we can get ourselves into some trouble. When you bring this up with the expert group please mention that the following statement has some implications that we really don't want to support in the batch container, "The batch runtime then interrupts the batchlet thread, which results in java.lang.InterruptedException.(Section 8.11)."

1. Firstly, a container can't throw a java.lang.InterruptedException on a thread where it doesn't have control; it can only set the interrupted flag to true on a thread and then hope that whatever code has control checks for that flag and throws an InterruptedException. So again, we are back to the Batchlet code having to check for the flag and throw the InterruptedException.

2. The first point then implies that the batch runtime must implement (and spec out) its own JSE and J2EE thread pool management to enforce this thread stop behavior.  The batch container won't be able to use any managed thread pools included with a J2EE application server or any third party work managers since we have to have full control over the threads and how to stop them. Different workmanagers handle "forced" stops in different ways and most don't provide a user API that can set an interrupted flag on a thread, (however they all do require a stop() method to be implemented). 

So simply mentioning InterruptedException can be misleading because it is a behavior that is not possible to implement by any batch RI.
Comment 3 cvignola 2012-11-29 21:57:53 UTC
I thought thread A could interrupt thread B as long as the SecurityManager allowed access.  In our case thread A would normally have access.  But I see the slippery slope and we don't need both stop and interrupt.  Stop will probably end up being optional.  But we can drop the interrupt stuff.