Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

MultiSRPC.H

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 // Last modified on Sun May 22 22:53:25 EDT 2005 by ken@xorian.net   
00020 //      modified on Fri Aug 14 15:32:04 PDT 1998 by mann   
00021 //      modified on Mon Jun 16 11:07:42 PDT 1997 by heydon 
00022 //      modified on Sun Aug 20 08:51:54 PDT 1995 by levin 
00023 
00024 // MultiSRPC -- a cache of SRPC connections to servers on various machines
00025 
00026 // A "MultiSRPC" object is a cache of client SRPC connections to
00027 // potentially multiple servers that all export the same interface.
00028 // The object provides two functions, Start and End.  A client calls
00029 // Start and specifies the desired host for the server; Start returns
00030 // a suitable SRPC object, either from its cache or newly created.
00031 // The client calls End to tell MultiSRPC that it is finished with an
00032 // SRPC connection, which is then placed in the cache for future use
00033 // by Start.
00034 
00035 // Each MultiSRPC object represents a cache for a collection of
00036 // servers for the same interface.  Here the term "interface" is used
00037 // somewhat loosely, since SRPC supports only a weak notion of
00038 // interface.  SRPC allows its callers to specify a TCP port number
00039 // (or name for a port number) that is used to connect client and
00040 // server, but it is the responsibility of client and server code to
00041 // agree on such a number through other means.
00042 
00043 // There are two common styles of assigning port numbers.  In the
00044 // simpler case, a port number is associated with an abstract
00045 // "service" in advance of its deployment.  This number is either
00046 // wired into the code of client and server, or is placed in some
00047 // external configuration database where it is looked up by using some
00048 // other piece of statically shared information.  This technique works
00049 // well when the set of services can be enumerated in advance of
00050 // execution.
00051 
00052 // A more complicated scheme is used when the service is, in effect,
00053 // an object, and the number of objects and/or their distribution
00054 // across service machines is not known statically.  In this case, the
00055 // port number is assigned dynamically and communicated between client
00056 // and servers by means external to SRPC.  This technique allows
00057 // multiple object servers to reside on the same host machine; they
00058 // simply use different port numbers.
00059 
00060 // MultiSRPC supports both of these styles.  An "interface" (port
00061 // number) can be specified at construction time, in which case all
00062 // cached connections held by the object use the same port number.
00063 // Alternatively, the interface need not be specified at construction
00064 // time, in which case the client must specify a port number on each
00065 // call to Start.
00066 
00067 
00068 #ifndef _MULTI_SRPC_H
00069 #define _MULTI_SRPC_H
00070 
00071 #include <Basics.H>
00072 #include "SRPC.H"
00073 
00074 class MultiSRPC {
00075 public:
00076   // Constructors
00077   MultiSRPC(const Text &interface = Text(""));
00078   /* Make a new, empty cache for connections to servers.  If "interface" is
00079      non-empty, the servers all must export it.  If "interface" is empty,
00080      the choice of interface is made at the time Start is called. */
00081 
00082   // Destructor
00083   ~MultiSRPC();
00084 
00085   typedef int ConnId;
00086   /* A connection identifier is ``valid'' iff it is non-negative. */
00087 
00088   // Request a new SRPC connection to a particular server
00089   ConnId Start(const Text &hostname, SRPC*& srpc) throw (SRPC::failure)
00090     { return Start(hostname, "", srpc); };
00091   /* Return the valid identifier of a dedicated SRPC connection to a server
00092      for the interface named in the constructor running on the machine named
00093      "hostname", and set "srpc" to a pointer to the underlying connection.
00094      When done with the connection, either call "End" to make the connection
00095      available to other clients, or call "Discard" to cause the connection
00096      to be closed.
00097 
00098      Throws "SRPC::failure" if the interface name specified in the
00099      constructor was empty or if "hostname" is an unknown host or if
00100      that host is not currently exporting the interface named in the
00101      constructor. */
00102 
00103   ConnId Start(const Text &hostname, const Text &interface, SRPC*& srpc)
00104     throw(SRPC::failure);
00105   /* Return the valid identifier of a dedicated SRPC connection to a server
00106      for the specified interface on the specified hostname, and set "srpc"
00107      to a pointer to the underlying connection.  When done with the
00108      connection, either call "End" to make the connection available to other
00109      clients, or call "Discard" to cause the connection to be closed.
00110 
00111      Throws "SRPC::failure" if the constructor specified a non-empty
00112      interface name or if "hostname" is an unknown host or if that
00113      host is not currently exporting the specified "interface". */
00114 
00115   // Finish using a connection
00116   void End(ConnId id) throw();
00117   /* Make the connection "id" available to other clients. If "id" is invalid,
00118      this is a no-op. Otherwise, "id" must be a (valid) connection identifier
00119      returned by an invocation of the "Start" method above. */
00120 
00121   /* Usage Note: Since "End" is a no-op when "id" is an invalid connection
00122      identifier, no tests are required to handle the case where "Start" throws
00123      "SRPC::failure". Instead, clients can write code like this:
00124 
00125        MultiSRPC::ConnId id = -1;
00126        try {
00127            SRPC *srpc;
00128            id = multi.Start(hostname, srpc);
00129            // use "srpc" connection here
00130            multi.End(id);
00131        } catch (SRPC::failure) {
00132            multi.End(id);
00133            // handle failure
00134        }
00135   */
00136 
00137   void Discard(ConnId id) throw();
00138   /* Close the connection "id" and free the resources it consumed. Call this
00139      instead of End if you know the connection will not be useful to another
00140      client in the future.  If "id" is invalid, this is a no-op. */
00141 
00142   void Purge(const Text &hostname, const Text &interface) throw(SRPC::failure);
00143   /* If there are any cached SRPC connections to the specified interface on 
00144      the specified hostname that are not in use, close and discard them. */
00145 
00146 private:
00147   // the server interface
00148   Text intf;
00149 
00150   // The connections are stored in a table indexed by server host name.
00151   // The entire table is protected by a mutex.
00152   Basics::mutex mu;
00153 
00154   // For now, the table is a simple array of entries. If the "srpc" entry is
00155   // NULL, then a failure was detected on some previous SRPC connection that
00156   // used this entry in the table, so the entry is available for a new
00157   // connection.  If the "interface" entry is Empty(), it is implicitly equal
00158   // to the value of "this->intf", which cannot be Empty().  
00159   struct Entry {
00160       Text hostname;
00161       Text interface;           // empty iff intf is non-empty
00162       bool inUse;               // connection in use?
00163       SRPC *srpc;               // NULL means this entry is not used
00164 
00165       // default constructor/destructor
00166       Entry() throw () : inUse(false), srpc((SRPC *)NULL) { /*SKIP*/ }
00167       ~Entry() throw ();
00168   };
00169   typedef Entry *EntryPtr;
00170 
00171   // The "tbl" is capable of holding "num" Entry's. The current entries are
00172   // "tbl[0]".."tbl[next-1]". All entries "tbl[next]".."tbl[num-1]" are NULL.
00173   int next, num;
00174   EntryPtr *tbl;
00175 };
00176 
00177 #endif // _MULTI_SRPC_H

Generated on Mon May 8 00:48:57 2006 for Vesta by  doxygen 1.4.2