45. 유휴 타임아웃 판정과 활동 시각 갱신 (C#)

난이도 하 해설 보기 →

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

결함 코드 · C#
// ============================================================================
// [코드리뷰 문제] C# — 유휴(idle) 타임아웃 판정과 활동 시각 갱신
// ----------------------------------------------------------------------------
// 시나리오:
//   서버는 죽은/방치된 연결을 정리하려고 세션마다 마지막 활동 시각을 기록하고,
//   주기적으로 (now - LastActivity) 가 임계(IdleTimeout)를 넘는 세션을 끊는다.
//   일부 상호작용(맵 리소스 다운로드, 대형 스냅샷 스트리밍, 상점 목록 전송)은
//   서버가 클라이언트로 오래 "보내기만" 하는 구간이 있다. 이 동안 클라이언트는
//   보낼 것이 없어 수신만 한다.
//
// 요구사항:
//   - 진짜로 방치된(양방향 무통신) 연결만 유휴로 판정해 끊는다.
//   - 서버가 활발히 데이터를 보내는 중인 정상 연결을 유휴로 오판해 끊으면 안 된다.
//
// 과제: (A) (B) 지점의 동작을 설명하고 수정안을 제시하라.
// ============================================================================

using System;
using System.Collections.Generic;

public sealed class Session
{
    public int Id;
    public DateTime LastActivity = DateTime.UtcNow;

    public void OnReceive(byte[] data)
    {
        LastActivity = DateTime.UtcNow;    // (A) 수신 시 활동 시각 갱신
        // ... 수신 처리 ...
    }

    public void SendLargeAsset(byte[] chunk)
    {
        // 대형 자산을 여러 청크로 나눠 전송한다(여기서는 전송만 수행).
        // ... 소켓 send ...
    }
}

public sealed class IdleReaper
{
    public static readonly TimeSpan IdleTimeout = TimeSpan.FromSeconds(30);

    public void Sweep(IEnumerable<Session> sessions)
    {
        var now = DateTime.UtcNow;
        foreach (var s in sessions)
        {
            if (now - s.LastActivity > IdleTimeout)   // (B)
                Disconnect(s);
        }
    }

    private void Disconnect(Session s) { /* ... 세션 종료 ... */ }
}
내 리뷰 · C#
내 답안 · 자동 저장

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