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.
All coding must be done in the Java Programming Language.Lab 3 Due: 5:00 pm, Monday, May 4, 2020
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.