6.096 - Introduction To Interactive Programming

Laboratory 2: Systems of Objects; Nodes and Channels

You should read through this entire assignment before you begin.

Preparing for the Lab

1. Experiment with the application.

This week's laboratory project involves a network routing simulation. In the simulation, routers (nodes) send and receive packets (pieces of information) to each other along various routes (channels). The nodes could be computers, for instance, sending and receiving information from each other across the internet. This problem set could be a scaled down (very scaled down) version of a commercially available product. A demonstration of the simulation is available, which you can see by typing the following on an athena workstation: The idea of the simulation is to experiment with various network configurations and empirically determine their behavior. In other words, play with the application and see what happens. When the GUI pops up, you will see a large center panel (currently blank). Above that will be three menus, below are the available GUI elements. To use the simulator in the most basic way you first construct a network and then set it in motion. The necessary steps are described below.

To construct a node, select from the paint buttons in the lower border of the application. The first node is a source (i.e., generates objects or packets), the second an intermediate connecting node, and the third a sink (i.e., eats objects). You can click on nodes to select the type to be painted, then click on the drawing area to place them. (To remove an element, click on it and then select "Delete Selection" from the Selection menu.)

The black line to the right is a channel. You can draw channels by selecting this element from the lower border, double clicking on a start node, then clicking on another node. Note that channels have directions: they go from the node you start with to the node you end with. It is possible to have more than one channel between two nodes (e.g., one in each direction), but this isn't drawn particularly well.

To start objects moving through the demo, select "Start Simulation" from the Control menu. You can pause the simulation using "Stop Simulation". You can dynamically add elements while the simulation is running. You can also temporally "remove" a node or channel by selecting it and then choosing the "Disable Selection" command from the Selection menu. To re-enable an element, use the "Enable Selection" command. Using the "Delete Selection" option to physically remove an element from the network while the simulation is running is discouraged; deletion is provided only for creating a new network, not for dynamically changing network behavior. Check the fine print for why (link removed, fineprint.html lost).

Experiment with the network for a few minutes. Can you get the channels to fill up? Can you create any other interesting behavior? Remember that you can disable channels (using the menu) while the simulation is running. You may want to keep a record of your experiments to compare your later results with. (Such a record should include both network topology (how things are connected) and dynamic behavior (what you did, what it did).) You can even save any particularly interesting network configurations using the Save Network option under the File menu. When you save networks, be sure to leave the .binsort suffix on their names, as this allows the application to filter out files that could not be the network you want to load. There is fine print on this (link removed, fineprint.html lost).

We have provided two connecting types of nodes. The first, and the one you have been using, is DefaultNodeBehavior. The other is IntermediateNodeBehavior. Can you decern any differences between the two? What, if any, advantages does one enjoy over the other?

2. Design your code.

In this lab, you need to build the behavior for a Node. You will do this by creating a class that implements NodeBehavior. You may want to look at the code for the NodeBehavior interface now.

Your NodeBehavior class will not be a Runnable; instead it will be called by a Node, which is Runnable and has its own Thread. The Node's run method also contains the while(true) loop. (Node also implements the graphical user interface (GUI) for a node.) The heart of Node's run method looks something like this:

InputChannel[] inputChannels;
OutputChannel[] outputChannels;
public void run () {
    while (true) {
        this.nodeBehavior.act( this.inputChannels,
                               this.outputChannels );
Since act() will be called from inside a while(true) loop, you only have to handle one object at a time.

Note that act takes two arrays as its arguments. The first is an array of input channels. Each of these channels may contain packets ready to be read. Each

InputChannel has

    public Object readObject()
        throws ChannelEmptyException, ChannelDisabledException;
You only need to read one packet from one input channel on each time around the interactive control loop, though. Note that input channels may be empty or disabled, in which case they will throw an appropriate exception.

The second argument to act is an array of output channels. An active non-full output channel would be a good place to put any packet you may have picked up. OutputChannel has

public void writeObject( Object ) 
   throws ChannelFullException, ChannelDisabledException;
But be careful: when the output channels are full, they will throw an exception if you try to write to them. Make sure that you don't drop any packets if this happens, or write packets that don't exist.

The main piece of your job is to implement the act method of NodeBehavior. This method should take an object off of one of the inputChannels (using readObject()) and feed it to one of the outputChannels (using writeObject()). Remember that there are potentially several streams of each kind, and that some of these streams may be disabled.

There are several ways that you can choose the input and output channels from their respective arrays. Think of at least two, and record these strategies. The more creative you can be, the more interesting your lab will be. You should design code for at least one of these strategies, and ideally for more than one.

One of the main points of this lab is to observe the effects of different strategies on the behavior of your network as a whole. Is your strategy fair? Does it drop packets? Create them? Do packets cluster in certain parts of your network? Can you come up with a strategy that behaves differently?

Some utilities that you might want to use:

public static int cs101.util.MoreMath.randomInt( int range );
returns an int between 0 and range, inclusive. You can refer to it as Math.randomInt if you include the line import cs101.util.*; at the top of your file.
public static void Thread.sleep( int millis )
    throws InterruptedException;
causes the current Thread to sleep for millis milliseconds. This allows you to put delays in your nodes. Warning: You will have to catch the exception, though you don't necessarily have to do anything with it.

If you have other ideas, design them and then ask us about them.

3. Handle exceptions.

Channels occasionally throw exceptions. You need to be concerned about four of these: Make sure that your code is robust to these exceptions, and does not lose objects.

Building your code.

Your job in lab is to implement one or more node behaviors, to test these behaviors on your own examples, and to exchange example networks with other students in the class. During lab, we will create a shared repository of test networks. Test data development should be pooled, and sharing of test data is encouraged. Discussion of why networks behave as they do is strongly encouraged. Talk to the people next to you to get good ideas for test networks. If you need help loading another student's test network, please ask us to show you how.

Begin the lab by implementing a node behavior. You will need to define a new class, say MyClass. What should you call the file it's defined in? What does it need to extend or implement? What methods does it have? (Remember that the interactive control loop is already defined for you, but it expects to be able to call your act method with two arrays.

The first lines of your file, before your class definition, will need to say:

package BinSort;
import BinSort.Exceptions.*;
Also, you should be sure that your class is public.

Once your code compiles, you should try running it. To run your code, you will need to supply the name of your node behavior class to BinSort. You can do this by typing

BinSort.Main MyClass
(assuming that MyClass is the name of your class, and also that you've already compiled your class using javac.)

You can now test your code using a network you have saved. It is probably best to use a very simple network first -- if you don't have a simple one saved, you might want to create one now.

Once you have this network running, try some others. See if you can find one that stumps your code. (Try to fix it, or at least to understand why. Can you design another network to stump your code?)

Don't forget to tell the course staff about your networks, so that we can use them, too :)


Solutions will be availble here at the conclusion of the lab.

This course is a part of Lynn Andrea Stein's Rethinking CS101 project at the MIT AI Lab and the Department of Electrical Engineering and Computer Science at the Massachusetts Institute of Technology.

Questions or comments:
Last modified: Thu Aug 28 13:00:47 1997