본문 바로가기
日常

[항해99 8기 - 66일차] 어렵다..

by stella_gu 2022. 9. 14.

서버 배포 후 어느 정도 오류 수정과 예외 처리를 끝내고..

계속 마음에 걸렸던 todo 전체 및 상세 조회 부분을 손보기 위해 다시 보는데...

 

아무리봐도 응답값이 너무.. 비효율적인 것 같다...

 

todo 게시글이 쌓이고 요청이 많아지면서 응답속도가 느려지는 게 보여서

서비스 출시 후에 과연 서버가 견딜 수 있을까...? 하는 걱정이 자꾸 들었다

 

ec2 프리티어를 써서 느린 건지 기분탓인지 모르겠으니 일단 수정하고 비교해 보자...!

 

 

[ 상세 조회 - 수정 전 ]

todoGet = async (userId, todoId) => {
    const todoInfo = await Todo.findOne({
      where: { todoId },
      include: [ChallengedTodo, Comment],
    });

    if (!todoInfo) {
      throw Boom.badRequest("존재하지 않는 Todo입니다.");
    }

    if (!todoInfo.isTodo) {
      throw Boom.badRequest("이미 삭제된 Todo입니다.");
    }

    if (!userId) {
      return {
        todoId,
        userId: todoInfo.userId,
        isFollowed: false,
        profile: todoInfo.profile,
        todo: todoInfo.todo,
        mbti: todoInfo.mbti,
        nickname: todoInfo.nickname,
        commentCounts: todoInfo.commentCounts,
        challengedCounts: todoInfo.challengedCounts,
        isChallenged: false,
        isTodayDone: false,
        createdAt: todoInfo.createdAt,
        updatedAt: todoInfo.updatedAt,
        comment: todoInfo.Comments.map((c) => {
          return {
            commentId: c.commentId,
            userId: c.userId,
            comment: c.comment,
            nickname: c.nickname,
            isCommented: false,
            createdAt: c.createdAt,
            updatedAt: c.updatedAt,
          };
        }),
      };
    }

    // 오늘 도전한 todo 있는지 체크
    const today = new Date();
    today.setHours(0, 0, 0, 0); // 오늘 (과거의) 자정
    const todayChall = await ChallengedTodo.findOne({
      where: {
        userId,
        createdAt: { [Op.gte]: today },
      },
    });

    const myfollowing = await Follow.findAll({
      where: { userIdFollower: userId },
    });

    return {
      todoId,
      userId: todoInfo.userId,
      isFollowed:
        myfollowing.findIndex((f) => f.userIdFollowing === todoInfo.userId) !==
        -1
          ? true
          : false,
      profile: todoInfo.profile,
      todo: todoInfo.todo,
      mbti: todoInfo.mbti,
      nickname: todoInfo.nickname,
      commentCounts: todoInfo.commentCounts,
      challengedCounts: todoInfo.challengedCounts,
      isChallenged:
        todoInfo.ChallengedTodos.findIndex((c) => c.userId === userId) !== -1
          ? true
          : false,
      isTodayDone: todayChall ? true : false,
      createdAt: todoInfo.createdAt,
      updatedAt: todoInfo.updatedAt,
      comment: todoInfo.Comments.map((c) => {
        return {
          commentId: c.commentId,
          userId: c.userId,
          comment: c.comment,
          nickname: c.nickname,
          isCommented: c.userId === userId ? true : false,
          createdAt: c.createdAt,
          updatedAt: c.updatedAt,
        };
      }),
    };
  };
isfollowed  - todo 작성자가 내가 팔로우한 사용자인지 
ischallenged  - 내가 도전한 적 있는 Todo인지
isTodayDone  - 오늘 도전한 todo가 있는지
isCommented  - 내가 작성한 댓글인지 

 

api 명세 그대로 보내려고 하다보니 

todoInfo를 다시 나눠서 return값을 만들어내고,

isCommented까지 백에서 map을 돌려가며 보내줄 필요가 있을까..?

 

 

최대한 계산을 줄여 코드를 좀 덜어내고 싶어서

todoInfo를 그대로 보내고 js 함수를 최대한 제거해 보았다.

 

 

[ 상세 조회 - 수정 후 ]

todoGet = async (userId, todoId) => {
    const todoInfo = await Todo.findOne({
      where: { todoId },
      include: [
        { model: Comment },
        { model: User, attributes: ["nickname", "profile"] },
      ],
    });

    if (!todoInfo) {
      throw Boom.badRequest("존재하지 않는 Todo입니다.");
    }

    if (!todoInfo.isTodo) {
      throw Boom.badRequest("이미 삭제된 Todo입니다.");
    }

    // 도전한 적 있는지 체크
    const challenge = await ChallengedTodo.findOne({
      where: { userId, ChallengedTodo: todoId },
    });

    // 오늘 도전한 todo 있는지 체크
    const today = new Date();
    today.setHours(0, 0, 0, 0); // 오늘 (과거의) 자정
    const todayChall = await ChallengedTodo.findOne({
      where: {
        userId,
        createdAt: { [Op.gte]: today },
      },
    });

    // 작성자 팔로우 여부 체크
    const myfollowing = await Follow.findAll({
      where: { userIdFollower: userId, userIdFollowing: todoInfo.userId },
    });

    return {
      todoInfo,
      isFollowed: myfollowing ? true : false,
      isChallenged: challenge ? true : false,
      isTodayDone: todayChall ? true : false,
    };
  };

 

+ 비회원 유저는 상세 todo 페이지 못 보게 기획이 수정됨

 

 

꽤... 깔끔해진 거 같다....!

 

 

일단 더미데이터를 넣어서 테스트 해보자!!!

 

 

 


단순히 로컬에서 더미 데이터로 댓글을 500개 만들어서 테스트 해 본 결과

4.75초에서 0.053초로 단축되었다

 

게시글 하나에 댓글이 500개 넘게 달릴 일이... 우리에겐 없겠지만..

서비스 출시 후 트래픽이 몰릴 경우를 생각하면 충분히 의미 있는 결과가 아닐까...?

 

 

 

 

이제 전체 조회 손보러 가자