Question

I am still learning about appropriate Java EE patterns and would appreciate advice on the best tools to use for this problem.

I have a system that needs to manage a number of instances of intelligent agents. Clients can create a new instance or access a desired instance by name. Multiple clients can access the same agent at once.

Our plan is to expose operations to the agents via a REST interface, so a call might be something like:

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

These sessions wouldn't persist past restart, so I'm not looking for Resource management.

My thought was that we could use a @Singleton Session bean to manage the mapping of names to agents and then inject that into the @Stateless session beans that would provide the utility methods to the REST web services.

I want to make sure I'm not misusing @Singleton here. Because multiple clients can access the same agent, there doesn't seem to be any way to use Java EE Session management to facilitate object management across sessions. Are there other injectable objects I should use besides a @Singleton Session bean? Is this generally the correct approach to use for this problem? Tips appreciated!

Était-ce utile?

La solution

I dont't think any of the out of the box mechanisms of EJB is a good fit for the notion of agent - a stateful entity with it's own lifecycle in the server, accessible to multiple clients at the same time.

Stateless session beans have no state, and stateful session beans are meant only for one client.

So a design possible would be to extract the state from the agent into a AgentState object. Then store the state of each agent in a ConcurrentHashMap, indexed by agent name. The hash map could be wrapped in a @Singleton bean.

The REST controller code could then retrieve the agent state by name, instantiate on the fly an agent new MyAgent(agentState) passing it the state, and then do some operation.

The agent state can be concurrently retrieved from the cache by several clients. The key is the MyAgent code needs to prevent corruption of the agent state, by getting a lock on the agent object whenever it's executing compound operations:

class MyAgent {

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

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

This will prevent race conditions when two clients read the same value of a property, and concurrently take an action instead of waiting for the other agent to finish and release the agent state.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top