I'm designing an operation in an EJB environment that involves many tasks, which can be done concurrently.
I need a controller:
- that tracks each of these tasks and allows each task to register information about the task including its completion.
- The controller would need to be synchronised allowing only one task to update its status at a time.
- Tracking the status involves maintaining complex objects rather than just a set of flags, so my controller really needs to be some kind of java object which stores the status in a set of objects, rather than storing the status in a database table.
I was planning on using JMS and Message Driven Beans to allow each of the tasks to run in its own thread. However, I don't know how to implement the controller. I was thinking of using a stateful session bean, whose handle could be passed to each of the MDBs, but I learn now that concurrent access to a stateful session bean's methods is not allowed by the spec (though some containers e.g. WebLogic, do support it through a proprietary extension).
Can anyone else suggest a better approach to this problem?
I have seen something similar done where the controller was itself an MDB and it used a reply queue and messages to synchronize updates on the controller. The controller MDB fired off the first task, then sat waiting on the reply queue to manage the state. However, I don't really like the idea of having an MDB active for the duration of the operation, as it could be quite long-lived (few seconds to an hour). My experience with MDBs is the number of 'consumers' (think that's the right term) used to service the MDBs is a limited resource, and we've had problem with contention on these consumers, so tying up a consumer for a long time is a bad idea.
My solution also needs to work in a clustered environment.
You're right that you cannot share the same SFSB for concurrency purposes. Perhaps you can use an RMI controller with your own (hand-rolled) synchronization blocks? You could register it in JNDI instead of the RMI registry. You'd then be looking up a single pre-instantiated controller object which implemented your own threading policy.
Maybe you can help me understand that a bit better. So if I implemented an RMI object with synchronized blocks, the synchronization would work even if the state update requests to the rmi object came from different nodes on the cluster. Would a remote rmi update on the object that hit a sync lock wait until the lock was released.
Remember that there would be at least two threads (client and server). How they map onto each other is indeterminate, because the RMI spec does not mandate a thread dispatching policy. But I would expect the client stub to block until it got a response from the server, unless the expected return type of a call is void, in which case it should continue.
Based on the constraints you had indetified, the RMI approach will be the best possible one. However have a question for you, why do you feel it is important for you to store in the information of state in memory and not the DB. Because if you have an appropriate Level2 and 3 data cache in the system the DB hits will be minimised. Is it just that you still have not considered any data caching solutions?
can handle this and more. It might be worth checking out.
: Cluster your Work. Work your Cluster.
Well exactly the point I was trying to make.
Nice agressive sales push ;)
The main reason for not storing the state in a database, is that the state is itself made up of a bunch of fairly complex value objects. Different tasks may register different value objects. As tasks complete and dependencies are resolved, then the value objects will be persisted to the database. However, in the meantime it seems simpler to keep them in memory.
Ok that sheds some light into the matter.
One alternative mechanism to streamline that would be to associate a WorkID to the overall set of tasks and consolidate them based on it. Each task can have an identifier too which is a derivative of the WorkID.
I know allot of people have aversions towards having too many ID's to track in the system, but IMHO it is still an effective mechanism to correlate information.
Let us know if you find a way around this, I'll be very interested in learning how you have solved the problem.
Another potentially technology to involve could be JDO. Then you dont have to go through the pains of dealing with VO's and some commercial implementations like JDO Genie and KODO also provide native integration to Caching systems like the one provided by Tangosol.