|
Package name java.rmi Sequence Diagrams
This diagram explains the procedure that ocurrs when a new object is to be exported.
Initially the user calls one of the static export methods of the Class UnicastRemoteObject or a new UnicastRemoteObject is created. The RemoteReferenceManager is in charge of the management of the exported objects, so the UnicastRemoteObject export method delegates this task to the RemoteReferenceManager singleton. In turn the RemoteReferenceManager creates a new ObjID for the object which uniquely identifies it, and the calls the export service of the TransportManager. The TransportManager creates a new ServerSocket and a new thread listening for incoming calls in the ServerSocket, and it returns an Endpoint which it is used to create the stubs for the exported object. With the Endpoint instance a new ServerRef constructed, and holds Reference to the actual object. Finally the RemoteReferenceManager updates several internal tables, and returns a new Stub created for the object.
This way, we have a new Stub (possibly cached) for the exported object, and a listening thread waiting for new connections on that object.
![]()
This diagram represents the procedure by which a RMI user invokes a method on a Remote object.
Initially the Client invokes a method on a Stub which references to an exported Remote object. The Stub calls the RemoteReferenceManager invoke method. The RemoteReferenceManager must send the needed information to the corresponding server. For that purpose it uses the services provided by the TransportManager singleton. Specifically it calls the invoke method on the TransportManager instance, which will send the ObjID, the method hash and the argumets to the specified Endpoint, and it will wait for the response from the server. Finally when the return value comes back, it is given back to the calling client.
![]()
The execution of a remote method on the server begins when a new incoming call message is received on the listening ServerSocket of the exported object. Then the ObjID, hash of the method and parameters are received. The concrete execution of the method it should be done by the RemoteReferenceManager via the executeCall method. The RemoteReferenceManager lookups the ServerRef corresponding to the received ObjID, and executes the method identified by the hash on the concrete object refereed by the ServerRef. Once the method has been executed the result is sent back through the TransportManager to the calling process.
![]()
The garbage collection mechanism specified for RMI is similar to that implemented for Modula3. Basically this mechanism guarantees the persistence of remote objects as long as a client with a reference to that object exists. This issue is acknowledge through the use of Reference Counting.
An exported object can only be unexported by the DGC when: 1 There are no more remote references to the object in any client. 2 There are no more (Strong) references to the exported object in the servers JVM. 3 There are no more Remote references to the object in the servers JVM. 4 The object has not already been explicitly exported by the servers process.
The first issue is acknowledge through the use of reference counting for the Clients holding references. The second and third conditions are acknowledged through the use of WeakReferences and ReferenceQueues on the server side. Finally the fourth issue is handled by the unexportation mechanism.
Distributed Garbage Collector - Server Side As mentioned before the server side of the Distributed Garbage Collector must hold reference counters for every exported object. For this purpose any client receiving a reference to an exported object sends a “dirty” call to the server for that object indicating that the reference count of that object must be incremented. Similarly when an client will no longer use a remote reference sends the server a “clean” call indicating that the reference counter should be decremented.![]() While a remote reference to an exported object exists in any client the server must guarantee that a Strong reference to the exported object is still reachable. Although the DGC must not interfere with the java's native garbage collection mechanism. If a strong reference for every exported object was hold in the DGCServer, then that object could never be collected. To avoid that we have created a changing reference. The DGC holds one of those changing references, which is a strong reference when the reference counter for the refereed object is bigger that 0, and is a weak reference when the counter reaches 0. ![]() Summing up: Data Structures used: Note: this is a conceptual scheme, the actual structures differ from the ones showed below. ReferenceQueue Distributed Garbage Collector - Client Side When an object is transferred during a remote call invocation, it is deserialized by the Java serialization mechanism, and the resolveObject() method is invoked on the RMIObjectInputStream class. If the received object is a stub (either a proxy stub or a stub created by rmic), this method gets the instance of the Client Distributed Garbage Collector (which is a singleton object) and sends the received stub to it, calling the getStubInstance(Remote) method. The Client DGC will search for a previously received instance of the stub, in order to keep only one instance for that stub in the client. If an instance of the stub already exists in the client, that instance is simply returned and the new received stub is replaced by the pre-existent one. The received stub is then discarded, and the client application receives the old-unique instance of the stub. If the received stub is the first instance of that stub in the client, a dirty call is sent to the Server Distributed Garbage Collector of that stub, in order to get the appropriate Lease for it, which will grant the remote server will not be garbage collected in the server.![]() After the lease has been received, a dirty call must be scheduled in order to renew the Lease before its expiration. The dirty call is then scheduled in a task of a Timer object, which will send the dirty message to the Server Distributed Garbage Collector every half the time granted by the Lease returned by the server. ![]() Transport Layer - Call Invocation When an invocation request from a stub (see Remote Call Invocation diagram explanation) is executed on the TransportManager, a ClientConnection is requested from the ConnectionPool. If there is not any available connection to reuse, a new connection is created and returned. The returned connection will be a concrete subclass of the abstract type AbstractClientConnection, (either a SingleOpClientConnection (http), or a StreamClientConnection (direct JRMP)) depending on the reachability of the server, and determined by the transport’s fallback mechanism. The “invoke” method is then executed over this connection, which will forward the request in the concrete method “methodCall”, which is specific for each kind of connection. When the invocation has returned, the connection is checked in order to determine if could be reused in the future; if is a “reusable” connection (stream), it will be returned to the pool, otherwise (http), it will be closed and discarded. Finally, the object returned by the connection’s “invoke” method is returned to the caller.![]() Transport Layer - Fallback Connection Strategy This scheme presents the default Fallback mechanism RMI uses to connect to to a server. Initially the client attempts a direct TCP/IP connection to the server. If that connection fails it attempts to create a HttpSocket specifying the hostname and the port of the Proxy through which the connection must traverse. If the direct HTTP connection fails it attempts to create a connection through the same Proxy assuming a CGI script which forwards RMI requests is loaded on the server machine.![]() Transport Layer - MultithreadedServer When a connection is accepted at the server a new ServerConnection is created to handle that connection. This connection is created using the ServerConnectionFactory. Then the serve method is called on the AbstractServerConnection wich actually handles the request. The AbstractServerConnection can be an instance of StreamServerConnectionFactory, or SingleOpServerConnection, depending on whether the client is using a direct or an HTTP connection. See StreamServerConnection and SingleOpServerConnection explanations.![]() Transport Layer - StreamServerConnection The StreamServerConnection initially reads the contents of the message sent and it encapsulates them on a Message instance. Afterwards checks which kind of message was read and handles ir accordingly. Each kind of message has a special private method that handles it. It is worth noting that all the interaction with the concrete messages is handled with the appropriate protocolHandler. Also is important to note that this version of the ServerConnection sends and receives more than one message through the same Conncetion. In fact receives the DGCAck before quiting the execution![]() Transport Layer - SingleOpServerConnection Refer to StreamServerConnection for explanation on this diagram. The difference between this diagram and the StreamServerConnection - Design Version 4 is that at most one message can be sent and received, thus eliminating the possibility to receive a Ping message and to send the DGCAck through this connection.![]() Transport Layer - StreamClientConnection This sequence represents the concrete implementation for the “methodCall” method described in the TransportManager.invoke sequence, for the specific direct JRMP “StreamClientConnection” class. In this connection type, the connection should be previously established via the establishConnection method, which sends and receives the necessary handshake information to sets the channel ready for call invocation. The call data is written through the ClientProtocolHandler, and then the output stream is flushed. The response from the server is read and the returned ReturnMessage is inquired in order to determine if a DGCAck message should be sent. If this is true, a DGCAck message is sent over the same connection. Finally, if the response from the server was an exception, the received exception is unpacked and thrown to the client; otherwise, the received object is returned to the client.![]() Transport Layer - SingleOpClientConnection This sequence represents the concrete implementation for the “methodCall” method described in the TransportManager.invoke sequence, for the specific JRMP through HTTP “SingleOpClientConnection”. This connection type is characteristic for its single round trip with the server, since all exchange is made through HTTP messages. Initially the call request is delegated to the ClientProtocolHandler, which is in charge of sending the call data to the underlying stream. A flush() invocation will send the HTTP message to the server, and then the answer from the server is read through ClientProtocolHandler’s methods again. If the response from the server is a stub (or contains one or more stubs), a DGCAck message is sent again to the server; for this purpose a call to the acknowledgeDGCAck method of the TransportManager (which handles this task sending the message in a different connection) is made. If the response received from the server is an exception, the exception is unpackaged and thrown to the client. Finally, if the response from the server is an object, the object is returned.![]() |
Copyright © 2005-2006 Instituto Tecnológico Córdoba
Last updated: Mar 17, 2006 |
|