2013-05-11 2 views
0

Что я делаю неправильно в этом простом примере? (Glassfish 4.0-B87 + Eclipse, Кеплер m6)Невозможно отменить @ Асинхронный вызов в EJB

Myself.java

package com.example.cancelbug; 

import java.util.concurrent.ExecutionException; 
import java.util.concurrent.Future; 

import javax.annotation.PostConstruct; 
import javax.annotation.PreDestroy; 
import javax.ejb.Singleton; 
import javax.ejb.Startup; 
import javax.inject.Inject; 

@Singleton 
@Startup 
public class Myself { 
    @Inject Other other; 
    private Future <Integer> future; 

    @PostConstruct 
    public void post_construct() { 
    System.out.println("post_construct started"); 
    future = other.ton_of_work(); 
    System.out.println("post_construct ended"); 
    } 

    @PreDestroy 
    public void pre_destroy() { 
    System.out.println("pre_destroy started"); 
    System.out.println("cancel result: " + Boolean.toString(future.cancel(true))); 
    try { 
     System.out.println("future result: " + future.get().toString()); 
    } catch (InterruptedException | ExecutionException e) { 
     System.out.println("future result: interrupted"); 
     Thread.currentThread().interrupt(); 
     System.out.println("thread reinterrupted"); 
    } 
    System.out.println("pre_destroy ended"); 
    } 
} 

Other.java

package com.example.cancelbug; 

import java.util.concurrent.Future; 

import javax.ejb.AsyncResult; 
import javax.ejb.Asynchronous; 
import javax.ejb.Stateless; 

@Stateless 
public class Other { 
    @Asynchronous 
    public Future <Integer> ton_of_work() { 
    System.out.println("other: ton_of_work started"); 
    int i; 
    for (i = 0; i < 10; ++i) { 
     try { 
     System.out.println("other: take a nap"); 
     Thread.sleep(1000L); 
     System.out.println("other: woke up: " + Integer.toString(i)); 
     } catch (InterruptedException e) { 
     System.out.println("other: ton_of_work interrupted"); 
     Thread.currentThread().interrupt(); 
     break; 
     } 
    } 
    System.out.println("other: ton_of_work returning"); 
    return new AsyncResult <Integer>(new Integer(i)); 
    } 
} 

Выходной

post_construct started 
post_construct ended 
other: ton_of_work started 
other: take a nap 
other: woke up: 0 
other: take a nap 
other: woke up: 1 
other: take a nap 
other: woke up: 2 
other: take a nap 
pre_destroy started 
cancel result: false   <<<<<<< expected true; ton_of_work: interrupted 
other: woke up: 3    <<<<<<< expected no such output 
other: take a nap    <<<<<<< expected no such output 
other: woke up: 4    <<<<<<< expected no such output 
other: take a nap    <<<<<<< expected no such output 
other: woke up: 5    <<<<<<< expected no such output 
other: take a nap    <<<<<<< expected no such output 
other: woke up: 6    <<<<<<< expected no such output 
other: take a nap    <<<<<<< expected no such output 
other: woke up: 7    <<<<<<< expected no such output 
other: take a nap    <<<<<<< expected no such output 
other: woke up: 8    <<<<<<< expected no such output 
other: take a nap    <<<<<<< expected no such output 
other: woke up: 9    <<<<<<< expected no such output 
other: ton_of_work returning 
future result: 10    <<<<<<< expected 2 
pre_destroy ended 

Ожидаемые результаты:

post_construct started 
post_construct ended 
other: ton_of_work started 
other: take a nap 
other: woke up: 0 
other: take a nap 
other: woke up: 1 
other: take a nap 
other: woke up: 2 
other: take a nap 
pre_destroy started 
cancel result: true    <<<<<<< actual false 
other: ton_of_work interrupted <<<<<<< actual missing 
other: ton_of_work returning 
future result: 2    <<<<<<< actual 10 
pre_destroy ended 
+0

Injecting '@Resource SessionContext session_context;' и вызов 'session_context.wasCancelCalled()' возвращает true, но не прерывает 'sleep' или другой блокирующий вызов, поэтому больно сделать логику приложения также опросом статус достаточно часто. – necromancer

ответ

8

EJB 3.1 обеспечивает только совместные асинхронные прерывания; то есть EJB может проверить, вызвал ли клиент отмену. Невозможно получить фактический Thread.interrupt, даже если вызывается Future.cancel (true).

Существует проблема с выпуском EJB открытого типа (EJB_SPEC-73), чтобы разрешить фактические прерывания потока. Это обсуждалось в группе экспертов EJB 3.2 (1, 2, 3, 4, 5, 6), но обсуждение в конечном итоге было отложено до следующей версии спецификации EJB.

+0

Благодарю вас за авторитетный и полный ответ! – necromancer

 Смежные вопросы

  • Нет связанных вопросов^_^