Skip to content

Conversation

@sunwon12
Copy link
Contributor

@sunwon12 sunwon12 commented Dec 15, 2025

History

  • 이번 PR은 퀴즈 생성을 위한 Gemini API 연동 아키텍처를 전반적으로 리팩터링하여, 클라이언트 관리, rate limiting, 서킷브레이크, 모니터링, 요청/프롬프트 생성 책임을 각각의 모듈로 분리하는 작업입니다.
    이를 통해 기존 GeminiSdkClient, GeminiClientManager 등에 몰려 있던 로직을 정리하고 로직 흐름의 가시성을 높이는 게 목표입니다
  • 기존에는 키를 획득 후 제미나이 응답이 성공적이라면 rate limit를 위해서 RPM, PRD를 +1 하는 구조였습니다. 기존 로직의 문제점은 제미나이 응답이 길어질 시 요청은 되었지만 +1이 안되어 rate limit이 도달했지만 다른 스레드들도 같은 API Key로 요청할 수 있습니다

Major Changes & Explanations

  • Gemini 클라이언트 아키텍처를 모듈화하여, API 호출, 클라이언트 관리, 레이트 리미터, 회로 차단기, 프롬프트/요청 생성 로직을 각각의 서비스/컴포넌트로 분리했습니다.

  • GeminiRateLimiterService와 Redis를 활용해 일일/슬라이딩 윈도우 레이트 리밋을 중앙에서 관리하고, GeminiRetryHandler가 라운드로빈 방식으로 계정을 순회하며 레이트 리밋된 계정은 스킵하도록 재시도 전략을 개선했습니다.

  • GeminiMonitoringScheduler를 통해 시간별 사용 리포트와 일간/주간 토큰 사용량을 Discord로 전송하는 모니터링·알림 기능을 추가해 운영 시 가시성을 강화했습니다.

  • GeminiRequest DTO, GeminiRequestFactory, CustomObjectMapper 등을 도입해 Gemini 요청/응답 생성과 파싱을 표준화하고, API 연동 코드에서 공통 관심사를 분리했습니다.

  • RPM, PRD를 미리 +1 하고 제미나이 응답이 실패했다면 롤백하는 구조로

리뷰 시에는

  • 새 아키텍처가 기존 퀴즈 생성 플로우(도메인 서비스, 이벤트 흐름 등)와 잘 연결되는지,
  • 레이트 리미트/리트라이 정책이 실제 운영 기준(일일 쿼터, SLA)에 맞게 설계되었는지,
  • 모니터링 지표와 Discord 알림 포맷이 운영자가 바로 이해하기 좋은 수준인지
    를 중심으로 봐주시면 좋겠습니다.

- GeminiClientManager 통합, GeminiRateLimiterService 리팩토링(Stateless), 불필요한 클래스 제거 및 관련 의존성 수정
- Token Tracking & Usage Logic 통합
- Gemini Monitoring & Discord Alerts
@sunwon12 sunwon12 requested a review from AlphaBs December 15, 2025 18:56
@sunwon12 sunwon12 self-assigned this Dec 15, 2025
@sunwon12 sunwon12 added the ♻️ refactor Extra attention is needed label Dec 15, 2025
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @sunwon12, 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!

This pull request significantly refactors the architecture for interacting with the Gemini API, particularly for quiz generation. The changes introduce a more modular and robust design by separating concerns into distinct services for API client management, rate limiting, circuit breaking, and request/prompt generation. This enhances the system's resilience against API rate limits and failures, improves monitoring capabilities with detailed usage reports, and streamlines the process of making Gemini API calls through better abstraction and centralized error handling.

Highlights

  • Gemini Client Architecture Refactor: The Gemini API interaction logic has been completely overhauled, moving from a few large classes (GeminiSdkClient, GeminiClientManager) to a more modular structure with dedicated services for API calls, client management, rate limiting, circuit breaking, and prompt/request generation.
  • Centralized Rate Limiting and Retry: A new GeminiRateLimiterService handles both daily and sliding window rate limits using Redis, and GeminiRetryHandler intelligently retries API calls using available Gemini accounts in a Round-Robin fashion, skipping rate-limited ones.
  • Enhanced Monitoring and Alerting: A new GeminiMonitoringScheduler provides hourly usage reports and daily/weekly token usage summaries, sent via Discord, improving visibility into Gemini API consumption.
  • Improved Request/Response Abstraction: The introduction of GeminiRequest DTO, GeminiRequestFactory, and CustomObjectMapper centralizes and standardizes the process of building requests and parsing responses for Gemini API calls.
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.

Copy link
Contributor

@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

안녕하세요. Gemini 클라이언트 및 Rate Limiter 아키텍처 리팩토링 PR을 검토했습니다. 전반적으로 큰 클래스들을 작고 책임이 명확한 컴포넌트로 분리하여 코드의 유지보수성과 테스트 용이성을 크게 향상시킨 훌륭한 리팩토링입니다. 특히 API 호출, 재시도, 서킷 브레이커, 속도 제한 등의 로직을 명확하게 분리한 점이 인상적입니다. 다만, 몇 가지 예외 처리 및 안정성 관련하여 개선이 필요한 부분을 발견하여 코멘트를 남겼습니다. 해당 부분들을 수정하면 더욱 견고한 코드가 될 것 같습니다. 수고 많으셨습니다!

Comment on lines +37 to +49
for (Account account : geminiAccountConfig.getAccounts()) {
try {
Client client = Client.builder()
.apiKey(account.getApiKey())
.build();

clientList.add(client);
nameList.add(account.getName());
log.info("Gemini Client 등록 성공: {}", account.getName());
} catch (Exception e) {
log.error("Gemini Client 초기화 실패: {}", account.getName(), e);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

생성자에서 Gemini 클라이언트 초기화 시 발생하는 Exception을 단순히 로깅만 하고 넘어가는 점이 우려됩니다. 만약 모든 API 키가 유효하지 않아 clients 리스트가 비어있게 되면, getAvailableClient() 메서드에서 clients.size()가 0이 되어 ArithmeticException: / by zero가 발생하여 애플리케이션이 오작동할 수 있습니다. 모든 클라이언트 초기화에 실패하면 애플리케이션을 시작하지 못하도록 처리하는 것이 더 안전합니다. 생성자 루프 이후에 clients 리스트가 비어있는지 확인하는 로직을 추가하는 것을 권장합니다.

@github-actions
Copy link

github-actions bot commented Dec 15, 2025

Test Results

103 files  103 suites   17s ⏱️
533 tests 533 ✅ 0 💤 0 ❌
543 runs  543 ✅ 0 💤 0 ❌

Results for commit a9e5241.

♻️ This comment has been updated with latest results.

@sunwon12 sunwon12 changed the title [Quiz][Refactor] Gemini Client & Rate Limiter 아키텍쳐 [Quiz][Refactor] Gemini Client & Rate Limiter 책임 분리 및 RPM, RPD 선획득 롤백 Dec 15, 2025
@github-actions
Copy link

github-actions bot commented Dec 15, 2025

🌻 테스트 커버리지 리포트

Overall Project 52.63% -1.94% 🍏
Files changed 55.62% 🍏

File Coverage
GeminiClientContext.java 100% 🍏
GeminiRateLimiterService.java 99.36% -0.64% 🍏
GeminiRetryHandler.java 96.23% -1.51% 🍏
GeminiClientManager.java 91.67% -8.33% 🍏
Book.java 79.62% 🍏
GeminiSdkClient.java 76.26% -23.74% 🍏
GeminiTokenTracker.java 44.44% -16.34%
GeminiCircuitBreakerService.java 21.67% -78.33%
GeminiMonitoringScheduler.java 17.92% -82.08%
GeminiRequestFactory.java 15% -85%
GeminiApiService.java 5.88% -94.12%
GeminiQuizPromptProvider.java 1.43% -98.57%

@sunwon12 sunwon12 merged commit 77abbc3 into dev Dec 15, 2025
1 check passed
@sunwon12 sunwon12 deleted the refactor/quiz-solid branch December 15, 2025 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

♻️ refactor Extra attention is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants