# Connection Management in ORBLink

## Connection management introduction and terminology

Connection management refers to the set of APIs that perform administrative functions that handle socket opening and closing. Using the connection management API, an application can determine the set of open sockets, can close them when applicable, and can set hooks that are called when a particular connection is closed.

All of the connection management APIs are encapsulated in IDL.

## Junction

The ORB interfaces to TCP/IP sockets through the abstract interface `ORBLink::Junction`:

    module ORBLink{
      pseudo interface Junction {
        readonly attribute value socket;
        unsigned long SecondsIdle();
        boolean isOpen();
    };

The attributes and operations supported by the `ORBLink::Junction` pseudointerface (which is to say, the Lisp class named `orblink:junction`:

- The `socket` attribute of `ORBLink::Junction` is an opaque Lisp type corresponding to the underlying socket stream.
- The `SecondsIdle()` operation gives the number of seconds the junction has been idle. It is reset to `0` on creation or I/O activity, but information requests do not result in resetting the idle time.
- The `isOpen()` operation returns `T` if and only if the junction is actively forwarding messages, that is if its state is `open`. This state can be set to closed by the `ActiveJunction::close()` operation.

## Subclasses of Junction

    module ORBLink {...
      pseudo interface ActiveJunction : Junction {
        readonly attribute unsigned long MessagesReceived;
        readonly attribute string RemoteHost;
        readonly attribute unsigned long RemotePort;
        void close();
        };
      pseudo interface PassiveJunction : Junction {;};
      pseudo interface ClientJunction : ActiveJunction {;};
      pseudo interface ServerJunction : ActiveJunction {};
     };
    };

Any junction instance is an instance of one of three disjoint classes:

1. `Orblink:ClientJunction`

   An instance of `ORBLink:ClientJunction` is responsible for forwarding messages, normally request messages, from a CORBA client to a CORBA server.

2. `ORBLink:ServerJunction`

   An instance of `ORBLink:ServerJunction` is responsible for forwarding messages, normally replies, from a CORBA server to a CORBA client.

3. `ORBLink:PassiveJunction`.

   An instance of `ORBLink:PassiveJunction` is responsible for listening to connection requests from prospective clients and allocating Server junctions as necessary to handle the resulting connections.

### `ActiveJunction`

An instance of `Orblink:ActiveJunction` is either an instance of `orblink:clientjunction` or an instance of `orblink:serverjunction`. The attributes supported by the pseudo-interface `ORBLink::ActiveJunction` are:

- The `MessagesReceived` attribute gives the number of messages that have been received.
- The `RemoteHost` attribute gives the name of the host to which the active junction is connected.
- The `RemotePort` attribute is the remote port of the corresponding socket.

An instance of `orblink:activejunction` also supports the `close` operation. When invoked on a junction, the `close` operation:

- closes the junction - future invocations of the `isOpen()` operation will return `nil`
- Terminates any associated threads, typically threads listening for input, and
- closes any associated streams, namely the value of the `socket` attribute if it is an open stream.

An active junction also closes itself if its associated `socket` stream signals an I/O error, including an EOF error.

- When a `ServerJunction` is closed, it removes itself from the list of ServerJunctions maintained by the ORB in its `ServerJunctions` attribute; it cannot be reused.
- When a `ClientJunction` junction is closed, however, it is reopened when a new `Request` is invoked through that junction.

## Determining the available junctions

The ORB itself offers facilities for listing the available junctions and for customizing the behavior of a junction on closure:

    module ORBLink {
      pseudo interface ORB : CORBA::ORB{
           readonly attribute ServerJunctionList ServerJunctions;
           readonly attribute ClientJunctionList ClientJunctions;
           readonly attribute PassiveJunctionList PassiveJunctions;
     };
    };

The `ORBLink::ORB::ServerJunctions`, `ORBLink::ORB::ClientJunctions`, and `ORBLink::ORB::PassiveJunctions` attributes contain lists of the operational junctions of the appropriate type.

Thus, the forms:

    (op:serverjunctions corba:orb)
    (op:clientjunctions corba:orb)
    (op:passivejunctions corba:orb)

Will return lists (or sequences) of the server, client, and passive junctions.

## Junction close policies

The behavior of junctions on closure is determined by the following pseudo-IDL:

    module ORBLink {
      pseudo interface ORB : CORBA::ORB{
        attribute boolean HandleJunctionClosePolicy;
        void HandleJunctionClose (in Junction j);
    }

When the value of the `HandleJunctionClosePolicy` attribute of the `corba:orb` singleton is `nil`, junction closure operates normally.

When the value of the `HandleJunctionClosePolicy` attribute of the `corba:orb` singleton is `T`, on the other hand, after a junction `j` is closed the `HandleJunctionClose` operation of the `CORBA:ORB` object is invoked with parameter of `j`. In this case, the user should override the definition of `HandleJunctionClose`.

For example, the following set of definitions will print a message whenever a junction is closed:

    (corba:define-method HandleJunctionClose ((orb ORBLink:ORB) junction)
      (format t "HandleJunctionClose: closed junction: ~s ~%" junction)
      (force-output)
    )

    (setf (op:HandleJunctionClosePolicy CORBA:ORB) T)

## Junction error policies

The behavior described in this section is experimental and has not been tested.

The behavior of the ORB on a server junction error (that is, an I/O error, as contrasted with an error signalled by a servant) is also customizable. It is encapsulated in the ORB IDL:

    module ORBLink {
      pseudo interface ORB : CORBA::ORB{
        enum ServerJunctionErrorPolicyType {continue, debug, handle};
        attribute ServerJunctionErrorPolicyType ServerJunctionErrorPolicy;
     };
    };

Because a junction error results in a junction close, normally customization of the close method is sufficient.

The server junction error handling is determined by the `ServerJunctionErrorPolicy` attribute of `CORBA:ORB`:

1. If this value is `:continue`, the error is ignored.
2. If the value is `:debug`, a debugger is invoked.
3. If the value is `:handle`. the `HandleJunctionError` operation on the `CORBA:ORB` object is invoked with parameters the server junction that caused the error and the error itself.

The default value of the ServerJunctionErrorPolicy is `:continue`.

Client junction errors are normally signalled back to the invoking client; thus, client junction error customization is not exposed in this API.

## Forcing errors to outstanding requests when a socket closes

In release 6.1, a new function has been added to let an application force errors to all outstanding requests when a socket closes. The function is orblink:break-pending-requests:

### orblink:break-pending-requests junction

This function takes an Orblink junction as its argument and generates an error response for any outstanding request made on the junction.

A typical use:

    (setf
      (op:HandleJunctionClosePolicy CORBA:ORB) t
      (op:ServerJunctionErrorPolicy CORBA:ORB) :handle
      (op:break_policy corba:orb) :return)

    (corba:define-method HandleJunctionClose ((orb ORBLink:ORB) junction)
       (orblink:break-pending-requests junction))

This will cause a transient error return to any process waiting for a response on a broken socket.