users@ejb-spec.java.net

[ejb-spec users] [jsr345-experts] Re: Interrupting async invocation on Future.cancel request?

From: Marina Vatkina <marina.vatkina_at_oracle.com>
Date: Tue, 09 Oct 2012 15:08:59 -0700

Carlo,

Carlo de Wolf wrote:
> On 09/09/2008 09:55 PM, Kenneth Saks wrote:
>>>
>>> If the method is already started and mayInterruptIfRunning is true,
>>> the executing thread is interrupted. Right?
>>
>> We can't have the container just stop the thread of an active
>> business method while it's executing. It would leave the
>> instance in an unknown state and likely break data integrity. The
>> bean developer at least has the option of explicitly
>> checking isCancelled() and exiting gracefully.
>
> By nature session beans are not transactional themselves. If they
> would be backed by transactional memory, then yes I would be in favor
> of having them interrupted. In the proposal it would force the burden
> of maintaining data integrity onto the bean developer by use of the
> thread API.

It will be up-to the bean developer to code a reaction to thread
interruption (see my response to Alex). Without that, nothing will
happen with the executing method.
>
> Hence we went for the wasCancelCalled option. Note that there was a
> valid comment by David Lloyd that the usage of j.u.c.Future in that
> regard is an abomination, but alas that is all history.

I'll try to search for the details of the 3.1 EG discussion.

thanks,
-marina

>
> Carlo
>
> On 09/25/2012 11:03 PM, Marina Vatkina wrote:
>> Jeremy,
>>
>> I understand your concern. My counter-argument is that support for
>> thread interruption is a basic Java SE feature, and it will be
>> counter-intuitive to require bean providers to opt-in into it.
>>
>> But I'm definitely interested in other opinions (even if they are "do
>> not have a preference").
>>
>> thanks,
>> -marina
>>
>> Jeremy Bauer wrote:
>>> Marina,
>>>
>>> I agree that this is a useful feature. My primary concern is that
>>> enabling the new behavior by default may break existing
>>> applications. Before giving it a +1, I'd like to hear a contrary
>>> argument or that we'll gate the feature, with the new behavior being
>>> non-default.
>>>
>>> -Jeremy
>>>
>>>
>>>
>>> From: Marina Vatkina <marina.vatkina_at_oracle.com>
>>> To: jsr345-experts_at_ejb-spec.java.net,
>>> Date: 09/24/2012 06:53 PM
>>> Subject: [ejb-spec users] [jsr345-experts] Re: Interrupting
>>> async invocation on Future.cancel request?
>>> ------------------------------------------------------------------------
>>>
>>>
>>>
>>>
>>> Jeremy, Experts,
>>>
>>> I think it is very useful to require the EJB container to interrupt the
>>> running thread on Future.cancel(true) call. It will not only allow the
>>> code that has no access to the SessionContext to short-circuit the long
>>> running process, but follow more closely the coding patterns in a
>>> non-Java EE applications.
>>>
>>> Please let me know if you think otherwise.
>>>
>>> For the reference, this is the description of the outcome of the
>>> Thread.interrupt call:
>>> http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupt()
>>> <http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupt%28%29>
>>>
>>>
>>> -marina
>>>
>>> Marina Vatkina wrote:
>>> > Hi Jeremy,
>>> >
>>> > Jeremy Bauer wrote:
>>> >> 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.
>>> > If the code doesn't have the Thread.isInterrupted() check, nothing
>>> > wrong would happen, it will continue executing as before. Are you
>>> > concerned about the code that the async method may be invoking
>>> > directly or indirectly and which is already written to catch the
>>> > InterrupedException, and rethrow it or throw another exception
>>> > instead? That code would benefit from a short-circuit behavior
>>> because
>>> > it will be able to avoid extra processing.
>>> >
>>> > Another reason for supporting the Thread.isInterrupted() check is
>>> that
>>> > it is available to any code that can be called by the async method
>>> > (vs. SessionContext that needs to be passed around explicitly).
>>> >
>>> >> 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.
>>> >
>>> >
>>> > I would expect that JDBC resources to know how to handle an
>>> > interruption, and not leave themselves in a bad state (as apposed to
>>> > killing the thread, that is indeed a bad idea).
>>> >
>>> >>
>>> >> 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.
>>> >
>>> > We can do that, but Future.cancel should not be called with
>>> > mayInterruptIfRunning=true if the code is not ready to be
>>> interrupted...
>>> >
>>> > But I'd be interested what others think, in particular those who work
>>> > on the application part of the world...
>>> >
>>> > thanks,
>>> > -marina
>>> >>
>>> >> -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
>>> >>
>>> >>
>>> >>
>>>
>>>
>