Lab 10:
Concurrency and Client/Server
We've seen the power of computational objects with
local state as tools for modeling. Yet, as section 3.1.3 warned,
this power extracts a price: the loss of referential transparency,
giving rise to a thicket of questions about sameness and change, and
the need to abandon the substitution model of evaluation in favor of
the more intricate environment model.
The central issue lurking beneath the complexity
of state, sameness, and change is that by introducing assignment we
are forced to admit time into our computational models. Before we
introduced assignment, all our programs were timeless, in the sense
that any expression that has a value always has the same value. In
contrast, recall the example of modeling withdrawals from a bank
account and returning the resulting balance, introduced at the
beginning of section 3.1.1:
(withdraw 25)
75
(withdraw 25)
50
Here successive evaluations of the same expression
yield different values. This behavior arises from the fact that the
execution of assignment statements (in this case, assignments to the
variable balance) delineates moments in time when values change. The
result of evaluating an expression depends not only on the
expression itself, but also on whether the evaluation occurs before
or after these moments. Building models in terms of computational
objects with local state forces us to confront time as an essential
concept in programming.
We can go further in structuring computational
models to match our perception of the physical world. Objects in the
world do not change one at a time in sequence. Rather we perceive
them as acting concurrently - all at once. So it is often natural to
model systems as collections of computational processes that execute
concurrently. Just as we can make our programs modular by organizing
models in terms of objects with separate local state, it is often
appropriate to divide computational models into parts that evolve
separately and concurrently. Even if the programs are to be executed
on a sequential computer, the practice of writing programs as if
they were to be executed concurrently forces the programmer to avoid
inessential timing constraints and thus makes programs more
modular.
In addition to making programs more modular,
concurrent computation can provide a speed advantage over sequential
computation. Sequential computers execute only one operation at a
time, so the amount of time it takes to perform a task is
proportional to the total number of operations performed. However,
if it is possible to decompose a problem into pieces that are
relatively independent and need to communicate only rarely, it may
be possible to allocate pieces to separate computing processors,
producing a speed advantage proportional to the number of processors
available.
Unfortunately, the complexities introduced by
assignment become even more problematic in the presence of
concurrency. The fact of concurrent execution, either because the
world operates in parallel or because our computers do, entails
additional complexity in our understanding of time.
Labwork
finish this during section
Exercise 1.
For this lab you'll need three people, each on a
separate workstation. One person should choose to be the server, and
should do this:
> (load "~cs61as/lib/im-server.scm")
> (im-server-start)
Make a note of the IP address and port number that this
prints! The other people will be clients. They should do this:
> (load "~cs61as/lib/im-client.scm")
> (im-enroll "123.45.67.89" 6543) ; use actual numbers from server!
but using the server's IP address instead of
123.45.67.89 and the server's port number instead of 6543. (Note
that the IP address must be enclosed in quotation marks.)
The clients can then send each other messages:
> (im 'cs61as-xy "Hi there, how are you?")
The messages can't include more than one line.
A client can leave the IM system by running
> (im-exit)
The server can quit (which disconnects all the clients) with
> (im-server-close)
Note:
This lab is short so that you can start on the homework early.
It'll be easier to test your work with several people. Also, the
homework is slightly longer than usual.
Homework
do this in section if possible; finish the rest at home
Client/Server Questions:
These exercises use the Instant Message program, found in the
following files:
~cs61as/lib/im-client.scm
~cs61as/lib/im-server.scm
~cs61as/lib/im-common.scm
Exercise 2.
Invent the capability to send a message to a list of
clients as well as to a single client. Do this entirely in the
client program, so what actually goes to the server is multiple
requests.
Exercise 3.
Invent the capability to broadcast a message to every
client. Do this by inventing a broadcast command that the
server understands.
Exercise 4.
Could #2 have been done with the server doing part of
the work? Could #3 have been done entirely in the client code?
Compare the virtues of the two approaches.
Exercise 5.
Invent the capability of refusing messages from specific
people. The sender of a refused message should be notified of the
refusal. Decide whether to do it entirely in the client or with the
server's cooperation, and explain why.
Exercise 6.
Why is the 3-way handshake necessary when connecting to
the server?
Concurrency Questions
To work with the ideas in this section you should first
(load "~cs61as/lib/concurrency.scm")
Exercise 7.
Exercise 3.38, 3.39,
3.40, 3.41,
3.42, 3.44, 3.46,
3.48,
of Abelson & Sussman
Exercise 8.
Do the following reading: