15-440 Project 1 FAQ
The following web page is supplement to the main project document,
available as a
PDF
.
General
Where can I find the resources for this assignment?
All files are available from the AFS directory
/afs/cs.cmu.edu/academic/class/15440-f12/P1:
-
P1-f12.tgz:
A compressed tar file containing source code, libraries, and executables for both Linux and Mac OS X
-
go/README.txt:
The README file for the code distribution.
How do I run Go?
The following describes how this works on an Andrew Linux machine.
- The go directory is at /usr/local/lib/go
- The go program is available as /usr/local/bin/go
- You will need to set your GOPATH environment variable to include both the main go directory and your own go directory.
- You need to set the environment variable GOROOT to /usr/local/lib/go.
What code can I (re)use for this assignment?
In general, all of the code you use for this assignment must be your
own. The only exceptions are:
Can I add my own packages to my code?
We encourage you to do so, especially for code that can be shared
across multiple packages or programs (e.g., utilities for dealing with
passwords and hashes in part B). What you should do is:
- Set up a subdirectory in contrib. Let's say it's called "contrib/foo".
- Put your go files for the package in there. Have each of them start with the declaration package foo.
- Whereever you want to use this package, include "P1-f12/contrib/foo in your set of imports.
You might want to also generate testing code for this package, in the Go tradition of doing unit testing of every package, but that's entirely up to you.
How will this project be graded?
The maximum score for the project will be 100 points. These will be distributed as follows:
- Part A will count 55 points
- Part B, running on top of our version of the LSP package will count 35 points
- Part B, running on top of your implementation of the LSP package will count an additional 10 points
We will grade according to correctness and style. Correctness will be
tested via the testing code we have already provided. Style will be
based on both the low-level details of your code (comments,
indentation, variable name selection), as well as the quality of the
overall design. ADVICE: use the Go formatter (the
fmt option of the go program) to automatically
indent your code according to standard Go style.
Part A
How do I turn in my code for Part A?
Project 1 Part A is due on Monday Sept 24th at 10:00PM. You will turn in your Part A code on Autolab under Project 1 Part 1 - LSP. You will turn in exactly 1 tar file with the contrib directory. Any changes in the official directory or api or tests will be nullified. For example
- cd go/src/P1-f12/
- tar cvf handin.tar contrib/
There is a size limit for handins, so if you built binaries or stored large logs in your contrib directory, you'll want to move them elsewhere or delete them. Your code will be autograded and you will see your results after a few minutes (depending on system load, which might be high at the last minute). You will be fine if you submit it on time, but you are not guaranteed immediate results so try to finish early :).
Note that these are the same tests as we've provided in the latest handout, so please do not try to use autolab for testing. It is only meant as a sanity check that you've turned in a working tar file that builds and runs. There are 32 tests and your raw score is out of 32 (1 point for each test). There are 3 points for style that will be assigned afterwards. Please refer to the above grading question to see how your score will be weighted when determining final grades.
What can we assume about the ordering of calls relative to the
various close operations?
This has been changed (both simplified and relaxed) since the original
writeup. You can assume the following. You need not do any error
checking.
- For the client: after Close has been called, there will
be no further calls to Read, Write, or
Close.
- For the server: after CloseConn has been called on some
connection C, there will be no further calls to Write, or
CloseConn for connection C.
- For the server: after CloseAll has been called, there
will be no further calls to any method for this server.
What should be the effect of the CloseConn method?
We have made a few changes to its specification. Here is a summary of what should happen when the server calls
CloseConn on some connection C:
- The call should return immediately.
- The server should stop accepting messages from connection C.
- Subsequent calls to Read should not return any data from connection C.
- If there are any messages that have been written to connection C
but not yet sent over the network, the server should keep sending and
resending them until either 1) all have been sent (and acknowledged),
or 2) the connection has been lost.
My code seems to hang in some of the tests. It works OK if I set GOMAXPROCS to something greater than 1. Is that OK?
Your LSP code should work with GOMAXPROCS set to its default value of 1. Most likely, you have a busy-waiting loop in your code, where you keep testing some values without performing any operations that require attention from the operating system (such as channel reads and writes, network operations, etc.). You shouldn't need such loops. Instead, set up channels to have one goroutine signal another when some event has occurred.
I'm really having a hard time dealing with all the issues related to closing connections, stopping the goroutine loops, etc.. Can you give me some advice?
This is indeed one of the trickiest parts of both the client and server. Here's how we implemented things.
For the client, it's useful to think of there being two sides involved
in terminating the client: the application and the network.
- The
application side stops when the client executes the Close() method.
This indicates that the client does not intend to issue any new
writes, or to read any more data. However, there could still be data
that has been written by the client, but not yet sent over the
network.
- The network side stops when the epoch limit is reached
without receiving any new messages from the server. This indicates
that there will be no more incoming data, and that it will be
impossible to send any more messages. However, there could still be
messages that have been received, but not yet read by the application.
- Once the application side has stopped, the network side can stop when either 1) all remaining outgoing messages have been sent and acknowledged, or 2) the epoch limit is reached without receiving any new messages from the server.
- Once the network side has stopped, the application side can stop when either 1) all remaining incoming messages have been read, or 2) the application calls the Close() method.
When both sides have stopped, the goroutines can exit their loops and return.
On the server side, the same basic idea holds, but at two different levels:
- Locally, for each connection C, its application side stops when the server calls CloseConn(C), and the network stops when the epoch limit is reached without any messages from the client.
- Globally, the application stops when the server executes the CloseAll() method, and the network stops when all of the connections have stopped.
My code seems flaky. Sometimes it works, and other times it doesn't. What's going on
Chances are that you are experiencing race conditions. Based on
student code we've seen, there seem to be a lot of these. If you have
different goroutines accessing a common map, accessing a sequential
buffer, or updating a shared variable, then chances are that you have
races in your code.
The easiest ways to avoid races is to
centralize all of the logic into a single event handler. It's the
only one that really does much. The other routines do minimal tasks,
e.g., triggering an epoch event or reading a message from the network.
They generate requests which are fed to the event handler. The event
handler then just sits in a loop, where on each step it receives a
request from some channel via a select statement, and takes some
action, and possibly responds to the requester via a reply channel.
It is much easier to write concurrent code when most of the activity
is purely sequential. You need not worry which goroutines update or
use which parts of the state, because really only the event handler
does this.
I can't find anything on the web about the Live Sequence Protocol. Is there
an RFC?
As the writeup states, the protocol is ``home grown.'' It's intended
to have the sort of features you might encounter in a real-world
protocol, but many simplifications have been made to make it easier to
implement.
Part B
How do I turn in my code for Part B?
Project 1 Part B is due on Monday Oct 1st at 10:00PM. There are two ways of handing in your Part B code on Autolab:
- Project 1 Part 2 - Password cracker (contrib LSP)
Using this option will cause autolab to use your contrib version of LSP. This will allow you to get the (up to) 10 points for running part B on top of your implementation of LSP.
- Project 1 Part 2 - Password cracker (official LSP)
Using this option will cause autolab to use the official version of LSP. You will not get the 10 points for running part B on top of your implementation of LSP.
You can handin your code to either of these submissions to get credit. If you handin to both of these, then we will take the better of the two. However, if you know you only want to handin to one of these, then please only handin to one of them to reduce congestion. For example, if you get full credit with your contrib LSP, there is no point in submitting to the official LSP. Or if you know your LSP will cause the system to hang and timeout, then submit only to the official LSP test.
In either case, you will turn in exactly 1 tar file with the contrib directory. Any changes in the official directory will be nullified. For example
- cd go/src/P1-f12/
- tar cvf handin.tar contrib/
There is a size limit for handins, so make sure you delete any binaries and large log files in the contrib tree. Running go build in a directory will generate a large binary in the directory, so you must remove these binaries before handin. Your code will be autograded and you will see your results after a few minutes (depending on queue length, which might be long at the last minute). These tests are known to take about 4 minutes assuming autolab starts running the job immediately. You will be fine if you submit it on time, but you are not guaranteed immediate results so try to submit early :).
Note that these are the same tests (rtest, wtest, stest) as we've provided in the latest handout, so please do not try to use autolab for testing. It is only meant as a sanity check that you've turned in a working tar file that builds and runs.
The request and worker tests are scaled to 5 points each. The server test is scaled to 20 points. There are 5 points for style. Lastly, 10 points will be assigned for using your LSP implementation for the contrib LSP submission. These 10 points are scaled based on if you pass the part B tests. Please refer to the above grading question to see how your score will be weighted when determining final project 1 grades.