private void applyLogEntry ( LogEntry entry ) { if ( logger . isFineEnabled ( ) ) { logger . fine ( "Processing " + entry ) ; } Object response = null ; Object operation = entry . operation ( ) ; if ( operation instanceof RaftGroupCmd ) { if ( operation instanceof DestroyRaftGroupCmd ) { setStatus ( TERMINATED ) ; } else if ( operation instanceof UpdateRaftGroupMembersCmd ) { if ( state . lastGroupMembers ( ) . index ( ) < entry . index ( ) ) { setStatus ( UPDATING_GROUP_MEMBER_LIST ) ; UpdateRaftGroupMembersCmd op = ( UpdateRaftGroupMembersCmd ) operation ; updateGroupMembers ( entry . index ( ) , op . getMembers ( ) ) ; } assert status == UPDATING_GROUP_MEMBER_LIST : "STATUS: " + status ; assert state . lastGroupMembers ( ) . index ( ) == entry . index ( ) ; state . commitGroupMembers ( ) ; UpdateRaftGroupMembersCmd cmd = ( UpdateRaftGroupMembersCmd ) operation ; if ( cmd . getMember ( ) . equals ( localMember ) && cmd . getMode ( ) == MembershipChangeMode . REMOVE ) { setStatus ( STEPPED_DOWN ) ; // If I am the leader, I may have some waiting futures whose operations are already committed // but responses are not decided yet. When I leave the cluster after my shutdown, invocations // of those futures will receive MemberLeftException and retry. However, if I have an invocation // during the shutdown process, its future will not complete unless I notify it here. // Although LeaderDemotedException is designed for another case, we use it here since // invocations internally retry when they receive LeaderDemotedException. invalidateFuturesUntil ( entry . index ( ) - 1 , new LeaderDemotedException ( localMember , null ) ) ; } else { setStatus ( ACTIVE ) ; } response = entry . index ( ) ; } else { response = new IllegalArgumentException ( "Invalid command: " + operation ) ; } } else { response = raftIntegration . runOperation ( operation , entry . index ( ) ) ; } if ( response == PostponedResponse . INSTANCE ) { // postpone sending response return ; } completeFuture ( entry . index ( ) , response ) ; }
Applies the log entry by executing operation attached and set execution result to the related future if any available .