더! 좋은 구현 방법을 찾는 과정

ML 서버에서 퀴즈 정보를 받고 프론트에 넘겨주는 방법

클라이언트에서 방 생성 요청이 들어올 때 백 서버에서 ML 서버에 문제 생성 요청을 한다. 이 때 생각할 수 있는 방법이 두 가지였다.

  1. 문제 생성이 완전히 끝난 후 클라이언트에 응답을 보낸다.

    이 방법은 방을 생성하기까지 시간이 오래 걸려 사용자가 기다려야 한다는 단점이 있다.

  2. 백 서버에서 ML 서버에 퀴즈 생성 요청은 비동기로 호출하고 클라이언트에 바로 응답을 보낸다. ML 서버에서는 한 문제가 생성될 때마다 백 서버에 응답을 보낸다.

    이 방법의 장점은 사용자가 바로 대기방에 입장할 수 있다는 것이다.

    단점으로 생각했던 것은, ML 서버에서 계속해서 생성되는 문제를 yield를 사용해 리턴하는데 백 서버에서 그 응답 데이터를 받으려면 stream 형태로 받아야 했고, 이를 위해 WebFlux 의존성을 추가해야 한다. 처음에는 MVC 패턴에서 WebFlux 의존성을 추가하는 것이 안 좋은 방법이라고 생각했으나, 공부를 하면서 이 방법이 MVC 패턴에서 스트림 데이터를 처리하는 일반적인 방법이라는 것을 알게 되어 문제가 해결되었다.

    하지만 퀴즈 생성이 게임 진행보다 무조건 빠르다는 보장이 없어 안정적이지 못하다는 문제가 남아있었다.

이 내용으로 멘토님께 질문을 드리고, 멘토링 이후 사용하기로 한 방식은 다음과 같다.

  1. ML에서 문제를 생성하고 BE에 넘겨주는 방식
    1. ML에서 문서 요약이 생성되면 DynamoDB에 저장하여 BE에 DB id 반환하기
    2. ml은 계속 문제 생성하며 DB 업데이트
    3. 서버는 라운드가 시작될 때마다 id를 사용해 DB를 체크하여 문제가 있으면 5문제씩 큐에 저장
  2. BE에서 FE로 문제를 넘겨주는 방식
    1. 게임이 한 문제씩 진행될 때마다 BE에서 FE로 큐에서 한 문제를 웹 소켓으로 보내줌
    2. 그 문제가 진행되는 동안에는 큐에 그대로 두다가 다음 문제로 이동할때 문제를 큐에서 버리기

DynamoDB 업데이트 추적 방식

  1. DynamoDB Update를 트리거로 한 aws 람다 함수를 생성해, 항목 update 이벤트가 있을 때마다 실행되게 한다.
  2. 그 실행 결과가 Cloud Watch Log에 찍히는데 이 로그를 계속 추적한다. 업데이트 로그가 5번 추적되면 퀴즈를 가져올 수 있는 상태라고 판단하여 퀴즈를 읽어온다.

기존 방식은 업데이트 됐는지 확인하기 위해 계속해서 쿼리를 날려 쿼리 비용이 부담되고 그 때마다 항목을 읽어와 리소스적으로도 낭비였다. 그러나 Cloud Watch Log를 추적하는 방식은 비용이나 리소스 사용이 훨씬 적을 것으로 생각된다.

프론트에 퀴즈를 보내는 방법

프론트에 퀴즈를 하나씩 보내줄 때 소켓으로 보내주는데, 한 플레이어가 요청을 하면 모든 플레이어에게 응답이 간다. 즉 모든 플레이어가 요청을 하면 플레이어 수만큼 퀴즈가 보내지는 문제가 발생한다.

개인별 큐를 생성해두고 1대1로 요청을 한 유저에게만 반환을 하는 방법도 생각했는데 이 방법은 한 명이 인터넷이 끊기는 등 엇갈리게 되면 서로 퀴즈 번호가 안 맞게 될 것 같았다. 그리고 큐를 개인별로 만드는 것이 굉장히 리소스 낭비 같았다.

이 문제에 대해 팀원들에게 조언을 구하고 다음과 같은 방식을 적용하기로 했다.

  1. 퀴즈 방 별로 큐가 하나 있다.