Each lab will consist of a small problem and details of how to proceed. You need to submit labs to the TAs for grading--see submission instructions below. Generally, unless otherwise specified, you will have one week to complete each assigned lab.
See the syllabus for information on grading. Turning in lab assignments is required. Submit your assignments to the subversion repository according to the directions on the syllabus page.
You
may write these solutions in either
Java or C++...your choice.
Lab 3 Due: 5:00 pm, Friday May 1, 2015
Problem 1 (Message Queue):
For
this assignment you will implement a distributed message queue in your language of
choice. There are two kinds of messages that can be sent to the
Queue: a "QueryMsg" and a "ReplyMsg". A user should be able to add messages
to the Queue or remove messages from the Queue (assume the queue is
strictly FIFO).
What you need to implement:
1. A class called MessageQueue that stores the messages it gets in a
Vector (or similar class). The Vector class (already available in
Java.util and the STL etc.) implements an array with dynamic size. The
MessageQueue will need to implement methods to manipulate the queue
(e.g. addMsg, popMsg, isEmpty etc.).
2. A base class called Message and subclasses : QueryMsg and ReplyMsg.
There are several basic mechanisms for handling messages in queues. One is to simply return the oldest message in the queue. Say that two messages are sent to the queue (M1 and M2 in that order). When a request is made to return a message from the queue (note that the request does not specify a particular message), a FIFO queue will always return the "first in", that is, M1. The next request would return M2, and so on.
3.
You are to provide an ability to simply request from your message queue
the "next" message from the queue. The "next" message in a FIFO
sense is the oldest message in the queue, in our example, M1. One
way to do this would be to implement a "getNextFIFOMessage()" method on
your queue which would return M1, then M2, etc. Whenever a
message is retrieved from the queue, it is also removed from the queue.
Another
basic mechanism for handling messages in queues is to be able to put a
"request" on a queue, have a responder read that request (which will
remove the request message from the queue), and then send a "reply"
message to the queue, which is a reply to the specific message the
responder retrieved from the queue. Say for example we have a
"translation" queue that takes in request messages that contain a word
form of a number, such as the word "one" and we want a response message
that converts that word "one" to its numeric representation, that is to
say, we want a reply message sent to the queue that contains the number
"1". Let's also imagine that two additional messages have been
put on the message queue as requests for translation, "two" and "three".
So
how would we do that? How would the responder communicate "this
is a response to the request to transate the word "two" AND the numeric
representation of the word "two" is "2"? One way this is often
solved (hint) is that the
Message class contains both a "Header" that contains an identifier that
uniquely identifies a particular message, and a "Body" (or "Payload")
that contains the actual response message, ie, "2". That way the
client that requests a translation for the word "two" can indicate that
this message ID is "12345" and the translator that returns the
translated response "2" marks that response as message ID
"12345". In this way, I can request a translation for the word
"five" and mark it as ID "67890" .
4.
Include
the ability (implementation and test code) to respond to a particular
QueryMsg with a particular ReplyMsg. You may use our translate
problem if you prefer, or create another scenario of your own choosing.
In this case, there are two
queue writers - one that adds QueryMsg's, and another that responds to
a specific QueryMsg with a ReplyMsg. The QueryMsg requests should be
retrieved in FIFO
fashion (i.e. reply to the oldest query first). This is the start
of a
"distributed" message queue that uses a simple interprocess
communication mechanism so that one process can send a message to
another process over the message queue. So in our example, the
QueryMsg would set the header ID and a responder client would retrieve
that QueryMsg from the queue, translate the body of the message (the
word "two") into its numeric representation, and send it back to the
queue as a ReplyMsg. You do not have to specifically implement
our numerical translation problem for this lab. If you have
another scenario you prefer, you may use that one instead. If you
do choose to implement the numeric translator, you should only support
translations of a few words, say "one" through "five". Please
keep it contained whatever scenario you choose. You may assume
that once you have replied to all the request messages on the queue,
you are done. You do not need to worry about retrieving a
ReplyMsg from the queue. You will need to worry about how a
Responder will only receive QueryMsgs from the queue and not his own
ReplyMsgs. One approach is to add a type to the message header
indicating whether the message is a REQUEST or REPLY. But that is
just one way to do it.
Test your program by using the message queue to send and receive a
couple of messages. Include tests to reply to a query.
Submitting:
Submit your assignments to the subversion repository in the pre-existing folder named "labN"
(where N is the homework number). Please include a README text file that contains any
instructions for the TAs to assist with grading, and design notes are often the most useful thing you can provide.
We do not usually need any info on how to compile your code unless your code layout is arcane.