You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
현재 나인크로니클 클라이언트(이하 클라이언트)에서는 LocalLayer(이하 레이어)를 통해 클라이언트에서 캐싱되고 있는 상태에 임시적인 변경사항을 담아두고 있습니다. 레이어를 사용하게된 이유는 다음과 같습니다.
유저가 Tx를 스테이징(게임상에서 액션을 실행)시키더라도 블록체인상에서의 상태는 바로 변경되지 않습니다. 해당 Tx는 검증을 통해 블록에 포함이되고, 클라이언트 입장에선 해당 블록 정보를 받아 Tx의 결과를 확인할때까지의 시간이 필요합니다.
전투와 같은 몇몇액션은 Tx를 스테이징시키고 사용자의 입력을 막고 로딩화면에서 대기를 시키지만, 상태를 변경시키는 대부분의 액션은 입력을 막지않고 다른 행동을 취할 수 있습니다.(상점, 조합, AP 충전과 같은 메인 메뉴 등에서의 다른 활동들)
사용자의 상태를 변경시키는건 대부분 본인이 직접 Tx를 스테이징시키는 행위를 통해 일어나지만 외부(다른 유저, 시스템으로 돌아가는 서비스)에서 사용자의 상태를 변경시키는게 가능합니다. (컨텐츠 리워드를 통한 NCG, CRYSTAL과 같은 FAV나 아이템 지급, 상점에 올려둔 아이템을 다른 유저가 구매해갔을때)
따라서 클라이언트는 유저가 Tx를 스테이징시키기 위해 사용되는 재화(FAV, AP, 아이템 등)의 소모값을 미리 검증하고 재화부족을 통한 Tx의 스테이징을 막기 위해 레이어를 통해 변경점이 있을때마다 변경사항을 미리 반영해둡니다. 예시는 아래와 같습니다.
특정 액션(전투, 마켓)은 소모값으로 AP를 요구합니다. 따라서 AP를 요구하는 액션을 실행시킨 경우 클라이언트는 현재 AP에서 해당 액션이 요구하는 AP를 미리 차감합니다. 이를 통해 다음 액션을 실행하기전에 AP가 부족한 상황인데도 불필요한 요청을 막습니다.
특정 액션(마켓, 조합)은 유저의 인벤토리에 있는 아이템을 삭제합니다. 따라서 해당 액션들을 실행하면 클라이언트는 현재 인벤토리에서 해당 액션에서 사용된 아이템을 없는 아이템취급하고, 이를 통해 다른 액션에서 해당 아이템을 사용하지 못하도록 막습니다.
유저가 스테이징한 Tx가 체인에 포함되어 로딩이 끝날 경우 클라이언트는 레이어를 통해 미리 반영해둔 변경사항을 제거하고 체인에서 변경사항이 반영된 상태를 클라이언트가 캐싱하게 처리합니다.
유저가 한번에 여러 액션을 흘리지 않는 경우엔 한번의 렌더를 통해 레이어가 자연스럽게 정리되면서 크게 문제가 되지않는 구조입니다.
다만 문제는 위에서 얘기된 대부분의 액션이 로딩을 통한 입력을 막지않고 다른 행동을 취할 수 있다는 점입니다.
이를 통해 아래와 같은 시나리오가 발생합니다.
조합 액션을 실행해 사용자의 인벤토리에서 다량의 아이템을 제거하는 레이어를 처리합니다. 해당 레이어는 아이템별로 취급되어 N개의 레이어가 생깁니다.
마켓 액션을 실행해 사용자의 인벤토리에서 다량의 아이템을 제거하는 레이어를 추가로 처리합니다. 마찬가지로 해당 레이어는 아이템별로 취급되어 N개의 레이어가 생깁니다.
Tx가 처리되어 로딩이 끝나서 클라이언트는 레이어를 정리하려 합니다. 다만 현재 구조에선 어떤 레이어를 제거해야할지 (이 레이어가 조합 액션을 통해 생성된 레이어인지, 마켓 액션을 통해 생성된 레이어인지)를 알지 못합니다. 따라서 액션의 필드를 통해 어떤 레이어를 제거해야할지를 프로그래머가 유추해서 처리하고, 나머지 레이어는 다른 액션에서 정리하도록 상태를 캐싱하기전에 남아있는 레이어를 다시 적용시킵니다.
위와 같은 과정에서 유저가 액션을 실행할수록 클라이언트에서 관리하는 상태의 복잡도가 올라가서 어떤 레이어를 적용하고 제외시킬지, 레이어가 적용된 캐싱된 상태가 의도한 상태가 맞는지를 판단하기 어려워집니다.
결국 현재 클라이언트는 레이어의 변경사항이 일어날때마다 체인에서 최신상태를 항상 요청해서 초기화를 진행한 후 남아있는 레이어를 적용해 캐싱을 하고 있습니다.
지금까진 블록팁을 통해 받아온 상태가 클라이언트 입장에선 현재까지 플레이어가 실행한 액션을 통해 변경된 최신 상태이었기때문에 큰 문제가 없어보였지만, V190 마일스톤에서 립플래닛의 업데이트를 통해 더이상 블록팁을 기준으로 받아온 상태가 클라이언트 입장에서 기대하는 변경사항이 적용된 상태가 아니라 Tx가 스테이징되기 이전 상태를 불러오면서 문제가 발생하고 있습니다. (#5133 등의 이슈들)
여러개로 각자 관리되고 있는 레이어를 액션단위의 묶음을 통해 한번에 처리하는 것(이를 통해 렌더시점에 해당 액션의 변경내역만 제거)
레이어 적용시 무분별하게 호출되는 초기화 제거
레이어에 위 2개의 개선사항을 적용해 상태관리를 좀 더 쉽게 처리하는걸 기대합니다. 다른 방식의 개선이나 새로운 제안이 있다면 공유해주세요.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
현재 나인크로니클 클라이언트(이하 클라이언트)에서는 LocalLayer(이하 레이어)를 통해 클라이언트에서 캐싱되고 있는 상태에 임시적인 변경사항을 담아두고 있습니다. 레이어를 사용하게된 이유는 다음과 같습니다.
유저가 한번에 여러 액션을 흘리지 않는 경우엔 한번의 렌더를 통해 레이어가 자연스럽게 정리되면서 크게 문제가 되지않는 구조입니다.
다만 문제는 위에서 얘기된 대부분의 액션이 로딩을 통한 입력을 막지않고 다른 행동을 취할 수 있다는 점입니다.
이를 통해 아래와 같은 시나리오가 발생합니다.
위와 같은 과정에서 유저가 액션을 실행할수록 클라이언트에서 관리하는 상태의 복잡도가 올라가서 어떤 레이어를 적용하고 제외시킬지, 레이어가 적용된 캐싱된 상태가 의도한 상태가 맞는지를 판단하기 어려워집니다.
결국 현재 클라이언트는 레이어의 변경사항이 일어날때마다 체인에서 최신상태를 항상 요청해서 초기화를 진행한 후 남아있는 레이어를 적용해 캐싱을 하고 있습니다.
지금까진 블록팁을 통해 받아온 상태가 클라이언트 입장에선 현재까지 플레이어가 실행한 액션을 통해 변경된 최신 상태이었기때문에 큰 문제가 없어보였지만, V190 마일스톤에서 립플래닛의 업데이트를 통해 더이상 블록팁을 기준으로 받아온 상태가 클라이언트 입장에서 기대하는 변경사항이 적용된 상태가 아니라 Tx가 스테이징되기 이전 상태를 불러오면서 문제가 발생하고 있습니다. (#5133 등의 이슈들)
레이어에 위 2개의 개선사항을 적용해 상태관리를 좀 더 쉽게 처리하는걸 기대합니다. 다른 방식의 개선이나 새로운 제안이 있다면 공유해주세요.
Beta Was this translation helpful? Give feedback.
All reactions