Persistence and the Server Lifecycle

throw new OverdraftExceptionfalse; } return; } public void unreferenced { if null==_factory { return; } try { _factory.serverNoLongerActive_accountName; } catchRemoteException e { Factory is having issues} _factory = null; } }

17.4.2.3 The launch code and the client

The launch code and the client for this version of the bank example are essentially the same as they were for the version based on BasicAccountFactory_Impl . The only difference is that BankClientFrame s releaseAccount method no longer needs to tell the factory that it is done with a particular account server. releaseAccount is accordingly much simpler: private void releaseAccount { _account=null; return ; }

17.5 Persistence and the Server Lifecycle

Weve been talking about factories as convenient generalizations of the idea of a naming service: a factory is just a naming service that can launch servers. Another way to think about the idea of a factory server is that its really a generalization of the idea of a class object. That is, the factories weve been implementing are objects with a set of constructors and maintain information about all the instances of Account , much the same way that a class object can have static information that is not specific to any particular instance of the class. Weve already come close to this idea with LockingFactory_Impl . It also allows a client to lock a set of servers in a single method call. The next step is to note that LockingFactory_Impl can also, should we so desire, control other aspects of the servers lifecycle. Suppose, for example, we were to change the definition of serverNoLongerActive to the following: public void serverNoLongerActiveString accountName, Remote server throws RemoteException; The factory now gets both the name of the server and a stub to the server when the server is otherwise unreferenced. At which point, the factory can do things such as: Implement a simple external persistence layer. That is, the factory can query the server for state information, which the factory then stores in a relational database before the server is garbage collected. Tell the server to persist itself. This is a more object-oriented version of the first point. If theres no real reason the factory ought to know anything about the servers state, the persistence code probably belongs inside Account_Impl . Keep the stub inside an indexed data structure in case it is needed again. By doing this, the factory keeps the server up and running. This is a potential performance optimization, based on the idea that a certain percentage of users forget to perform a transaction and wind up requesting the server a second time. • In this model, the factory tracks resource consumption and releases unused servers either after a significant period of time e.g., they arent being used by any client and havent been requested in 20 minutes or if resources become tight. The essential point is simple: if you have something that creates objects, and knows when theyre due for garbage collection, as LockingFactory_Impl does, then you have a perfect place to insert code that performs all sorts of secondary maintenance tasks. Really interested in this idea? Check out the Enterprise JavaBeans specification or see Enterprise JavaBeans, Second Edition by Richard Monson-Haefel OReilly. An Enterprise JavaBeans container is a variation on this design, with explicitly labelled hooks for persistence and transactional control.

17.6 Activation