10.4 Remote Peer Queues
As discussed in section 10.2, peer queues can be formed
interactively during an attachment between the two sides. The protocol
provides for the creation and closing of these queues on both sides.
The handling of data on these queues are performed by data handlers,
routines which either provide data to the queue or consume data from the
queue. They are triggered by the appropriate control messages, so that a
data consumer handler would consume data arriving on a queue, and a data
provider handler would send data onto a queue (which would be consumed on
the other side). These data handlers can be user defined.
The programmer for the remote side needs to provide the remote side of the
interface to the peer queue.
10.4.1 Synchronous peer queues
The implementation of a synchronous peer queue on the ECLiPSe side is
shown in figure 10.2. There is an in-memory buffer, which is
implemented as a memory queue in ECLiPSe (i.e. queue("") option
for open/3). Associated with the memory queue is the actual socket
stream to the remote side.
The memory queue is the queue that the user sees on the ECLiPSe
side, with name Name and a unique integer id Queue, which is
the stream id for the memory queue. The id is used by both sides to identify
the queue, as it is unique (a symbolic name can always be reassigned), and
is used in the control messages. To conform to normal ECLiPSe streams,
these queues appear uni-directional to the user, i.e. data can be either
written to or read from the queue. The direction is fromec if the
direction of the data is from ECLiPSe to the remote side (i.e.
ECLiPSe can output to the queue), and toec
if the direction is from the remote side to ECLiPSe (i.e. ECLiPSe
can read from the queue). The user perform normal I/O operations on the
memory queue, and the protocol ensures that the data is transferred
correctly to the remote side without blocking.
Figure 10.2: ECLiPSe implementation of remote synchronous peer queue
The socket stream is largely hidden from the user on the ECLiPSe side,
with data automatically transferred between it and the buffer. The buffer
is needed to ensure that when data is transferred between the two sides,
the I/O operation is synchronised (the data is being read on one end of the
socket while it is being written at the other), so no blocking will occur.
When a side needs to initiate an I/O operation with the other side (either
to write data to or read data from the other side via the socket stream), it must have control
(otherwise it would not be in a position to initiate an action). Before
performing the I/O operation, a control message is sent to the other side to
allow it to prepare to read the data before the I/O operation is actually
initiated. The memory queue thus serves to buffer the data before it is
transferred to the socket stream.
The socket stream must be connected to the remote side before it could be
used. Control messages are used also to synchronise the connection of
the socket. The protocol does not specify if a buffer is needed on the
remote side, this depends on the facilities available in the language used
for the remote side.
For a particular synchronous queue, a data handler can only be defined on
one side of the queue, but not both.
10.4.2 Asynchronous peer queues
I/O operations on these queues do not need to be controlled by the remote
protocol, but their creation and closing is controlled by the remote
protocol, so that the remote interface can keep track of these queues.
These are implemented as raw socket streams on the ECLiPSe
side, with I/O operations performed directly on the socket. The Name and
Queue id for the stream is thus those for the ECLiPSe socket stream. It
is the responsibility of the user to ensure that I/O operations do not
block on these queues. They are provided to allow asynchronous transfer of
data (e.g. from ECLiPSe side to the remote side without handing over
control), and also they allow more efficient transfer of data.