TapMsgQueue.mesa
Copyright Ó 1989 by Xerox Corporation. All rights reserved.
Doug Terry, February 19, 1990 2:53:15 pm PST
Message queues are the basic facilities for passing around messages in Tapestry. Messages can be read from a queue and written to a queue. Queue's can also be laziliy evaluated, i.e. the contents are generated as requested. While the basic operations on a message queue remain the same, they can be implemented in different ways by different "classes".
Message queues are modeled after LoganQuery's complex cursors. Messages are defined to be compatible with LoganBerry entries.
DIRECTORY
LoganBerry USING [Entry],
LoganQuery USING [ComplexCursor],
Rope USING [ROPE];
TapMsgQueue: CEDAR DEFINITIONS
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
Messages are lists of fields where each field has a type (tag) and a value (contents). For instance, a message header is parsed into a list of fields. The message body is often a single field with type $Text; however, structured messages may be parsed into several fields.
Msg: TYPE ~ LIST OF MsgField;
MsgField: TYPE ~ RECORD [
type: ATOM,   -- field tag
value: ROPE   -- field contents
];
Message queues are logically sequences of messages.
MsgQueue: TYPE ~ REF MsgQueueRec;
MsgQueueRec: TYPE ~ RECORD [
class: QueueClass ← NIL,  -- queue's class
nonempty: CONDITION,   -- for notifications that message is available
closed: BOOLEANFALSE, -- operations no longer allowed
data: REF    -- data slot for class implementor
];
Queue operations
Get: PROC [queue: MsgQueue, wait: BOOLEANFALSE] RETURNS [msg: Msg];
Returns the next message in the queue. Returns NIL if no message is currently available and wait=FALSE; this does not imply that the queue will remain empty forever. If wait=TRUE then the call might block until a message is available or the queue is closed, in which case NIL might be returned.
Put: PROC [msg: Msg, queue: MsgQueue] RETURNS [];
Adds a message to the queue. Put always works on message queues returned by Create. It may not work on other classes of message queues.
Close: PROC [queue: MsgQueue] RETURNS [];
Destroys the message queue.
Create: PROC [] RETURNS [queue: MsgQueue];
Creates a message queue of class $Basic.
Duplicate: PROC [queue: MsgQueue] RETURNS [q1, q2: MsgQueue];
Creates two queues where each produces the same elements as the original queue.
Merge: PROC [q1, q2: MsgQueue] RETURNS [queue: MsgQueue];
Creates a new queue that contains elements from both of the input queues in unspecified order.
Queue classes
To implement a new class of queues, one must provide a get operation and, optionally, put and end operations. Class implementors must also provide an operation for creating queues of the given class. Creation of a message queue is class-specific since the Create operation may take a variety of parameters that govern the behavior of the queue.
QueueClass: TYPE = REF QueueClassRec;
QueueClassRec: TYPE = RECORD [
flavor: ATOMNIL,   -- name of queue's class
get: GetProc ← NIL,   -- get next message from queue
put: PutProc ← NIL,  -- put message onto queue
close: CloseProc ← NIL  -- destroy the queue
];
GetProc: TYPE = PROC [queue: MsgQueue] RETURNS [msg: Msg];
Retrieves the next queued message in a manner particular to the class of queue.
PutProc: TYPE = PROC [queue: MsgQueue, msg: Msg] RETURNS [];
Adds a message in a manner particular to the class of queue.
CloseProc: TYPE = PROC [queue: MsgQueue] RETURNS [];
Destroys the given queue and any queues that feed this queue.
Conversions
CursorFromMsgQueue: PROC [mq: MsgQueue] RETURNS [cursor: LoganQuery.ComplexCursor];
Returns a cursor whose contents are obtained from the input queue.
EntryFromMsg: PROC [msg: Msg] RETURNS [entry: LoganBerry.Entry];
Converts a message to a LoganBerry entry.
MsgFromEntry: PROC [entry: LoganBerry.Entry] RETURNS [msg: Msg];
Converts a LoganBerry entry to a message.
END.