users@glassfish.java.net

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

From: Reza Rahman <reza.rahman_at_oracle.com>
Date: Mon, 11 Aug 2014 10:49:28 -0500

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
>>
>
>
>
> --
> Dennis Gesker