// File: /workspace/github_c_makefile_star2_O0/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clearNodeFailureIfNeeded
void clearNodeFailureIfNeeded(clusterNode *node) {
    mstime_t now = mstime();

    redisAssert(nodeFailed(node));

    /* For slaves we always clear the FAIL flag if we can contact the
     * node again. */
    // 如果 FAIL 的是从节点，那么当前节点会直接移除该节点的 FAIL
    if (nodeIsSlave(node) || node->numslots == 0) {
        redisLog(REDIS_NOTICE,
            "Clear FAIL state for node %.40s: %s is reachable again.",
                node->name,
                nodeIsSlave(node) ? "slave" : "master without slots");
        // 移除
        node->flags &= ~REDIS_NODE_FAIL;

        clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG);
    }

    /* If it is a master and...
     *
     * 如果 FAIL 的是一个主节点，并且：
     *
     * 1) The FAIL state is old enough.
     *    节点被标记为 FAIL 状态已经有一段时间了
     *
     * 2) It is yet serving slots from our point of view (not failed over).
     *    从当前节点的视角来看，这个节点还有负责处理的槽
     *
     * Apparently no one is going to fix these slots, clear the FAIL flag. 
     *
     * 那么说明 FAIL 节点仍然有槽没有迁移完，那么当前节点移除该节点的 FAIL 标识。
     */
    if (nodeIsMaster(node) && node->numslots > 0 &&
        (now - node->fail_time) >
        (server.cluster_node_timeout * REDIS_CLUSTER_FAIL_UNDO_TIME_MULT))
    {
        redisLog(REDIS_NOTICE,
            "Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.",
                node->name);

        // 撤销 FAIL 状态
        node->flags &= ~REDIS_NODE_FAIL;

        clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x10, %rsp
movq %rdi, -0x8(%rbp)
callq 0x252e0
movq %rax, -0x10(%rbp)
movq -0x8(%rbp), %rax
movl 0x30(%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x6a816
jmp 0x6a838
leaq 0x7b860(%rip), %rdi     # 0xe607d
leaq 0x7b481(%rip), %rsi     # 0xe5ca5
movl $0x511, %edx            # imm = 0x511
callq 0x63ca0
movl $0x1, %edi
callq 0x1f3b0
movq -0x8(%rbp), %rax
movl 0x30(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x6a854
movq -0x8(%rbp), %rax
cmpl $0x0, 0x840(%rax)
jne 0x6a8a5
movq -0x8(%rbp), %rdx
addq $0x8, %rdx
movq -0x8(%rbp), %rax
movl 0x30(%rax), %esi
andl $0x2, %esi
leaq 0x7b859(%rip), %rcx     # 0xe60c6
leaq 0x7c5ee(%rip), %rax     # 0xe6e62
cmpl $0x0, %esi
cmovneq %rax, %rcx
movl $0x2, %edi
leaq 0x7b807(%rip), %rsi     # 0xe608e
movb $0x0, %al
callq 0x24fb0
movq -0x8(%rbp), %rax
movl 0x30(%rax), %ecx
andl $-0x9, %ecx
movl %ecx, 0x30(%rax)
movl $0x6, %edi
callq 0x69b00
movq -0x8(%rbp), %rax
movl 0x30(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x6a918
movq -0x8(%rbp), %rax
cmpl $0x0, 0x840(%rax)
jle 0x6a918
movq -0x10(%rbp), %rax
movq -0x8(%rbp), %rcx
subq 0x868(%rcx), %rax
leaq 0xa9021(%rip), %rcx     # 0x1138f8
movq 0x7c0(%rcx), %rcx
shlq %rcx
cmpq %rcx, %rax
jle 0x6a918
movq -0x8(%rbp), %rdx
addq $0x8, %rdx
movl $0x2, %edi
leaq 0x7b7e1(%rip), %rsi     # 0xe60db
movb $0x0, %al
callq 0x24fb0
movq -0x8(%rbp), %rax
movl 0x30(%rax), %ecx
andl $-0x9, %ecx
movl %ecx, 0x30(%rax)
movl $0x6, %edi
callq 0x69b00
addq $0x10, %rsp
popq %rbp
retq
nop