Hi Marina,
I appreciate the usefulness of this capability, but it has some
implications for any code that is executing at the time of the interrupt.
The bean may be in the middle of calling a resource, such as a JDBC
connection, and that resource could be in the middle of i/o, etc. External
libraries, even components internal to the server itself, may not be
designed to gracefully handle interrupts. That could result in the server
and/or resources being left in a bad state.
Also of concern is that the proposal would change current default
behavior. An existing application, client and/or server side, most likely
wouldn't be coded to handle the new behavior. If we do go with option b)
or c), my preference would be to add a switch such as
@Asynchronous(interruptable=true) that lets a bean provider opt to get the
new behavior. By opting in, it would be assumed that the a bean provider
would know and accept the implications - to the bean, bean client, and any
external library or resource it may be calling - of a mid-operation
interrupt and would be able to handle the interrupt and cleanup
appropriately.
-Jeremy
From: Marina Vatkina <marina.vatkina_at_oracle.com>
To: jsr345-experts_at_ejb-spec.java.net,
Date: 09/12/2012 08:48 PM
Subject: [jsr345-experts] Interrupting async invocation on
Future.cancel request?
Experts,
I was looking at the rules for canceling long-running async methods in
the current spec, and if and how we can improve them.
This is what the EJB spec says on the subject (see
3.4.8.1.1Future.cancel):
1) "If a client calls cancel on its Future object, the container will
attempt to cancel the associated asynchronous invocation /only/ if that
invocation has not already been dispatched".
2) "If the mayInterruptIfRunning flag is set to true, then subsequent
calls to the SessionContext.wasCancelCalled method from within the
associated dispatched asynchronous invocation must return true. [...] If
the dispatched asynchronous method does decide to short circuit its
processing as a result of checking SessionContext, it the responsibility
of the Bean Provider to decide how to convey that information to the
client"
I.e. after the method had started execution, the container is not
expected to do anything, even if the mayInterruptIfRunning flag is set
to true, and it becomes a bean provider responsibility to implement
support for cancellation that would look like this:
while (true) {
doNextPart();
if (sctx.wasCancelCalled())
break;
else
doSomethingElse();
}
Which might be good enough, but I am interested in your opinion on
adding support for interrupting the thread of execution if the method
invocation had already started when the Future.cancel is called?
Please let me know if:
a) You think, it is good enough and we should not make any changes to
the Future.cancel handling
b) You think that we should add the following statement to the spec (and
modify the current statements accordingly): "If a client calls
cancel(true) on its Future object while the associated asynchronous
invocation is in progress, the container will interrupt the thread of
execution. It is the responsibility of the Bean Provider to handle
InterrupedException or check the thread interrupted state and decide how
to convey that information to the client".
c) In addition to (b), require the EJB container to throw an exception
(InterrupedException or EJBException) if an interrupted thread attempts
to invoke an EJB method that the container interposes on.
thanks,
-marina