private CompletableFuture < Void > sendHeartbeat ( GossipMember member ) { return bootstrapService . getMessagingService ( ) . sendAndReceive ( member . address ( ) , HEARTBEAT_MESSAGE , SERIALIZER . encode ( localMember ) ) . whenCompleteAsync ( ( response , error ) -> { if ( error == null ) { Collection < GossipMember > remoteMembers = SERIALIZER . decode ( response ) ; for ( GossipMember remoteMember : remoteMembers ) { if ( ! remoteMember . id ( ) . equals ( localMember . id ( ) ) ) { updateMember ( remoteMember , remoteMember . id ( ) . equals ( member . id ( ) ) ) ; } } } else { LOGGER . debug ( "{} - Sending heartbeat to {} failed" , localMember . id ( ) , member , error ) ; if ( member . isReachable ( ) ) { member . setReachable ( false ) ; post ( new GroupMembershipEvent ( GroupMembershipEvent . Type . REACHABILITY_CHANGED , member ) ) ; } PhiAccrualFailureDetector failureDetector = failureDetectors . computeIfAbsent ( member . id ( ) , n -> new PhiAccrualFailureDetector ( ) ) ; double phi = failureDetector . phi ( ) ; if ( phi >= config . getPhiFailureThreshold ( ) || ( phi == 0.0 && System . currentTimeMillis ( ) - failureDetector . lastUpdated ( ) > config . getFailureTimeout ( ) . toMillis ( ) ) ) { if ( members . remove ( member . id ( ) ) != null ) { failureDetectors . remove ( member . id ( ) ) ; post ( new GroupMembershipEvent ( GroupMembershipEvent . Type . MEMBER_REMOVED , member ) ) ; } } } } , heartbeatScheduler ) . exceptionally ( e -> null ) . thenApply ( v -> null ) ; }
Sends a heartbeat to the given peer .