백엔드에 로그인 유저들의 정보를 담은 배열을 만들어두고, 접속과 연결해제 이벤트 마다 이 배열을 수정해주고 있습니다.
새로운 유저 접속 시에 이 배열을 통해서 현재 접속 유저 정보들을 클라이언트로 보내주려고 하는데, socket.io가 빠르게 접속 / 연결해제되는 경우 배열의 추가 / 삭제 순서가 꼬이는 버그가 있었습니다.
→ 누군가가 빠르게 접속하고 나갔을 때?
→ 숫자가 -1이 되거나, +1이 되고 변경되지 않는 경우
→ 전송을 취소
→ 접속 → 네트워크 요청 → 퇴장 → 아직 요청 중이라면, 요청 끊기
이런 문제가 발생하는 경우에 socket.io의 이벤트 기반의 동작 때문에 배열에서 공유자원 문제가 발생하는걸까요?
반대로, 아무리 이벤트 + 비동기방식이더라도 자바스크립트의 동작원리상으로 공유자원 문제가 발생하지 않을 것 같아서 궁금해졌습니다.
이런 문제를 겪어보신 적이 있으신가요?
→ 겪어보신분?
지나가던 캠퍼의 코멘트
Map을 사용하는 건 어떨까요?
key는 socket id, value는 아무값
socket.id는 소켓마다 동일하니까 socket.id를 키로 한 맵을 쓰면 늦게 없애든 일찍 없애든 같은 걸 삭제할 수 있죠
⇒ 변경이 끝나기 전에 클라이언트로 정보가 전달된다면 그것도 에러가 되지 않을까요?
⇒ 클라이언트로 플레이어 퇴장 → 입장 순으로 소켓 메시지를 받는 이상한 상황 같은 걸 말씀하시는 건가요
⇒ 배열에 플레이어들을 담아서 보내주는데, 변경되지 않은 이전 내용의 배열이 전달되거나, 로그아웃한 유저가 제대로 퇴장처리가 되지 않고 재입장해서 여러 명으로 표시되는 등 여러가지 문제가 있었습니다! 그런데 이게 상황마다 표시되는 순서가 전부 다 달라서 이런 문제를 의심했습니다!
⇒ 근데 단일콜스택인데 공유자원이 가능한가요??? 소켓관련한게 node스레드풀을 사용하지도 않을거같은데.. 그렇네용 워딩의 어폐가 있네요. 임계영역같은게 결국 multi가 들어가야하는 거라..
⇒ 그러니까요. 저도 그게 이상했습니다.
⇒ 아하! 공유자원이 아니라 콜스택에 쌓이는 순서가 꼬이는 거군요.
→ 하나의 변수를 사용한다.
→ 순서가 꼬였다.
→ 순서를 잘 보장해줄 수 있을까?
접속 stack
입장 stack
퇴장 stack
→ 공유자원X, 실행 순서가 꼬이는 문제
→ 어떻게 실행 순서를 잘 지킬 수 있을까? 어떻게 보장할 수 있을까?
→ 자료구조
→ 네트워크 요청을 취소하는 방법