Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Асинхронные методы в EJB и проверка прерывания потока / 21 сообщений из 21, страница 1 из 1
05.02.2013, 14:55:12
    #38138068
rabiter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
Доброго дня!

Вот же а... Хочу в асинхронном методе Stateless бина проверять, был ли прерван поток. Для этого как и написано в спеке, использую sessionContext.wasCancelCalled(). Работает в асинхронном методе нормально. Но стоит мне в асинхронный метод заинжектить другой бин и попробовать в этом бине проверить wasCancelCalled, как он бросает исключение:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
@Stateless
public class TheService {
    @Resource
    private SessionContext sessionContext;   
    @EJB
    private AnotherService anotherService;
    @Asynchronous
    public Future<String> doAsync() { // начинаю выполнение с вызова этого метода
        sessionContext.wasCancelCalled(); // ok
        anotherService.doSomeActivitiesInAnotherService();                
        return ...
    }
}

@Stateless
public class AnotherService {   
    @Resource
    private SessionContext sessionContext;
    public void doSomeActivitiesInAnotherService() {
        // some activity
        sessionContext.wasCancelCalled(); // throws a java.lang.IllegalStateException: Must be invoked from an async method.
        // some activity
    }
}



Т.е. я хочу чтобы у меня контейнер создал отдельный поток для выполнения, в этот поток я могу заинжектить обычный stateless бин, он так же будет выполняться в этом новом созданном потоке (ну логично, да?).
Но я не смогу проверить, был ли прерван поток. А вся нагрузка, основной цикл вычислений, у меня как раз находится в этом бине, который я инжектю в асинхронный метод. Вот же подстава.
...
Рейтинг: 0 / 0
05.02.2013, 15:10:47
    #38138098
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
Почему бы явно значение не передавать, если оно вам необходимо?
...
Рейтинг: 0 / 0
05.02.2013, 15:18:11
    #38138121
rabiter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
BlazkowiczПочему бы явно значение не передавать, если оно вам необходимо?

Прошу прощения, какое значение? Я не понял. Проблема в том, что я хочу в асинхронный метод заинжектить другой бин и вызвать метод на этом бине. Метод вызовется, но проверить в нем sessionContext.wasCancelCalled() не получится, а мне очень хочется это сделать.
...
Рейтинг: 0 / 0
05.02.2013, 15:22:03
    #38138132
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
rabiter,

public void doSomeActivitiesInAnotherService(boolean canceled) {
...
Рейтинг: 0 / 0
05.02.2013, 15:34:50
    #38138158
rabiter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
Blazkowiczrabiter,

public void doSomeActivitiesInAnotherService(boolean canceled) {

Так нет же. SessionContext.wasCancelCalled() это метод с помощью которого можно проверить была ли прервана таска или нет. Прерывается таска вызовом Future.cancel(true). Метод doSomeActivitiesInAnotherService может выполнятся минут 30, и на 15-й минуте быть прерванным. И предполагается что я там периодически буду опрашивать wasCancelCalled чтобы выявить факт отмены задания. Это что-то вроде Thread.interrupted().

Смысл такой:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
@Stateless
public class AnotherService {   
    @Resource
    private SessionContext sessionContext;
    public void doSomeActivitiesInAnotherService() {
        for (...) {
          // всякие вычисления долгие долгие
          if(sessionContext.wasCancelCalled()) { // каждый раз (или каждые N раз) я проверяю не было ли отменено задание
              throw new CancellationExceptoin();
          };
        }
    }
}



Но проблема в том, что я не могу вызвать sessionContext.wasCancelCalled в этом методе. Потому что я этот метод вызвал через прокси AnotherService. И видимо контейнер считает что я изменил контекст выполнения или что-то в этом роде.
При попытке ругается java.lang.IllegalStateException: Must be invoked from an async method.
...
Рейтинг: 0 / 0
05.02.2013, 15:42:39
    #38138180
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
Я не могу понять откуда есть такая уверенность что у двух разных stateless бинов SessionContext как-то вообще связан?
Так как это всё локально, ну передайте ссылку на локальный интефейс параметром:
public void doSomeActivitiesInAnotherService(TheService initiator)
и сделайте метод для обращения к его SessionContext-у.
...
Рейтинг: 0 / 0
05.02.2013, 16:07:27
    #38138242
rabiter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
BlazkowiczЯ не могу понять откуда есть такая уверенность что у двух разных stateless бинов SessionContext как-то вообще связан?
Так как это всё локально, ну передайте ссылку на локальный интефейс параметром:
public void doSomeActivitiesInAnotherService(TheService initiator)
и сделайте метод для обращения к его SessionContext-у.

Точно, вы абсолютно правы. Такая уверенность ошибочна, SessionContext у разных бинов, конечно же разный.
Но и вариант что вы предложили тоже не работает. Если я передаю ссылку на TheService initianor, потом получаю его sessionContext, то это уже не sessionContext бина TheService, это будет уже SessionContext бина AnotherService. При вызове на нем wasCancelCalled валится все то же исключение.
Я так это понимаю: sessionContext - прокси, и контейнер во время выполнения определяет к какому именно sessionContext обращаться. Таким финтом с передачей sessionContext или TheService initial входным параметром его не проймешь.
...
Рейтинг: 0 / 0
05.02.2013, 16:09:54
    #38138248
rabiter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
BlazkowiczТак как это всё локально, ну передайте ссылку на локальный интефейс параметром:
public void doSomeActivitiesInAnotherService(TheService initiator)

Вы ведь имеете ввиду передавать ссылку как this?
Код: java
1.
anotherService.doSomeActivitiesInAnotherService(this);
...
Рейтинг: 0 / 0
05.02.2013, 16:11:35
    #38138253
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
Что мешает просто создать именованный поток, потом при необходимости найти его по имени и проверить состояние?
...
Рейтинг: 0 / 0
05.02.2013, 16:14:56
    #38138259
rabiter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
ivanraЧто мешает просто создать именованный поток, потом при необходимости найти его по имени и проверить состояние?

Просто Thread через new? Ну я же должен работать согласно спеке. Надо чтобы все потоки создавал EJB контейнер, так как у него есть для них пул и все такое.
...
Рейтинг: 0 / 0
05.02.2013, 16:18:40
    #38138272
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
rabiterНо и вариант что вы предложили тоже не работает. Если я передаю ссылку на TheService initianor, потом получаю его sessionContext, то это уже не sessionContext бина TheService, это будет уже SessionContext бина AnotherService. При вызове на нем wasCancelCalled валится все то же исключение.

Я так это понимаю: sessionContext - прокси, и контейнер во время выполнения определяет к какому именно sessionContext обращаться. Таким финтом с передачей sessionContext или TheService initial входным параметром его не проймешь.

Это какая-то не правдоподобная фигня. Даже если sessionContext это прокси, то вызов всё равно находится в том же потоке что и
sessionContext.wasCancelCalled(); // ok
Это должна быть какая-то совершенно не вероятная магия, чтобы sessionContext внутри TheService поменялся на другой, в том же потоке.

Покажите код, что получилось.
...
Рейтинг: 0 / 0
05.02.2013, 16:23:45
    #38138288
rabiter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
BlazkowiczrabiterНо и вариант что вы предложили тоже не работает. Если я передаю ссылку на TheService initianor, потом получаю его sessionContext, то это уже не sessionContext бина TheService, это будет уже SessionContext бина AnotherService. При вызове на нем wasCancelCalled валится все то же исключение.

Я так это понимаю: sessionContext - прокси, и контейнер во время выполнения определяет к какому именно sessionContext обращаться. Таким финтом с передачей sessionContext или TheService initial входным параметром его не проймешь.

Это какая-то не правдоподобная фигня. Даже если sessionContext это прокси, то вызов всё равно находится в том же потоке что и
sessionContext.wasCancelCalled(); // ok
Это должна быть какая-то совершенно не вероятная магия, чтобы sessionContext внутри TheService поменялся на другой, в том же потоке.

Покажите код, что получилось.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
@Stateless
public class TheService {
    @Resource
    private SessionContext sessionContext;
    @EJB
    private AnotherService anotherService;
    @Asynchronous
    public Future<String> doAsync() {
        anotherService.doSomeActivitiesInAnotherService(this);
        return new AsyncResult<String>("ok");
    }
    public boolean wasCancelCalled() {
        return sessionContext.wasCancelCalled(); // здесь валится все то же исключение
    }
}
@Stateless
public class AnotherService {
    public void doSomeActivitiesInAnotherService(TheService initiator) {
        initiator.wasCancelCalled();
    }
}
...
Рейтинг: 0 / 0
05.02.2013, 16:30:43
    #38138310
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
А вызов
anotherService.doSomeActivitiesInAnotherService();
точно через локальный интерфейс идёт? или через remote?
...
Рейтинг: 0 / 0
05.02.2013, 16:32:09
    #38138316
rabiter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
Это какая-то не правдоподобная фигня. Даже если sessionContext это прокси, то вызов всё равно находится в том же потоке что и
sessionContext.wasCancelCalled(); // ok
Это должна быть какая-то совершенно не вероятная магия, чтобы sessionContext внутри TheService поменялся на другой, в том же потоке.

Поток хоть и тот же, но контекст-то уже другой, контекст-то уже принадлежит AnotherBean. И, похоже что когда я вызываю метод wasCancelCalled на бине TheService (который я передал как this), контекст все равно принадлежит AnotherBean.
...
Рейтинг: 0 / 0
05.02.2013, 16:35:10
    #38138327
rabiter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
BlazkowiczА вызов
anotherService.doSomeActivitiesInAnotherService();
точно через локальный интерфейс идёт? или через remote?

Точно через локальный. Т.е. я использую EJB 3.1 и вообще не указываю интерфейс. В этом случае если я не ошибаюсь, он считается локальным.
...
Рейтинг: 0 / 0
05.02.2013, 16:35:27
    #38138330
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
rabiterПоток хоть и тот же, но контекст-то уже другой, контекст-то уже принадлежит AnotherBean. И, похоже что когда я вызываю метод wasCancelCalled на бине TheService (который я передал как this), контекст все равно принадлежит AnotherBean.
А что за сервер? В исходники хочется посмотреть. Это какая мистика, как в том же потоке, контейнер вообще может узнать что рантайм уже в другом бине? callerClass что ли проверяет?
...
Рейтинг: 0 / 0
05.02.2013, 16:44:31
    #38138364
rabiter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
BlazkowiczrabiterПоток хоть и тот же, но контекст-то уже другой, контекст-то уже принадлежит AnotherBean. И, похоже что когда я вызываю метод wasCancelCalled на бине TheService (который я передал как this), контекст все равно принадлежит AnotherBean.
А что за сервер? В исходники хочется посмотреть.

Ну вот, сейчас мы сойдемся на том что гласфиш шляпа и на этом опять все обсуждения закончатся))

BlazkowiczЭто какая мистика, как в том же потоке, контейнер вообще может узнать что рантайм уже в другом бине? callerClass что ли проверяет?

Все выполняется в одном потоке. Контекста два. Один TheService, второй AnotherBean.
Изначально мы находимся в методе TheService#doAsync - первый контекст. Потом мы через прокси AnotherBean вызываем метод AnotherBean#doSomeActivitiesInAnotherService - тут контейнер переключает нас на второй контекст.
И наконец, мы через прокси (я же передал this, а по сути это ссылка на прокси TheService) переходим в метод TheService#wasCancelCalled() - тут контейнер почему-то не переключает нас обратно на первый контекст а оставляет во втором...
...
Рейтинг: 0 / 0
05.02.2013, 16:49:45
    #38138381
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
rabiterНу вот, сейчас мы сойдемся на том что гласфиш шляпа и на этом опять все обсуждения закончатся))

А я уже посмотрел. Но на поверхности ответа не увидел. Глубже копать пока некогда.

rabiterВсе выполняется в одном потоке. Контекста два. Один TheService, второй AnotherBean.
Изначально мы находимся в методе TheService#doAsync - первый контекст. Потом мы через прокси AnotherBean вызываем метод AnotherBean#doSomeActivitiesInAnotherService - тут контейнер переключает нас на второй контекст.
И наконец, мы через прокси (я же передал this, а по сути это ссылка на прокси TheService) переходим в метод TheService#wasCancelCalled() - тут контейнер почему-то не переключает нас обратно на первый контекст а оставляет во втором...
Люблю EJB, всё таким очевидным образом работает. :)

А если не в лоб, а по лбу?
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
@Stateless
public class TheService {
    @Resource
    private SessionContext sessionContext;
    @EJB
    private AnotherService anotherService;
    @Asynchronous
    public Future<String> doAsync() {
        anotherService.doSomeActivitiesInAnotherService(this);
        return new AsyncResult<String>("ok");
    }
    public boolean wasCancelCalled() {
        return sessionContext.wasCancelCalled(); // здесь валится все то же исключение
    }
}
@Stateless
public class AnotherService {
    @EJB
    private TheService callBack;

    public void doSomeActivitiesInAnotherService() {
        callBack.wasCancelCalled();
    }
}
...
Рейтинг: 0 / 0
05.02.2013, 16:58:16
    #38138409
rabiter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
BlazkowiczrabiterНу вот, сейчас мы сойдемся на том что гласфиш шляпа и на этом опять все обсуждения закончатся))

А я уже посмотрел. Но на поверхности ответа не увидел. Глубже копать пока некогда.

rabiterВсе выполняется в одном потоке. Контекста два. Один TheService, второй AnotherBean.
Изначально мы находимся в методе TheService#doAsync - первый контекст. Потом мы через прокси AnotherBean вызываем метод AnotherBean#doSomeActivitiesInAnotherService - тут контейнер переключает нас на второй контекст.
И наконец, мы через прокси (я же передал this, а по сути это ссылка на прокси TheService) переходим в метод TheService#wasCancelCalled() - тут контейнер почему-то не переключает нас обратно на первый контекст а оставляет во втором...
Люблю EJB, всё таким очевидным образом работает. :)

А если не в лоб, а по лбу?
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
@Stateless
public class TheService {
    @Resource
    private SessionContext sessionContext;
    @EJB
    private AnotherService anotherService;
    @Asynchronous
    public Future<String> doAsync() {
        anotherService.doSomeActivitiesInAnotherService(this);
        return new AsyncResult<String>("ok");
    }
    public boolean wasCancelCalled() {
        return sessionContext.wasCancelCalled(); // здесь валится все то же исключение
    }
}
@Stateless
public class AnotherService {
    @EJB
    private TheService callBack;

    public void doSomeActivitiesInAnotherService() {
        callBack.wasCancelCalled();
    }
}



Эх, думал уже об этом. Сразу скажу, что вылетает то же самое исключение. Но это вроде и понятно. Мы разве не создадим третий контекст выполнения когда заинжектим TheService initiator и вызываем на нем wasCancelCalled() ?
Как бы суметь вернуться именно к первому контексту. Вообщем я буду дальше смотреть, если найду решение, напишу тут.
...
Рейтинг: 0 / 0
05.02.2013, 16:59:38
    #38138416
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
rabiterКак бы суметь вернуться именно к первому контексту. Вообщем я буду дальше смотреть, если найду решение, напишу тут.
Я бы исходники GlassFish подебажил и посмотрел как он находит Future в InvocationContext.
...
Рейтинг: 0 / 0
05.02.2013, 17:06:22
    #38138441
rabiter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронные методы в EJB и проверка прерывания потока
BlazkowiczrabiterКак бы суметь вернуться именно к первому контексту. Вообщем я буду дальше смотреть, если найду решение, напишу тут.
Я бы исходники GlassFish подебажил и посмотрел как он находит Future в InvocationContext.

Спасибо за совет!
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Асинхронные методы в EJB и проверка прерывания потока / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]