users@glassfish.java.net

[gf-users] Re: Future get() method behavior

From: Dennis Gesker <dennis_at_gesker.com>
Date: Mon, 11 Aug 2014 10:25:17 -0600

Yes. That's the rub. It doesn't.

The future.get()'s should hold things up but they don't. B.1 executes
before A.1

I tried the same code with 4.1 b11 and got the same behavior.

2 methods at:
http://pastebin.com/tLuaWNBu

Dennis




On Mon, Aug 11, 2014 at 9:49 AM, Reza Rahman <reza.rahman_at_oracle.com> wrote:

> I'm not sure I follow A1 will always follow B1 as
> processRelatedProjectData is synchronous. What am I missing? Can you kindly
> post a complete non-working sample that can be independently tested? You
> would need that anyway if this is a bug.
>
> Sent from my iPhone
>
> On Aug 8, 2014, at 9:48 AM, Dennis Gesker <dennis_at_gesker.com> wrote:
>
> [Note: Forgot to take out company names in last post]
>
> That blocking behavior is what I expected but not exactly/always what I'm
> getting.
>
> When I call *(A) refresh* from another class using @Schedule (in my ejb)
> the value of *count* in *refresh* is correct and statement *(B.1) *executes
> before
>
> * (A.1). *
> However, when I call *(A) refresh* from an @ApplicationScoped bean (in my
> war) the value of *count* in *refresh* is *incorrect* and statement *(A.1)
> *executes before* (B.1)*. Most of the time *(B.1)* doesn't execute at
> all. In this scenario count always has a different count and NO exception
> is thrown. Its like it just gives up.
>
>
> *Method that kicks off the process *
> *(A) *public void *refresh*(String usr){
>
> // Bunch house cleaning
> count = count + processRelatedProjectData();
> //...
> logger.log(Level.INFO, "\tExit refresh"); <-- Last statement before exit
> *(A.1)*
>
> }
>
> *Method that uses the @Asynchronous methods*
> *(B) *private Integer *processRelatedProjectData*() {
>
> Future futureA = processProject.processData(Constant.COMPANY_A);
> Future futureB = processProject.processData(Constant.COMPANY_B);
> Future futureC = processProject.processData(Constant.COMPANY_C);
> //... A bunch of these
>
> try {
> count = count + (Integer) futureA.get();
> count = count + (Integer) futureB.get();
> count = count + (Integer) futureC.get();
> //... A bunch of these
>
> } catch (InterruptedException | ExecutionException |
> CancellationException ex) {
> throw new IllegalStateException("Cannot get the answer", ex);
> }
>
> logger.log(Level.INFO, "\tEnter processRelatedProjectData"); <-- Last
> statement before exit *(B.1)*
> }
>
> Dennis
>
>
> On Fri, Aug 8, 2014 at 8:47 AM, Dennis Gesker <dennis_at_gesker.com> wrote:
>
>> That blocking behavior is what I expected but not exactly/always what I'm
>> getting.
>>
>> When I call *(A) refresh* from another class using @Schedule (in my ejb)
>> the value of *count* in *refresh* is correct and statement *(B.1) *executes
>> before
>>
>> * (A.1). *
>> However, when I call *(A) refresh* from an @ApplicationScoped bean (in
>> my war) the value of *count* in *refresh* is *incorrect* and statement *(A.1)
>> *executes before* (B.1)*. Most of the time *(B.1)* doesn't execute at
>> all. In this scenario count always has a different count and NO exception
>> is thrown. Its like it just gives up.
>>
>>
>> *Method that kicks off the process *
>> *(A) *public void *refresh*(String usr){
>>
>> // Bunch house cleaning
>> count = count + processRelatedProjectData();
>> //...
>> logger.log(Level.INFO, "\tExit refresh"); <-- Last statement before exit
>> *(A.1)*
>>
>> }
>>
>> *Method that uses the @Asynchronous methods*
>> *(B) *private Integer *processRelatedProjectData*() {
>>
>> Future futureA = processProject.processData(Constant.COMPANY_A);
>> Future futureB = processProject.processData(Constant.COMPANY_B);
>> Future futureC = processProject.processData(Constant.COMPANY_C);
>> //... A bunch of these
>>
>> try {
>> count = count + (Integer) futureEZLNE.get();
>> count = count + (Integer) futureMONKL.get();
>> count = count + (Integer) futureALAMN.get();
>> //... A bunch of these
>>
>> } catch (InterruptedException | ExecutionException |
>> CancellationException ex) {
>> throw new IllegalStateException("Cannot get the answer", ex);
>> }
>>
>> logger.log(Level.INFO, "\tEnter processRelatedProjectData"); <-- Last
>> statement before exit *(B.1)*
>> }
>>
>> Dennis
>>
>>
>> On Fri, Aug 8, 2014 at 6:05 AM, Reza Rahman <Reza.Rahman_at_oracle.com>
>> wrote:
>>
>>> Please share code snippets annotating/explaining the issue. It's
>>> really hard to follow the description. Future.get will return as soon as
>>> there is a value to be returned from the underlying @Asynchronous method
>>> and should block until then, but no longer.
>>>
>>>
>>> On 8/6/2014 2:53 PM, Dennis Gesker wrote:
>>>
>>> I have an EJB method (in an EJB module within my EAR) which calls
>>> several other @Asynchronous methods in other classes which of course return
>>> a Future.
>>>
>>> In the calling method I issue get() statements so that I can use the
>>> returned value in a calculation. Nothing fancy there.
>>>
>>> I've been running this routine from @Schedule (once per day) method
>>> with no issues. Runs quickly (about 20 min) and reliably and returns the
>>> correct result -- an integer of record counts.
>>>
>>> However, when I try to run this same routine from my web module (within
>>> the same EAR) from within an @ApplicationScoped bean the method that calls
>>> the @Asynchronous methods returns/completes *before* the future.get()
>>> method called completes and returns a value. No exception is thrown.
>>>
>>> Shouldn't a Future.get() call just block/wait until its work is
>>> complete regardless of how its called? Is a different behavior to be
>>> expected when called from a web module? Perhaps some kind of implied
>>> timeout?
>>>
>>> I could use a hint.
>>>
>>> NetBeans 8 and JDK 1.8.0_11 and Glassfish 4.0.1 promoted build 10
>>> (July-29) on Win8.1 Pro 64
>>>
>>> Dennis
>>>
>>>
>>>
>>
>>
>> --
>> *Dennis Gesker*
>> <http://goog_777861789>[image: www.linkedin.com/in/gesker]
>> <http://www.linkedin.com/in/gesker>[image:
>> http://www.facebook.com/gesker] <https://www.facebook.com/gesker>[image:
>> https://twitter.com/gesker] <https://twitter.com/gesker>[image:
>> http://gesker.wordpress.com] <http://gesker.wordpress.com>[image:
>> https://pgp.mit.edu/pks/lookup?search=dennis%40gesker.com&op=index]
>> <https://pgp.mit.edu/pks/lookup?search=dennis%40gesker.com&op=index>[image:
>> http://www.gesker.com] <http://www.gesker.com>[image: dennis@gesker.com]
>> <dennis_at_gesker.com>
>>
>
>
>
> --
> *Dennis Gesker*
> <http://goog_777861789>[image: www.linkedin.com/in/gesker]
> <http://www.linkedin.com/in/gesker>[image: http://www.facebook.com/gesker]
> <https://www.facebook.com/gesker>[image: https://twitter.com/gesker]
> <https://twitter.com/gesker>[image: http://gesker.wordpress.com]
> <http://gesker.wordpress.com>[image:
> https://pgp.mit.edu/pks/lookup?search=dennis%40gesker.com&op=index]
> <https://pgp.mit.edu/pks/lookup?search=dennis%40gesker.com&op=index>[image:
> http://www.gesker.com] <http://www.gesker.com>[image: dennis@gesker.com]
> <dennis_at_gesker.com>
>
>


-- 
*Dennis Gesker*
<http://goog_777861789>[image: www.linkedin.com/in/gesker]
<http://www.linkedin.com/in/gesker>[image: http://www.facebook.com/gesker]
<https://www.facebook.com/gesker>[image: https://twitter.com/gesker]
<https://twitter.com/gesker>[image: http://gesker.wordpress.com]
<http://gesker.wordpress.com>[image:
https://pgp.mit.edu/pks/lookup?search=dennis%40gesker.com&op=index]
<https://pgp.mit.edu/pks/lookup?search=dennis%40gesker.com&op=index>[image:
http://www.gesker.com] <http://www.gesker.com>[image: dennis@gesker.com]
<dennis_at_gesker.com>