MsgQueue

- a Java package
- a CVS project
- by Tom Ioerger (Oct 2000)


Introduction

MsgQueue is a Java package I wrote that you can check out of CVS. It implements a simple queue system for receiving string messages. Each message is tagged with a sender ID and a timestamp.

MsgQueue is very liberal with security. Senders are responsible for identifying who they are (via an ID string), and the MsgQueue just trusts this implicitly. The user of the MsgQueue might want to be more careful with authentication if sender might lie. It is not really meant to be run in an environment in which agents could be devious or insincere.

Note that clients cannot read from the queue, only the "owner" (process which started the MsgQueue object).

Implementation

MsgQueues are built on top of a simple utility class called Queue, which is an adaptation of Vectors. Actually there are two ways to imagine implementing the 'pop' operation: 1) delete element 0, or 2) keep track of start index and simlpy increment it when something is popped. The current implementation uses the first approach, though second approach could have some advantages on the speed/space tradeoff for some applications. A MsgQueue uses three parallel Queues, to keep track of messages, senders, and timestamps.

Note: The MsgQueueObj class is synchronized, to prevent problems with concurrent access by multiple processes.

API

To use MsgQueue in other Java programs, of course you must import the package (and java.rmi.* as well). From the perspective of clients (who must do an RMI Naming.lookup call on the name bound to the running message queue object, creating a MsgQueueIfc interface object), there is only command currently available:
     public void tell(String sender,String message);
See Client.java for an example. The sender string is a simple ID, like "client1". From the perspective of "servers" (programs which use MsgQueue objects), there are several additional functions for getting messages out. The main ones are:
     public Vector pop();
     public Vector peek();
     public boolean isEmpty();
Clearly, pop() takes off the next message (in FIFO order), and peek tells you what it is without removing it from the queue. These two methods return a Vector which is a 3-tuple consisting of: 1) the message (String), 2) the ID of the sender (String), and 3) the timestamp (Date, a Java class). Here is a visual representation:
     pop/peek -> [String message,String sender,Date timestamp]
You can also dump messages, and use 'size()' to get the count. Of course, you have to do the usual RMI things as a server, such as set the security manager, create the object (MsgQueueObj), bind a name to it in the registry. See TestMQ.java for an example.

Client

Client is a little command-line program that can connect to an existing message queue and send messages to it. You invoke it as follows:
     java MsgQueue.Client clientname msgqueueobjectname
Don't forget to make sure 'rmiregistry' is running. The args you supply are: the name the client is to be known by (messages are automatically tagged with this before being sent), and the name of the message queue object (whatever the server object is bound to in the RMI registry; might want prefix with machine name).

What comes up is a command-line prompt. Basically, there are two simple commands: 'say' message, which sends the message, and 'quit'. Here is an example of using the client to connect to a message queue (called 'mq1') in a TaskableAgents agent:

     bradley# java MsgQueue.Client client1 mq1

     client1> say (location unitA 11 9)
     input: say (location unitA 11 9)
     sending: (location unitA 11 9)

     client1>quit

     bradley#

TestMQ

If you want to bring a message queue up by itself for testing, you can run the program TestMQ, which is invoked as follows:
     java -Djava.security.policy=policy MsgQueue.TestMQ //$(HOST)/mq1
Don't forget to make sure 'rmiregistry' is running. The policy file right now is all-inclusive; you can make it more restrictive if you want. Since this command is cumbersome to type, I put it in the Makefile, so you can try 'make runmq', for example.

After initializing a message queue object with a name (for RMI registry) as specified on the command line, TestMQ then enters a loop in which it dumps its message queue every 8 seconds.