private AuthInfoCache ReadCacheByAuthKey(string authkey)
        {
            AuthInfoCache cache = null;

            m_readLock.WaitOne();                                                               // 읽기 대기하기
            m_authkeyToInfoCache.TryGetValue(authkey, out cache);
            return(cache);
        }
        private AuthInfoCache ReadCacheByUserID(string userid)
        {
            AuthInfoCache cache = null;

            m_readLock.WaitOne();                                                               // 읽기 대기하기
            m_useridToInfoCache.TryGetValue(userid, out cache);
            return(cache);
        }
        /// <summary>
        /// user에게 새 authkey를 생성해준다.
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public string SetupNewAuthKey(string userid, UserType usertype)
        {
            var newkey = GenerateAuthKey(userid);

            QuerySetAuthInfo(userid, newkey, usertype);

            var cache = new AuthInfoCache()
            {
                userid   = userid,
                usertype = usertype,
                authkey  = newkey
            };

            CacheInfo(cache);                                                   // auth 정보를 캐싱해둔다.

            return(newkey);
        }
        private void CacheInfo(AuthInfoCache info)
        {
            m_readLock.Reset();                                                                 // 읽기 블락

            m_writeLock.WaitOne();                                                              // 쓰기 받고 다른 쓰기는 대기시키기

            if (info.userid == null)                                                            // fix : 비활성화되어서 null이 된 userid는 걸러내도록
            {
                m_authkeyToInfoCache.Remove(info.authkey);
            }
            else
            {
                m_useridToInfoCache[info.userid]   = info;
                m_authkeyToInfoCache[info.authkey] = info;
            }

            m_writeLock.Set();                                                                          // 다른 쓰기 허용하기

            m_readLock.Set();                                                                           // 읽기 허용
        }
        /// <summary>
        /// 유저의 종류를 가져온다.
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public UserType GetUserAuthType(string userid)
        {
            if (userid == null)                                                                                                         // ID 가 null이면 Guest임
            {
                return(UserType.Guest);
            }

            var cache = ReadCacheByUserID(userid);                                                              // 캐시에서 값을 읽어본다.

            if (cache == null)                                                                                  // 캐시에 값이 없으면 쿼리해온뒤 캐시를 채운다.
            {
                cache = new AuthInfoCache()
                {
                    userid   = userid,
                    usertype = QueryUserType(userid),
                    authkey  = QueryAuthKey(userid),
                };
                CacheInfo(cache);
            }
            return(cache.usertype);
        }
        /// <summary>
        /// authkey에 연결된 UserID를 가져온다.
        /// </summary>
        /// <returns></returns>
        public string GetUserIDFromAuthKey(string authkey)
        {
            if (authkey == null)                                                                                                // authkey가 null이면 Guest : ID도 null임
            {
                return(null);
            }

            var cache = ReadCacheByAuthKey(authkey);                                                            // 캐시에서 값을 읽어본다.

            if (cache == null)                                                                                  // 캐시에 값이 없으면 쿼리해온뒤 캐시를 채운다.
            {
                var userid = QueryUserID(authkey);
                cache = new AuthInfoCache()
                {
                    userid   = userid,
                    usertype = QueryUserType(userid),
                    authkey  = authkey,
                };
                CacheInfo(cache);
            }
            return(cache.userid);
        }
        /// <summary>
        /// 현재 세팅된 authkey를 가져온다. auth되지 않은 경우엔 null을 리턴.
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public string GetCurrentAuthKey(string userid)
        {
            if (userid == null)                                                                                                         // ID가 null일 경우 Guest임 : authkey도 null
            {
                return(null);
            }

            var cache = ReadCacheByUserID(userid);                                                              // 캐시에서 값을 읽어본다.

            if (cache == null)                                                                                  // 캐시에 값이 없으면 쿼리해온뒤 캐시를 채운다.
            {
                cache = new AuthInfoCache()
                {
                    userid   = userid,
                    usertype = QueryUserType(userid),
                    authkey  = QueryAuthKey(userid),
                };
                CacheInfo(cache);
            }

            return(cache.authkey);
        }