Raft Project 2 Review/Discussion (Winter 2021)
Lecture Notes for CS 190
Winter 2021
John Ousterhout
- Click here for
.cc file containing examples.
- Everyone made improvements from Project 1.
- Deeper classes (simpler APIs, less specialization & information leakage)
- Better error detection and logging (but still more work to do)
- Lines of code: 1806, 1961, 2591, 2702, 2751, 2844, 2957, 3089, 3839
- Size of largest project was due to shallow classes:
- 6 classes as part of RPC implementation: RpcServer, RpcClient, Socket,
Message, Request, Response
- More classes -> more interfaces to document
- Smaller classes -> more dependencies between classes -> more complex interfaces
- Example:
- Message::Recv detects EOF/error on socket
- But can't close socket because it doesn't own it
- Must pass info back to someone else who can then clean up
- Getters and setters
- Small methods -> ordering requirements
- Socket class exposed Lock and Unlock methods
- Implementation inheritance results in complex dependencies
- Overall: twice as much communication code as other projects
- Biggest missed opportunity: make Raft server independent of state machine.
- Define an interface for applying commands
- Pass an object implementing this interface into the server constructor
Class Design: Together vs. Apart
- Given various pieces of functionality, which belong together in the
same class/method and which should be separated in different classes/methods?
- Key considerations:
- Separate general-purpose and special-purpose code
- Over-specialization creates information leakage
- Combine things that are related, separate things that are not related
- Do the whole job in one place
- Examples:
- Raft server contains state machine for shell?
- Client main program also has code to communicate with Raft cluster?
- Communication libraries for server-server and client-server communication?
- Raft server also manages communication with clients?
- Log class also manages other persistent state such as term and vote?
Systems Issues
- These are out of scope for this class, but important to consider
when building "real" systems.
- Crash consistency when executing shell commands:
- Requires atomic implementation of executing the command and updating
lastApplied.
- Class cleanup:
- All classes should destruct cleanly
- Problem: classes that start background threads
- Unsafe to destroy object if thread still running
- Destructor should signal the background thread, wait for it to exit.
- Without clean destruction, hard to write unit tests
- Most projects are very inefficient (5-10x?):
- Lots of object copying (e.g. messages)
- Malloc/free
- Starting/stopping threads
- Extra network messages (e.g. broadcast every client request)
- Solution: learn what operations are unusually expensive, design to
minimize them.?
Other Issues
- What made projects easier or harder to read?
- Did anyone make changes to satisfy me that you didn't end up liking
- Word choice matters (see examples)
- Create helper classes (e.g. exceptions) as nested subclasses, not
top-level classes (see example)
- Heartbearts: several groups maintained the same interpretation as
Project 1: no log data