On Thu, Oct 9, 2008 at 10:36 AM, André Warnier <[EMAIL PROTECTED]> wrote:
> Leon Rosenberg wrote:
>>
>> On Thu, Oct 9, 2008 at 9:59 AM, André Warnier <[EMAIL PROTECTED]> wrote:
>>>
>>> I realise that this can be done via e.g. an external DB.
>>> It could also probably be done, most portably, by creating an entirely
>>> separate application accessed via HTTP calls e.g. (à la "Amazon DB" ?).
>>> But it looks as if "within the same container", it would be much more
>>> efficient if kept in local memory, and avoiding overhead like TCP/IP or
>>> JDBC
>>> or RMI.
>>>
>>> Not being an expert in any of the underlying matters, I would just like
>>> to
>>> know from the eperts here, but preferably without too many difficult
>>> words
>>> like "classloader" and "dispatchers", if this is in theory
>>> possible/allowed,
>>> if it could be done in such a way as to be portable to a different
>>> container
>>> etc..
>>
>> Well, it is possible by placing stuff in shared/lib and access it from
>> different contextes, but it will make your life extremely complicated,
>> especially if you start to reload applications on the fly, probably
>> causing an outofmemory exception at some point.
>> On the other side an rmi connection on the local machine is extremely
>> cheap (same applies to corba), if you make one call to rmi (or corba)
>> in one request to the application you won't even be able to measure
>> the transport overhead (far below 1 ms), and taking in account that
>> transport from browser to server is much much slower, you can ignore
>> the overhead. The overhead of http or soap is much higher due to
>> larger footprint of the call, parsing, connection issues (you have to
>> reconnect or handle keep alives yourself) and so on.
>> Behind your rmi service you can have an external db or just a hashmap
>> (concurrent one) or whatever serves best.
>> To sum it up, the TOC (total cost of ownership) of an RMI service are
>> much much lower as of most other solutions.
>>
> Many thanks.
> So, assuming that I am now convinced by RMI (Remote Method Invocation ?),
> how would such a scheme be implemented ?
> Are you talking about a separate daemon, running on the same host, which
> would "offer RMI services" to all these webapps ?

That would be the standard way of doing it. However, it is well
possible that the RMI Service is running in one of the webapps or a
special 'dummy' webapp  if you want to bundle startup/shutdown. You
would also need to start the rmiregistry which is just a programm
supplied with the jdk/jre and started by nohup rmiregistry & (on
*nix/mac)

> Or would this "thing" be living inside Tomcat ? If so, what kind of "thing"
> would this be ? It would, I guess, have to start before the webapps do, load
> its original data, then remain there waiting for client webapp RMI calls,
> yes ?

Yes, that would be probably the best :-)

It could look like following:

public interface CentralDataService extends Remote {
    void setData(String key, Object value) throws
CentralDataServiceException, RemoteException;
    Object getData(String key)throws CentralDataServiceException,
RemoteException;
}

impl
public class CentralDataServiceImpl implements CentralDataService{
    private Map<String,Object> data = new ConcurrentHashMap<String,Object>();

    public void setData(String key, Object value){
      data.put(key,value);
   }

   public Object getData(String key){
      return data.get(key);
}

}

server, the class you start from command line if run separately.
public class CentralDataServer{

        private static Logger log = Logger.getLogger(CentralDataServer.class);

       private static final String REG_HOST = "localhost";
       private static final int REG_PORT = Registry.REGISTRY_PORT; //default

        public static void main(String a[]){
                DOMConfigurator.configureAndWatch("/log4j.xml");
                Registry rmiRegistry = null;
                // lookup rmi registry
                try{
                        rmiRegistry = LocateRegistry.getRegistry(REG_HOST, 
REG_PORT);
                }catch(Exception e){
                        log.fatal("Coulnd't obtain rmi registry", e);
                        System.err.println("Coulnd't obtain rmi registry");
                        System.exit(-1);
                }

                try{
                        startService(rmiRegistry);
                }catch(Exception e){
                        log.fatal("Couldn't start service", e);
                        System.err.println("Couldn't start service");
                        System.exit(-2);
                }
        }

        public static final String getServiceId(){
               //use your own well known string, might be class name
                return "net_anotheria_xxx_CentralDataService";
        }
        public static void startService(Registry registry) throws Exception{
                CentralDataService myServant = new CentralDataService();
                CentralDataService rmiServant = (CentralDataService)
UnicastRemoteObject.exportObject(myServant, 0);;
                // //register service.
                String serviceId = getServiceId();
                registry.rebind(serviceId, rmiServant);
                log.info("UserServer for service " + serviceId + " is up and 
running.");
        }
}


---------

client:

        private CentralDataService myDataService;
        private static Registry rmiRegistry;
        static{
                // lookup rmi registry
                try{
                        rmiRegistry = LocateRegistry.getRegistry(REG_HOST, 
REG_PORT);
                }catch(Exception e){
                        log.fatal("Coulnd't obtain rmi registry", e);
                }
        }

init(){
       myDataService = rmiRegistry.lookup(CentralDataServer.getServiceId());

}

somewhere in the code:

    myDataService.setData(.....)
    myDataService.putData(....)...


I haven't actually compiled or tested the code but copied parts from
existing (working) code and altered it, so i don't guarantee it will
compile ;-) but it should give you the basic idea.

regards
Leon

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to