Skip to content

Conversation

@wlswnsdn
Copy link
Contributor

PR 제목

[Refactor]: API 호출 비동기화 및 Redis 캐싱 적용

✨ 변경 유형 (하나 이상 선택)

  • Feat: 새로운 기능 추가
  • Fix: 버그 수정
  • Refactor: 코드 리팩토링 (기능 변경 없음)
  • Docs: 문서 업데이트 (주석, README 등)
  • Chore: 기타 변경 (빌드 설정, 라이브러리 업데이트 등)
  • Test: 테스트 코드 추가/수정

📚 변경 내용

YouTube 영상 자막 및 상세 정보 조회에 Redis 캐싱 기능 도입. API 중복 호출 방지 및 성능 개선
관련 API 호출 로직을 동기(synchronous) 방식에서 비동기(asynchronous) 방식으로 전환. 효율적인 자원 관리 및 성능 향상에 기여
YouTube 자막 서비스에 캐시 미스 발생 시 불필요한 동시 API 호출을 막기 위해 Redis 락(lock) 메커니즘 적용
애플리케이션 시작/종료 시 Redis 연결 및 해제 로직 추가, 환경 변수 예시 파일(.env.example) 업데이트

⚙️ 주요 작업 (선택 사항)

  • 새로운 API 추가 (API 명세서 링크 또는 간단한 정보)
  • 데이터베이스 스키마 변경 (변경 내용 명시)
  • 외부 라이브러리 추가/제거 (라이브러리 명시)
    • redis[asyncio] 추가
    • tzdata 추가

✅ 체크리스트

  • 코드 컨벤션을 준수했습니다.
  • 변경 사항에 대한 문서 업데이트가 필요한 경우 반영했습니다.

🔗 관련 이슈 (선택 사항)

#149

💬 기타 (선택 사항)

Redis 클라이언트 싱글톤 패턴으로 구현하여 캐싱 인프라 구축
`.env.example`에 Redis 관련 환경 변수 추가
애플리케이션 시작 시 Redis 연결 테스트 및 종료 시 연결 해제
`requirements.txt`에 `redis[asyncio]` 의존성 추가
중복 API 호출 감소를 위한 기반 마련
유튜브 자막 데이터의 중복 API 호출 방지 위해 Redis 캐싱 도입
동일 자막 동시 요청 시 API 중복 호출 막는 Redis 락 메커니즘 구현
Redis 사용 불가 또는 오류 시 유튜브 API 직접 호출로 폴백 처리
자막 데이터 불변성 고려 30일 TTL 캐시 설정
`get_video_details` 메서드를 비동기로 변경하고 Redis 캐싱 로직 추가
캐시 적중 시 Redis 데이터 반환, 미적중 시 YouTube API 호출 후 5분 TTL로 캐싱
Redis 연결 실패 또는 오류 발생 시 API 직접 호출하도록 폴백 로직 구현
외부 API 호출(YouTube, LLM) 및 데이터 조회 로직을 비동기 방식으로 전환
Redis 캐싱을 적용하여 중복 API 호출 방지 및 성능 개선
서비스 전반의 응답 시간 단축 및 리소스 효율성 향상
@wlswnsdn wlswnsdn self-assigned this Nov 16, 2025
@wlswnsdn wlswnsdn added the 🛠️ 리팩토링 리팩토링 label Nov 16, 2025
@gemini-code-assist
Copy link

Summary of Changes

Hello @wlswnsdn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 애플리케이션의 외부 API 상호작용 및 데이터 검색 방식을 대폭 개선합니다. YouTube 영상 상세 정보와 자막 데이터에 Redis 캐싱을 적용하고, 기존의 동기 API 호출을 비동기 패턴으로 전환하여 전반적인 성능을 향상시키고 외부 API 요청의 중복을 줄입니다. 특히, YouTube 자막 캐시 미스 시 발생할 수 있는 동시 요청 문제를 해결하기 위해 Redis 기반의 락 메커니즘을 도입하여 효율적인 자원 관리를 가능하게 합니다.

Highlights

  • Redis 캐싱 도입: YouTube 영상 자막 및 상세 정보 조회에 Redis 캐싱 기능을 적용하여 API 중복 호출을 방지하고 성능을 개선했습니다.
  • API 호출 비동기화: 관련 API 호출 로직을 동기 방식에서 비동기 방식으로 전환하여 효율적인 자원 관리 및 성능 향상을 도모했습니다.
  • Redis 락 메커니즘 적용: YouTube 자막 서비스에서 캐시 미스 발생 시 불필요한 동시 API 호출을 막기 위해 Redis 락(lock) 메커니즘을 도입했습니다.
  • Redis 연결 관리: 애플리케이션 시작/종료 시 Redis 연결 및 해제 로직을 추가하여 안정적인 캐시 운영 환경을 구축했습니다.
  • 환경 변수 및 라이브러리 업데이트: Redis 관련 환경 변수를 .env.example에 추가하고, redis[asyncio]tzdata 라이브러리를 requirements.txt에 포함했습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link

🤖 Gemini AI 코드 리뷰

⚠️ 토큰 한도 초과 (부분 응답 가능)


이 리뷰는 Gemini AI가 자동으로 생성했습니다. 참고용으로만 활용해주세요.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이번 PR은 API 호출을 비동기화하고 Redis 캐싱을 도입하여 애플리케이션의 성능과 안정성을 크게 향상시키는 중요한 리팩토링입니다. 특히 transcript_service에서 분산 락(distributed lock)을 사용하여 캐시 미스 시 발생할 수 있는 thundering herd 문제를 방지한 점은 매우 훌륭합니다.

다만, 몇 가지 치명적인 문제점과 개선 사항이 발견되었습니다. 가장 중요한 것은 async 함수 내에서 동기(blocking) I/O 함수를 직접 호출하여 이벤트 루프를 블로킹하는 부분입니다. 이는 비동기 프로그래밍의 이점을 무효화시키므로 반드시 수정이 필요합니다. 관련하여 external/youtube/transcript_service.pyexternal/youtube/video_detail_service.py 파일에 수정 제안을 남겼습니다.

추가로 Redis 클라이언트 싱글톤 구현의 안정성을 높이고, 코드 가독성을 개선하기 위한 몇 가지 제안도 포함했습니다. 이 피드백들이 더 견고하고 효율적인 코드를 만드는 데 도움이 되기를 바랍니다.

Comment on lines 40 to 41
except Exception as e:
cls._instance = None

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Redis 연결 실패 시 Exception을 포괄적으로 잡고 있는데, 이는 예상치 못한 다른 오류까지 숨길 수 있습니다. 또한 에러 로그를 남기지 않아 원인 파악이 어렵습니다. 실패 원인을 기록하기 위해 에러 로깅을 추가하는 것이 좋습니다.

Suggested change
except Exception as e:
cls._instance = None
except Exception as e:
logger.error(f"Redis 연결 실패: {e}")
cls._instance = None


# 2. Lock 획득 시도 (다른 consumer가 조회 중인지 확인)
try:
acquired = await redis_client.set(lock_key, "1", nx=True, ex=30)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

get_structured_transcript 함수 내에 TTL, lock 만료 시간, 폴링 횟수 및 간격 등 여러 매직 넘버가 하드코딩되어 있습니다. 가독성과 유지보수성을 높이기 위해 이 값들을 파일 상단에 상수로 정의하는 것이 좋습니다.

예시:

TRANSCRIPT_CACHE_TTL_SECONDS = 30 * 24 * 3600  # 30일
TRANSCRIPT_LOCK_TIMEOUT_SECONDS = 30
LOCK_POLL_ATTEMPTS = 30
LOCK_POLL_INTERVAL_SECONDS = 1

TranscriptService에서 외부 API 호출 및 데이터 처리 시 메인 이벤트 루프 블로킹을 방지하기 위해 `get_transcript` 내부 조회 로직을 비동기 방식으로 변경

기존 동기 메서드를 비동기 래퍼로 감싸 `asyncio.run_in_executor`를 사용하여 스레드 풀에서 실행하도록 구현
비동기 환경에서 RedisClient의 get_instance 메서드가 동시에 여러 번 호출될 때 발생할 수 있는 race condition 방지
@github-actions
Copy link

🤖 Gemini AI 코드 리뷰

⚠️ 토큰 한도 초과 (부분 응답 가능)


이 리뷰는 Gemini AI가 자동으로 생성했습니다. 참고용으로만 활용해주세요.

@wlswnsdn wlswnsdn merged commit d56f70c into develop Nov 23, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants