Top

Bidirectional session modules

Donatien Grolaux

1 Introduction

The Session module provides a communication channel respecting this set of properties:

This module also offers a session gate, which is a single access point for spawning multiple sessions. Typically, a server can start a gate that will create a different session per client. When a client has finished to work with the server, the session is closed and no more communication is possible between them. However, the client can use the gate again to create a new session with the server.

This module doesn't provide an access control over the session instances and the gates. The application should define its own using the Connection and Ticket modules, or the SocketConnection module.

2 Examples

First example: a client-server implementation.

%% Server side
proc{Server Msg}
   ... %% insert here the code that responds to Msg
end 
L
G={Session.newGate L}
{SocketConnection.offerOn 5000 G}
{ForAll L
 proc{$ S}  
    thread 
       {ForAll {Session.getStream S}
        proc{$ M} {Server M} end}
    end 
 end}
 
%% client side
G={SocketConnection.take IP 5000} %% IP contains the IP of the server
S={Session.gateConnect G} %% S is a session connected to the server
{S.aSend run} %% sends the run message to the server
...

Second example: a timer server that sends a tick every second. Only one client can connect at a time.

%% server side
S={Session.new}
{SocketConnection.offerOn 5000 S}
thread 
   proc{Tick}
      try {Session.aSend S tick} catch _ then skip end 
      {Delay 1000} {Tick}
   end 
in 
   {Tick}
end 
 
%% client side
LS={Session.new}
{Browse {Session.getStream LS}}
RS={SocketConnection.take IP 5000}
{Session.connect LS RS} %% will fail if the server is not free
... 
{Session.disconnect S} %% disconnects from the server => another client can take over

3 Reference

Warning: local and remote session instances play a different role in the functions and procedures below. Except when otherwise stated, the first parameter is always a locally created session. Let's assume Offer is a function that makes an Oz entity remotely available, and Obtain the function that gets the offered reference:

SiteA

SiteB

SA={Session.new}

SB={Session.new}

{Offer SA}

 

 

SR={Obtain}

At this stage, SiteB has the remote reference SR to SA of SiteA. SiteB can connect both sessions by:

{Session.connect SB SR}

However swapping the parameters is invalid:

{Session.connect SR SB}

The first parameter of Session.connect must be session local to SiteB, which is not the case here.

3.1 Session Reference

is

{Session.is +X ?B}

tests whether X is a Session. X can be a remote session.

new

{Session.new ?S}

returns a new session instance.

connect

{Session.connect S1 S2}

Connects S1 with S2. Raises an exception if S1 or S2 are already connected to another session. Raises an exception if S2 is unreachable.

disconnect

{Session.disconnect S}

Disconnects S to whatever other session it was connected to. This is a synchronous disconnection, ie it waits for all pending messages to arrive before disconnecting. In case of permFail, the disconnection waits for a change of the communication status. If it resolves to ok, all pending messages are sent before disconnecting. If it resolves to permFail or disconnect, the disconnection is immediate, and pending messages may be lost in the process.

break

{Session.break S}

Disconnects S to whatever other session it was connected to. This is an as soon as possible disconnection: if the communication state was ok then all sent messages are garanteed to arrive before the disconnection. On the contrary, if the communication was in the permFail state, the disconnection is immediate and pending messages may be lost in the process. Note that break is the only way to terminate a session if it goes to permFail for an infinite amount of time.

getStream

{Session.getStream S ?Xs}

Returns the stream of messages sent by sessions connected to S. The returned stream doesn't start from the creation of S but from the moment it is asked. For that reason, it is often better to getStream before connecting to another session, otherwise messages might be lost.

getStateStream

{Session.getStateStream S ?Xs}

Returns the stream of communication states of S with the other sessions it is successively connected to. The returned stream doesn't start from the creation of S, but from the last known communication state change. So Xs has the form C|Cs where C is the current communication state of S and Cs is the stream that will receive the updates when that state changes. This stream can be composed of one of the following atoms: connect, disconnect, tempFail, ok, permFail.

getSideStream

{Session.getSideStream S ?Xs}

Returns the free-for-all stream of S. There is no need to connect to S to send an element to this stream. The returned stream doesn't start from the creation of S but from the moment it is asked. Elements of Xs are composed of pairs RS#M where RS is a reference to the session object used to send the message M.

getState

{Session.getState S ?T}

Returns current state of S, ie {Session.getStateStream S}.1.

getPeer

{Session.getPeer S1 ?S2}

Returns the session instance S1 is currently connected with, or unit if S1 is not currently connected.

sSend

{Session.sSend S M}

Sends M to the reception stream of the session S is connected to in a synchronous way: this command blocks until this message has arrived on the reception stream of the other site. Raises an exception if S is not currently connected.

aSend

{Session.aSend S M}

Sends M to the reception stream of the session S is connected to. Doesn't block. Raises an exception if S is not currently connected.

lSend

{Session.lSend S M}

Sends M to the reception stream of S itself.

sideSend

{Session.sideSend S1 S2 M}

Sends M to the free-for-all reception stream of S2. S2 receives the pair S1#M on his free-for-all stream. Nothing happens if S2 is unreachable.

bind

{Session.bind S Event Proc}

This procedure provides an event based way of managing communication state changes. Event must be one of these atoms: connect, disconnect, tempFail, ok, permFail. Proc is a zero parameter procedure that is executed each time the state change specified by Event occurs on S.

configure

{Session.configure S Param Value}

Changes the paramater Param of S to Value. Currently, the only configurable parameter is:

  • autoBreakAfter: either an integer representing milliseconds, or the atom inf for an infinite time (default). Specifies a time to wait before automatically breaking a session when a permFail occurs.

isConnected

{Session.isConnected S ?B}

Returns true if S is currently connected, false otherwise.

wait

{Session.wait[Ok|NotOk|Connect|Disconnect] S}

{Session.wait[Ok|NotOk|Connect|Disconnect]Or S V}

{Session.wait[Ok|NotOk|Connect|Disconnect]Ors S LV}

If the communication status of S is not in the specified state, then blocks until it is. Supported states are:

  • Ok means S is connected to another session instance and the link between them is fine.

  • NotOk in all situations that are not Ok.

  • Connect means S is connected to another session instance.

  • Disconnect means S is not connected to another session instance.

The Or flavour also specifies a logic variable V and blocks until the specified state occurs, or V is determined. The Ors flavour also specifies a list logic variable LV and blocks until the specified state occurs, or any of the elements of LV is determined.

3.2 Gate Reference

isGate

{Session.isGate +X ?B}

tests whether X is a Gate.

newGate

{Session.newGate ?S ?G}

returns a new gate and binds S to a list of futures. Each time a connection is created on this gate by Session.gateConnect, the next element of S is bound to the local session created for the communication.

gateConnect

{Session.gateConnect G ?S}

returns a local session S connected to a session created by the gate G.

closeGate

{Session.closeGate G}

Stops the gate G from accepting new connections and closes the associated list of sessions. G must be a local gate.



Donatien Grolaux
Version 1.2.3 (20020111)