8. 분산 전역 한도 카운터의 초과 판매(local count + 지연 동기화) (C#)

난이도 최상 해설 보기 →

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

결함 코드 · C#
// ─────────────────────────────────────────────────────────────
// 시나리오: 글로벌 한정 판매(예: 전 서버 통합 한정 아이템 1000개, 또는
//   전역 구매/동시접속 한도)를 여러 게임 서버 노드가 공유한다. 각 노드는
//   로컬 카운터로 자기 판매 수를 세고, 주기적으로 중앙 저장소(Redis 류)에
//   자기 기여분을 더하고 전역 합계 스냅샷을 받아온다. 판매 요청은 각 노드에서
//   초당 수천 건 들어오므로, 매 건마다 중앙을 왕복하지 않으려고 로컬 스냅샷으로
//   빠르게 판정한다.
//
// 요구사항:
//   - 전역 판매 수가 한도(_limit)를 절대 넘기면 안 된다.
//   - 정확성을 지키되, 매 판매마다 중앙 왕복을 강제하지 않는 설계가 바람직하다.
//
// 과제: (A)(B) 지점을 검토하라. 노드가 N개일 때 동기화 주기 사이에
//        전역 합계가 한도를 얼마나 초과할 수 있는지 설명하고,
//        정확성과 처리량을 모두 만족하는 수정안을 제시하라.
// ─────────────────────────────────────────────────────────────
using System.Threading;
using System.Threading.Tasks;

namespace Distributed
{
    public interface IKvStore
    {
        Task<long> IncrByAsync(string key, long delta);
        Task<long> GetAsync(string key);
    }

    public sealed class GlobalSaleLimiter
    {
        private readonly IKvStore _store;
        private readonly long _limit;
        private const string Key = "sold_total";

        private long _localSold;        // 이 노드가 판 수(아직 중앙 미반영)
        private long _globalSnapshot;   // 마지막으로 본 전역 합계

        public GlobalSaleLimiter(IKvStore store, long limit)
        {
            _store = store;
            _limit = limit;
        }

        // 주기 타이머가 호출: 내 판매분을 전역에 더하고 최신 합계를 받아온다
        public async Task SyncAsync()
        {
            long contrib = Interlocked.Exchange(ref _localSold, 0);
            await _store.IncrByAsync(Key, contrib);
            _globalSnapshot = await _store.GetAsync(Key);
        }

        // 한 건 판매 시도(핫패스: 중앙 왕복 없이 로컬 스냅샷으로 판정)
        public bool TrySell()
        {
            // (A)
            if (_globalSnapshot + _localSold < _limit)
            {
                // (B)
                _localSold++;
                return true;
            }
            return false;
        }
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

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