FLUSH2 design ============= Author: Bela Ban Version: $Id: FLUSH2.txt,v 1.5 2007/10/22 19:46:52 belaban Exp $ Prerequisites: - A flush is always started and stopped by the *same* member, both for joins and state transfer - For state transfers (but not for joins), we can have different members start a flush at the same time Structures: - FlushState - flush_active: whether we are currently running a flush - flush_leaders: set of members which started the flush (no duplicates) - start_flush_set: list of members from whom we expect a START-FLUSH-OK message - digests: digests from all members, received with START-FLUSH-OK message - stop_flush_set: list of members to whom we send a STOP-FLUSH message - down_mutex: for blocking of multicast down calls, unicasts are passed at all times On SUSPEND event: - If FlushState.flush_active: - Add flush leader to flush_leaders (if not yet present) - If already present: terminate (don't send START-FLUSH message) -Else - Set FlushState.flush_active to true - Add flush leader to flush_leaders (if not yet present) - Set start_flush_set and stop_flush_set - Multicast START-FLUSH - Block until start_flush_set is empty (block on start_flush_set) - Look at FlushState.digests: - If all digests are the same --> return - Else --> run reconciliation phase On START-FLUSH(sender=P): - If FlushState.flush_active: - Add flush leader to flush_leaders (if not yet present) -Else - Set FlushState.flush_active to true - Add flush leader to flush_leaders (if not yet present) - Call block() - Make down_mutex block multicast messages from now on - Return START-FLUSH-OK with my digest to P On START-FLUSH-OK(sender=P,digest D): - Add digest D to FlushState.digests - Remove P from FlushPhase.start_flush_set - Notify FlushPhase.start_flush_set if empty On RESUME event: - Multicast STOP-FLUSH event (asynchronously, don't wait for results) On STOP-FLUSH(sender=P): - Remove P from flush_leaders - If flush_leaders is empty: - Unblock down_mutex On SUSPECT(S): - Remove S from start_flush_set and stop_flush_set - If start_flush_set is now empty --> notify thread blocking on it - Remove S from FlushState.flush_leaders - If FlushState.flush_leaders is empty: (flush leader S crashed during flush !) - Unblock down_mutex On view change V: - Remove all members that are not part of V from start_flush_set and stop_flush_set - If start_flush_set is now empty --> notify thread blocking on it - Remove all members from FlushState.flush_leaders which are not part of V - If FlushState.flush_leaders is empty: (flush leader crashed during flush !) - Unblock down_mutex Reconciliation phase (in NAKACK): - Sends XMIT requests for message not in local digest, but in digest received from REBROADCAST_MSGS - Wait until local digest (updated when missing messages are received) is same as digest received from REBROADCAST_MSGS - Takes suspects into account