Skip to content

Conversation

@dev-ant
Copy link
Contributor

@dev-ant dev-ant commented Nov 4, 2025

📋 상세 설명

  • 경매 내역 스케줄러를 카테고리별 배치 처리 방식으로 개선
  • Too Many Request를 해결하기 위해 OPEN API 호출 간 지연을 설정할 수 있도록 변경
  • 로컬 개발용 Docker 환경을 추가하고, Dockerfile을 수정해 ARM/AMD 아키텍처 모두 지원하도록 변경

📊 체크리스트

  • PR 제목이 형식에 맞나요 e.g. feat: PR을 등록한다
  • 코드가 테스트 되었나요
  • 문서는 업데이트 되었나요
  • 불필요한 코드를 제거했나요
  • 이슈와 라벨이 등록되었나요

📆 마감일

Close #66

@dev-ant dev-ant requested a review from Copilot November 4, 2025 15:16
@dev-ant dev-ant self-assigned this Nov 4, 2025
@dev-ant dev-ant added the 🔧fix 버그 해결 label Nov 4, 2025
@github-actions
Copy link

github-actions bot commented Nov 4, 2025

✅ 테스트 결과 for PR

Build: success

🧪 테스트 실행 with Gradle
📈 Coverage: -0.00%

📁 테스트 결과
📁 커버리지 보고서 (HTML)

@codecov
Copy link

codecov bot commented Nov 4, 2025

Codecov Report

❌ Patch coverage is 0% with 45 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...application/scheduler/AuctionHistoryScheduler.java 0.00% 45 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refactors the auction history scheduler to batch process categories by top-level groupings with configurable delays, adds local development Docker environment support, and updates documentation.

  • Refactored AuctionHistoryScheduler to group item categories by top category and process/save them in batches with configurable delays between API calls
  • Added docker-compose-local.yml and .env.local.sample for local development with MySQL container
  • Updated Dockerfile to support both ARM64 and AMD64 architectures by removing alpine variant

Reviewed Changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/main/java/until/the/eternity/auctionhistory/application/scheduler/AuctionHistoryScheduler.java Refactored scheduler to group categories by top category, process in batches with delays, and save per top category
docker-compose-local.yml Added new Docker Compose configuration for local development environment with MySQL
docker-compose-dev.yaml Added explicit build configuration with context and dockerfile
.env.local.sample Added environment variable template for local development
Dockerfile Removed alpine variant for multi-architecture support
README.md Added local development section with Docker instructions
.gitignore Added .env.local to ignored files and updated comments
docs/CD_PIPELINE_GUIDE.md Updated step names from docker-compose.yaml to docker-compose-dev.yaml
.github/workflows/push-cd-dev.yml Updated step name from docker-compose.yaml to docker-compose-dev.yaml
.github/workflows/push-cd-prod.yml Updated step name from docker-compose.yaml to docker-compose-dev.yaml

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

image: open-api-batch-server:local
container_name: spring-app-local
ports:
-
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

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

Incomplete port mapping configuration. Line 16 has a dangling '-' without a port mapping, while line 17 has the actual port mapping. This will cause a YAML parsing error. Remove line 16.

Suggested change
-

Copilot uses AI. Check for mistakes.
private final AuctionHistoryPersister persister;

@Value("${openapi.auction-history.delay-ms}")
private long delayMs;
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

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

Using @Value to inject configuration into a field of a @RequiredArgsConstructor class can lead to NullPointerException if the field is accessed before Spring initializes it. Consider using constructor injection with @ConfigurationProperties or changing to setter injection with a @PostConstruct validation method to ensure the value is properly initialized.

Suggested change
private long delayMs;
private final long delayMs;

Copilot uses AI. Check for mistakes.
log.debug(
"> [SCHEDULE] Waiting {}ms before processing next category",
delayMs);
Thread.sleep(delayMs);
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

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

Using Thread.sleep() in a scheduler method can block the scheduler thread pool, potentially affecting other scheduled tasks. Consider using @Async with CompletableFuture and non-blocking delays, or ensure the scheduler is configured with an appropriate thread pool size to handle blocking operations.

Copilot uses AI. Check for mistakes.
log.debug(
"> [SCHEDULE] Waiting {}ms before processing next top category",
delayMs);
Thread.sleep(delayMs);
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

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

Using Thread.sleep() in a scheduler method can block the scheduler thread pool, potentially affecting other scheduled tasks. Consider using @Async with CompletableFuture and non-blocking delays, or ensure the scheduler is configured with an appropriate thread pool size to handle blocking operations.

Copilot uses AI. Check for mistakes.
Comment on lines +70 to +76
} catch (InterruptedException e) {
log.error(
"> [SCHEDULE] Thread interrupted during delay for category [{}]",
category.getSubCategory(),
e);
Thread.currentThread().interrupt();
break;
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

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

When breaking out of the inner loop due to InterruptedException, the outer loop continues processing subsequent top categories. Consider propagating the interrupt state to break out of the outer loop as well, or document why continuing with other top categories is the desired behavior.

Copilot uses AI. Check for mistakes.

- **로컬 개발**: 코드 수정 시마다 `--build` 옵션으로 재빌드 필요
- **메모리 설정**: 로컬 환경은 메모리 사용량이 낮게 설정되어 있음 (512MB)
- **데이터베이스**: `DB_IP=host.docker.internal`로 호스트 머신의 MySQL에 접근
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

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

The documentation states that DB_IP=host.docker.internal is used to access MySQL on the host machine, but according to the docker-compose-local.yml (line 31), it's set to mysql which refers to the MySQL container service name, not the host. This documentation is inconsistent with the actual implementation. Update to reflect that the local setup uses a containerized MySQL service.

Suggested change
- **데이터베이스**: `DB_IP=host.docker.internal`호스트 머신의 MySQL에 접근
- **데이터베이스**: `DB_IP=mysql`Docker Compose의 MySQL 컨테이너에 접근 (`mysql`은 서비스 이름)

Copilot uses AI. Check for mistakes.
- name: Copy docker-compose.yaml to server
- name: Copy docker-compose-dev.yaml to server
run: |
scp -i ~/.ssh/my-key.pem docker-compose.yaml ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:/home/${{ secrets.SERVER_USER }}/app/
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

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

The step name says 'Copy docker-compose-dev.yaml to server' but the command copies 'docker-compose.yaml'. Either update the command to scp docker-compose-dev.yaml to match the step name, or revert the step name change if 'docker-compose.yaml' is the correct file to copy.

Suggested change
scp -i ~/.ssh/my-key.pem docker-compose.yaml ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:/home/${{ secrets.SERVER_USER }}/app/
scp -i ~/.ssh/my-key.pem docker-compose-dev.yaml ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:/home/${{ secrets.SERVER_USER }}/app/

Copilot uses AI. Check for mistakes.
ssh -i ~/.ssh/my-key.pem ${{ secrets.PROD_SERVER_USER }}@${{ secrets.PROD_SERVER_HOST }} "mkdir -p /home/${{ secrets.PROD_SERVER_USER }}/app/logs"
- name: Copy docker-compose.yaml to server
- name: Copy docker-compose-dev.yaml to server
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

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

The step name says 'Copy docker-compose-dev.yaml to server' but the command copies 'docker-compose.yaml'. Either update the command to scp docker-compose-dev.yaml to match the step name, or revert the step name change if 'docker-compose.yaml' is the correct file to copy.

Suggested change
- name: Copy docker-compose-dev.yaml to server
- name: Copy docker-compose.yaml to server

Copilot uses AI. Check for mistakes.

| 환경 | Docker Compose 파일 | 설명 |
|------|---------------------|------|
| **로컬 개발** | `docker-compose.local.yml` | 로컬 코드 빌드, 낮은 리소스 사용 |
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

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

Filename inconsistency: The table references docker-compose.local.yml but the actual filename is docker-compose-local.yml (with hyphen, not dot). Update the table to use the correct filename.

Suggested change
| **로컬 개발** | `docker-compose.local.yml` | 로컬 코드 빌드, 낮은 리소스 사용 |
| **로컬 개발** | `docker-compose-local.yml` | 로컬 코드 빌드, 낮은 리소스 사용 |

Copilot uses AI. Check for mistakes.
@dev-ant dev-ant requested a review from Copilot November 4, 2025 15:38
@dev-ant dev-ant merged commit cb239a5 into dev Nov 4, 2025
5 of 6 checks passed
@dev-ant dev-ant deleted the fix/too-many-request branch November 4, 2025 15:39
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- name: Copy docker-compose.yaml to server
- name: Copy docker-compose-dev.yaml to server
run: |
scp -i ~/.ssh/my-key.pem docker-compose.yaml ${{ secrets.PROD_SERVER_USER }}@${{ secrets.PROD_SERVER_HOST }}:/home/${{ secrets.PROD_SERVER_USER }}/app/
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

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

The step name says 'Copy docker-compose-dev.yaml' but the actual command copies 'docker-compose.yaml'. This mismatch will cause the deployment to fail as the file being copied doesn't exist in the repository. Change the filename in the scp command to 'docker-compose-dev.yaml'.

Suggested change
scp -i ~/.ssh/my-key.pem docker-compose.yaml ${{ secrets.PROD_SERVER_USER }}@${{ secrets.PROD_SERVER_HOST }}:/home/${{ secrets.PROD_SERVER_USER }}/app/
scp -i ~/.ssh/my-key.pem docker-compose-dev.yaml ${{ secrets.PROD_SERVER_USER }}@${{ secrets.PROD_SERVER_HOST }}:/home/${{ secrets.PROD_SERVER_USER }}/app/

Copilot uses AI. Check for mistakes.
# =============================================================================
# Database Configuration
# =============================================================================
# 로컬 MySQL 사용 시 (Docker로 MySQL 실행하는 경우)
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

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

The .env.local.sample suggests using DB_IP=host.docker.internal for accessing a MySQL on the host machine, but docker-compose-local.yml line 30 overrides this with DB_IP: mysql (the Docker service name) in the environment section. This configuration in the sample file will be ignored and may confuse users. Update the comment to clarify that the MySQL service is included in the compose file and the DB_IP is overridden.

Suggested change
# 로컬 MySQL 사용 시 (Docker로 MySQL 실행하는 경우)
# 로컬 MySQL 사용 시
# ⚠️ docker-compose.local.yml을 사용할 경우, DB_IP는 'mysql'(서비스 이름)로 오버라이드됩니다.
# 아래 값은 Docker Compose를 사용하지 않고 직접 실행할 때만 적용됩니다.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔧fix 버그 해결

Projects

None yet

Development

Successfully merging this pull request may close these issues.

오픈 API 비동기 호출로 인한 Too Many Requests Error 발생

2 participants