Raft Project 2 Review/Discussion
Lecture Notes for CS 190
Winter 2018
John Ousterhout
Together or Apart?
- Tendency is still towards shallow/small classes (too much "apart")
- Example TA1 (separate class with methods just to log messages, each
method only invoked once)
- Separate class NetworkException generated only by
NetworkManager: make exception a nested class
- Example TA2: keep related code together within a method (do the whole
job in one place)
- Different classes for different return results from client requests
(Example TA3)
- Inheritance hierarchy for messages: factor out check for stale term?
- Should be apart: shell-command state machine built into Raft server
(make Raft server more general-purpose)
- Persistent log module taking on other responsibilities:
- Applying committed entries
- Persistent log class makes decisions about truncation, entry
equality (Example TA4)
- Separate structures for committed, uncommitted entries
- Best approach: keep it simple, general (just append and truncate)
Making Code Obvious
- Examples that are not obvious:
- Code looks unsafe, but it's actually safe (Example O1)
- Doesn't conform to normal usage: getters with no "get"
(commitIndex() instead of getCommitIndex())
- this.wait(), this.notify(): no place to put documentation
- ByteBuffer: internal state isn't obvious (especially when reused
in different places)
- Poor indentation (Examples O2, O3)
- Program appears to end without doing anything (Example O4)
- Command loop hidden among lambdas (Example O5)
- Declare as one type, allocate as another (Example O6)
- Assign "ids" to clients (like server ids) for sending responses
- Long lambdas (Example O7)
- Callbacks: flow of control is no longer obvious
- Depending on non-obvious state information, double-purpose a method
(Example O8)
- Send a request on one socket, get response on another
- Clients must establish a listen port to receive responses
- Try to conform to reader expectations and conventions, document when
you don't.
- Names: biggest problem is they don't reflect what's most important
- Heartbeats: no longer just heartbeats (Example N1);
heartbeat is now a special case
- Examples N2-N10 (think about abstraction: what's the key idea?)
- Documentation issues (see examples)
Other Issues
- Performance:
- Don't spend a lot of time at micro-optimizing
- Get a feel for big issues, focus on them
- Opening sockets
- One thread per open socket (Google: 100K open sockets/server!)
- Reading entire log into memory
- Copying entire log to do insertion or removal
- Cache misses