netobj/src/netobjrt/Transport.i3


 Copyright 1992 Digital Equipment Corporation.               
 Distributed only by permission.                             
 Transport.i3 
 Last modified on Thu Feb 24 18:14:55 PST 1994 by wobber         
      modified on Thu Feb 10 16:02:41 1994 by gnelson        
      modified on Fri Sep 11 15:27:53 PDT 1992 by evers  
      modified on Mon Jun 29  8:47:43 PDT 1992 by owicki 

The Transport interface separates the main part of the network object runtime system from the parts that deal with low-level communication. It is the interface that must be implemented to extend the system to use new communication protocols. The interface is reasonably narrow:

INTERFACE Transport;

IMPORT NetObj, NetObjNotifier, StubLib, StubConn, Thread;

TYPE
  T <: Public;
  Public = OBJECT METHODS
    fromEndpoint(e: Endpoint): Location;
    toEndpoint(): Endpoint;
    serviceCall(t: StubLib.Conn): (*reUse*) BOOLEAN
      RAISES {Thread.Alerted};
  END;

  Location <: LocationP;
  LocationP = OBJECT METHODS
    new(): StubLib.Conn
      RAISES {NetObj.Error, Thread.Alerted};
    free(c: StubLib.Conn; reUse: BOOLEAN);
    dead(st: NetObjNotifier.OwnerState);
  END;

TYPE Endpoint = TEXT;

REVEAL
  NetObj.Address = BRANDED REF ARRAY OF Endpoint;
  StubLib.Conn <: Conn;

TYPE
  Conn = StubConn.Public BRANDED OBJECT
    loc: Location
  END;

END Transport.
The main ideas in the interface were described in Section 1.5, page 15. To summarize these briefly:

\begin{itemize} \item A Transport.T is an object that manages connections of some particular class ({\it e.g.}, TCP).

\item A Transport.Location is an object that creates connections of some particular class to some particular address space.

\item A Transport.Endpoint is a transport-specific name for an address space ({\it e.g.}, an IP address plus a port number plus a non-reusable process ID).

\item The fromEndpoint method of a transport converts an endpoint into a location, or into NIL if the endpoint and transport are of different classes. \end{itemize}

\noindent See Section 1.5 for an overall discussion of these concepts. Here are specifications for the methods of a Transport.T:

\begin{itemize} \item The toEndpoint method returns an endpoint for the address space itself. The resulting endpoint should be recognized by the fromEndpoint method of transports of the same class anywhere in the network. That is, if a program instance P calls tr1.toEndpoint(), producing an endpoint ep, then the call tr.fromEndpoint(ep) executed in any program instance either returns NIL (if tr and tr1 are of different classes) or returns a location that generates connections to P.

\item Transports are required to provide the threads that listen to the server sides of connections. When a message arrives on the connection indicating the beginning of a remote call, the threads are required to call the serviceCall method of their transport. The default value of this method locates and calls the dispatcher procedure, as explained in Section 1.5, page 18. Ordinarily a transport implementation will not need to override this method. At the entry to tr.serviceCall(conn), conn.rd is positioned at the start of the incoming message. The serviceCall method processes the incoming remote invocation and sends the result on conn.wr. If it returns TRUE, then the remote invocation was processed without error and the transport can cache the connection. If it returns FALSE, a protocol error occurred during the call, and the transport should destroy the connection. \ttmindex{Transport.T}{serviceCall {\rm method}}

\end{itemize}

\noindent And here are the specifications for the methods of a Transport.Location:

\begin{itemize} \item The new method of a location returns a connection to the address space for which it is a location. The call loc.new() returns a connection whose server side is that address space and whose client side is the program instance making the call. By calling loc.new, the program acquires the obligation to pass the resulting connection to loc.free when it is finished with it. \ttmindex{Transport.Location}{new {\rm method}}

\item The call loc.free(c, reUse) frees the connection c, which must have been generated by loc.new(). If reUse is TRUE, the client asserts that the connection is in a suitable state for executing another remote method call. In particular, c.wr must be positioned at the beginning of a message. \ttmindex{Transport.Location}{free {\rm method}}

\item A transport is responsible for monitoring the liveness of program instances for which it has locations or connections. The method of monitoring depends on the transport. For example, the transport might periodically ping the other program instance. A program is considered dead if it exits, crashes, or if the underlying communication network cannot reach it for an appreciable amount of time. Suppose that loc is a location that generates connections to some program instance P. If P dies, the transport that provided loc is responsible for calling the method loc.dead(st). (The network object runtime implements this method; the transport should not override it.) The argument st indicates whether the transport has detected a permanent failure, or one that is potentially transient. In addition to calling loc.dead, the transport is responsible for alerting all threads it has spawned to handle method invocations on behalf of P. \ttmindex{Transport.Location}{dead {\rm method}} \index{liveness} \end{itemize}

\noindent A transport is expected to manage the connections it creates. If creating connections is expensive, then the transport's locations should cache them. If maintaining idle connections is expensive, then the transport's locations should free them. Often connections are time-consuming to create, but then tie up scarce kernel resources when idle. Therefore transports typically cache idle connections for a limited amount of time.

The Transport interface reveals the representation of NetObj.Address: an address is simply an array of endpoints for the program instance designated by the address. The endpoints are generally of different transport classes; they provide alternative ways of communicating with the program instance. The modules of the network object runtime that require this revelation are exactly the modules that import the transport interface, so this is a convenient place to put it. \ttindex{NetObj.Address}

The Transport interface also reveals more information about the type StubLib.Conn. If t is a StubLib.Conn, then t.loc is a Location that generates connections to the program instance at the other end of t. The connections generated by t.loc connect the same pair of program instances that t connects, but if t is a handle on the server side of the connection, then the connections generated by t.loc will reverse the direction of t: their client side will be t's server side, and vice versa (so-called back connections). On the other hand, if t is a handle on the client side of the connection, then the connections generated by t.loc will be in the same direction as t. \ttindex{StubLib.Conn} A transport must ensure that the loc field is defined in all connections returned by any of its locations. \index{back connections}