21. 비동기 복제 failover 시 확인된 쓰기 유실 (C#)

난이도 최상 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// [시나리오] 비동기 복제 스토리지의 쓰기 확인과 장애 승격 (서버-서버)
//
// 플레이어 상태(재화 등)를 프라이머리 노드에 쓰고, 비동기로 복제본에 전파한다.
// 쓰기 처리는 프라이머리에 커밋되면 곧바로 클라에 성공을 응답한다(빠른 응답).
// 프라이머리가 죽으면 복제본을 새 프라이머리로 승격(failover)한다.
//
// [요구사항]
//  - 클라에 "성공"으로 응답한 쓰기는 장애가 나도 유실되면 안 된다(내구성).
//  - 승격 후 옛 프라이머리가 복귀해도 데이터가 갈라지면(divergence) 안 된다.
//
// [과제]
//  아래 WriteBalance / Failover 를 리뷰하라. (A)(B) 지점의 동작을 근거로,
//  프라이머리 장애 시 무슨 일이 생기는지 재현과 함께 설명하고 수정안을 제시하라.

using System.Threading.Tasks;

public class ReplicatedStore
{
    private INode _primary;
    private INode _replica;

    public async Task<bool> WriteBalance(long playerId, long amount)
    {
        // 프라이머리에 로컬 커밋
        await _primary.CommitLocal(playerId, amount);

        // 복제는 비동기로 뒤따라감(응답을 막지 않음)
        _ = _replica.ReplicateAsync(playerId, amount);

        // (A) 복제 확인을 기다리지 않고 곧바로 성공 응답
        return true;
    }

    // 프라이머리 장애 감지 시 호출
    public void Failover()
    {
        // (B) 복제본을 새 프라이머리로 승격
        _primary = _replica;
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.