Lab 9 Distributed Programming
Purpose This lab is an introduction to distributed programs. In the context of this course, a distributed program is a collection of many world programs that send messages to, and receive messages from, a central server program. To receive a message means to handle another kind of event, and to send a message means for event handlers to return special kinds of results. The emphasis is on programming as opposed to design.
The World is Not Enough
TAs: lecture
A Universe consists of a bunch of world programs plus a central relaying component, called a universe server. Each world can send messages to this central server, and the server can send message to any selection of these worlds. In addition, the server can also kick out a world from its Universe.
Such message-exchange systems of programs are common. Multi-game player programs are one kind example that you know, chat rooms are another one.
A Code Walk
TAs: demo time
- Click RUN and evaluate
(token-ring 25)
This will run a universe for 25 seconds and display four screens: three "world" windows and one "universe" status window. Watch how the blue dot migrates from world window to world window. - Your TA has set up a universe server at an IP number posted on the white board. Now click RUN and evaluate
(make-world "your names" IP-NUMBER)
This expression creates a world program that registers itself with the TA’s server. When the server sends it a message, it is your world program’s turn to display a blue dot. The TA will call out your name.
TAs: code walk
It can receive messages with an on-receive clause. An on-receive handler consumes two arguments: (1) the current state of the world and (2) a message. In general, a message is an S-expression—
nested lists of symbols, strings, and numbers, but for most Universes, it suffices to send symbols or flat lists. - Every world-program handler may return a Package instead of just a world state:
; A [Package X Y] is (make-package X Y) ; interpretation: (make-package ws msg) specifies (1) the (next) ; state of the world and (2) a message for the central server. ; Constraint: Y must be a subset of S-expression.
How a server works A universe server is an event-driven program, just like your world programs. Instead of world, it uses universe to specify what kind of state the program keeps track of and how it reacts to events.
In most cases, a server must represent information about the worlds that currently participate in the universe. When a world connects or sends a message, the universe engine represents this world with an IWorld, which is created with make-iworld. The event handlers get a hold of this structure and the server’s state is typically a list of IWorlds or structures that associate IWorlds with additional data.
Your programs cannot construct IWorlds. To help you with testing, the teachpack supplies three sample IWorlds: iworld1, iworld2, and iworld3. Your program may extract some fields from IWorld structures; see docs.
the request from a world to join the universe, and
the arrival of a message from a specific world.
; [Bundle X Y] is (make-bundle X [List-of [Mail Y]] [List-of IWorld]) ; [Mail M] is (make-mail IWorld M) ; Constraint: M must be a subset of S-expression. ; interpretation: (make-bundle ns ms low) combines ; (1) the next state of the server (ns) ; (2) a list of mails that must go to various worlds (ms) ; (3) a list of internal worlds that must be kicked out of the universe
Programming Universes
Let’s change the universe program in a few ways. Students take over
Trust but Verify The sample program entrusts the individual worlds to hand back the token to the server. An alternative is to send 'go and 'stop messages to worlds.
Exercise 1 Modify the token-ring program as follows:
The server sends out both 'stop and 'go messages. The worlds receive [these] messages but never send any.
When the server’s clock ticks, the tick-handler sends out a 'stop message to the currently active world (if there is one), switches it to the end of the list, and sends a 'go message to the new first IWorld. When a world joins the universe, it is added to the end of the list of participants and the first world gets another 'go message.
You cannot remove the server’s on-msg clause because it is required. Silent worlds are toys. Instead modify its handlers so that it does nothing.
When a world program receives a 'go message, it starts showing the blue dot. When it receives a 'stop message, it stops showing the dot.
Delete the on-tick clause in the world programs.
Guideline As you modify the program, follow the design recipe as much as you can. First, change the protocol definition, which describes the messages that the server and the participating worlds exchange. Second, change the data definitions that describe the state of the world and universe program. Note that the signatures for the event handling functions remain the same because the names of the data definitions stay the same while their meaning changes. Third, edit the purpose statements of the event handlers. Fourth, change the examples/tests for the event handlers; for add-world, just comment out the tests–it is not testable for the revised task—
but do make examples. Fourth, change the function itself.
Stop after 20 minutes.
Run token-ring again after all functions pass their modified tests. Notify the TAs when you’re done. We will run another class room demo with the modified programs.
Take Your Positions The sample program exchanges rather uninteresting messages: 'go, which signals a specific world program that it may display a blue dot, and 'next, which signals to the server that the world program is done. In short, the nature of the symbols doesn’t matter; their very appearance suffices to change the state of the universe or world program. Also, the sample program does not engage the human players that launch the individual worlds.
Let’s change the program to use and exchange information about mouse clicks. The information is used to place the blue dot on the world canvases.
Switch partners. Download new copy of file from web and use it to re-start.
Exercise 2 Modify the token-ring program as follows:
The server sends and receives lists that consists of two natural numbers. The worlds receive and send the same kind of messages. The messages specify x and y coordinates.
The server sends (50,50) to the first world that signs up with the universe. When it receives a world message, it rotates the current world to the end of the list—
as before— and sends the next world in the list the coordinates that it just received. As new worlds sign up, they are added to the end of the list. When a world receives coordinates, it displays the blue dot at the specified coordinates. When the player clicks the mouse ("button-down"), it surrenders the right to display the dot.
Delete all those pieces from the world program that are no longer needed.
See Guideline above on how to go about implementing these changes.
Stop after 30 minutes.
Run token-ring again after all functions pass their modified tests. Notify the TAs when you’re done. We will run another class room demo with the modified programs.