Является ли bean-компонент @Singleton Session правильным местом для управления объектами в разных сеансах?

Я все еще изучаю подходящие шаблоны Java EE и был бы признателен за совет о лучших инструментах для решения этой проблемы.

У меня есть система, которой нужно управлять несколькими экземплярами интеллектуальных агентов. Клиенты могут создать новый экземпляр или получить доступ к нужному экземпляру по имени. Несколько клиентов могут получить доступ к одному и тому же агенту одновременно.

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

GET  /sessions/
POST /sessions/{name}
PUT  /sessions/{name}/doanaction

Эти сеансы не будут сохраняться после перезапуска, поэтому я не ищу управление ресурсами.

Моя мысль заключалась в том, что мы могли бы использовать сеансовый компонент @Singleton для управления сопоставлением имен с агентами, а затем внедрить его в сеансовые компоненты @Stateless, которые предоставили бы служебные методы веб-службам REST.

Я хочу убедиться, что я не злоупотребляю здесь @Singleton. Поскольку несколько клиентов могут получить доступ к одному и тому же агенту, похоже, нет никакого способа использовать управление сеансами Java EE для облегчения управления объектами между сеансами. Существуют ли другие инъекционные объекты, которые я должен использовать помимо компонента @Singleton Session? Это вообще правильный подход к этой проблеме? Советы приветствуются!


person Alex Pritchard    schedule 19.02.2014    source источник


Ответы (1)


Я не думаю, что какой-либо из готовых механизмов EJB хорошо подходит для понятия агента — объекта с состоянием и собственным жизненным циклом на сервере, доступного нескольким клиентам одновременно.

Сеансовые компоненты без состояния не имеют состояния, а сеансовые компоненты с состоянием предназначены только для одного клиента.

Таким образом, возможная схема заключалась бы в том, чтобы извлечь состояние из агента в объект AgentState. Затем сохраните состояние каждого агента в ConcurrentHashMap, индексированное по имени агента. Хэш-карту можно обернуть в bean-компонент @Singleton.

Затем код контроллера REST может получить состояние агента по имени, на лету создать экземпляр агента, new MyAgent(agentState) передав ему состояние, а затем выполнить некоторую операцию.

Состояние агента может одновременно извлекаться из кэша несколькими клиентами. Ключ в том, что код MyAgent должен предотвратить повреждение состояния агента, получая блокировку объекта агента всякий раз, когда он выполняет составные операции:

класс MyAgent {

public void someCompoundOperation() {
    synchronized (agentState) {
        ...
        String propertyA = agentState.getPropertyA();
        ... compare A with something

        agentState.setPropertyA(newA);
        ...
    }
}

Это предотвратит состояние гонки, когда два клиента считывают одно и то же значение свойства и одновременно выполняют действие вместо того, чтобы ждать, пока другой агент завершит работу и сбросит состояние агента.

person Angular University    schedule 19.02.2014
comment
Спасибо, именно такой подход я и предполагал. Есть ли способ позволить ejb распределять экземпляры агентов по нескольким машинам, как это можно сделать с помощью сеансовых компонентов @Remote? - person Alex Pritchard; 20.02.2014
comment
Я также ценю предостережение относительно синхронизированного доступа. Очень полезная информация! - person Alex Pritchard; 20.02.2014
comment
Я рад, что смог помочь. для кластеризации, возможно, лучше хранить состояние агента в базе данных, если возникает проблема с запросом его каждый раз, то можно настроить кластеризованный транзакционный кеш второго уровня docs.jboss.org/jbossclustering/cluster_guide/5.1/html/, хотя этот тип кеша обычно является платным продуктом. - person Angular University; 20.02.2014