-
Notifications
You must be signed in to change notification settings - Fork 0
refactor: 레포지토리 저장 로직 변경 #83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -17,7 +17,6 @@ | |||||||||||||||||||||||||||||||
| import com.devoops.service.github.WebHookService; | ||||||||||||||||||||||||||||||||
| import com.devoops.service.repository.RepositoryService; | ||||||||||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||||||||||
| import java.util.Optional; | ||||||||||||||||||||||||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||||||||||||||||||||||||
| import org.springframework.context.ApplicationEventPublisher; | ||||||||||||||||||||||||||||||||
| import org.springframework.stereotype.Service; | ||||||||||||||||||||||||||||||||
|
|
@@ -36,24 +35,23 @@ public class RepositoryFacadeService { | |||||||||||||||||||||||||||||||
| public GithubRepository save(RepositorySaveRequest request, User user) { | ||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||
| GithubRepoUrl repoUrl = new GithubRepoUrl(request.url()); | ||||||||||||||||||||||||||||||||
| GithubRepository savedRepository = saveRepository(repoUrl, user); | ||||||||||||||||||||||||||||||||
| webHookService.registerWebhook(user, savedRepository.getId()); | ||||||||||||||||||||||||||||||||
| GithubRepoInfoResponse repositoryInfo = gitHubService.getRepositoryInfo(repoUrl, user.getGithubToken()); | ||||||||||||||||||||||||||||||||
| GithubRepository savedRepository = repositoryService.findByUserAndExternalId(user, repositoryInfo.id()) | ||||||||||||||||||||||||||||||||
| .map(alreadyRegisteredRepo -> reTrackingOrThrowException(user, alreadyRegisteredRepo)) | ||||||||||||||||||||||||||||||||
| .orElseGet(() -> registerNewRepo(repositoryInfo, repoUrl, user)); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| eventPublisher.publishEvent(new AnalyzeMyPrEvent(repoUrl, user, this)); | ||||||||||||||||||||||||||||||||
| return savedRepository; | ||||||||||||||||||||||||||||||||
| } catch (GithubNotFoundException githubNotFoundException) { | ||||||||||||||||||||||||||||||||
| throw new GssException(ErrorCode.REGISTRY_GITHUB_REPOSITORY_NOT_FOUND); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private GithubRepository saveRepository(GithubRepoUrl url, User user) { | ||||||||||||||||||||||||||||||||
| GithubRepoInfoResponse repositoryInfo = gitHubService.getRepositoryInfo(url, user.getGithubToken()); | ||||||||||||||||||||||||||||||||
| long externalId = repositoryInfo.id(); | ||||||||||||||||||||||||||||||||
| Optional<GithubRepository> alreadyRegisteredRepo = repositoryService.findByUserAndExternalId(user, externalId); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if(alreadyRegisteredRepo.isPresent()) { | ||||||||||||||||||||||||||||||||
| return reTrackingOrThrowException(user, alreadyRegisteredRepo.get()); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private GithubRepository registerNewRepo( | ||||||||||||||||||||||||||||||||
| GithubRepoInfoResponse repositoryInfo, | ||||||||||||||||||||||||||||||||
| GithubRepoUrl url, | ||||||||||||||||||||||||||||||||
| User user | ||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||
| RepositoryCreateCommand createCommand = new RepositoryCreateCommand( | ||||||||||||||||||||||||||||||||
| user.getId(), | ||||||||||||||||||||||||||||||||
| repositoryInfo.name(), | ||||||||||||||||||||||||||||||||
|
|
@@ -62,7 +60,9 @@ private GithubRepository saveRepository(GithubRepoUrl url, User user) { | |||||||||||||||||||||||||||||||
| INITIAL_PULL_REQUEST_COUNT, | ||||||||||||||||||||||||||||||||
| repositoryInfo.id() | ||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||
| return repositoryService.save(createCommand); | ||||||||||||||||||||||||||||||||
| GithubRepository savedRepository = repositoryService.save(createCommand); | ||||||||||||||||||||||||||||||||
| webHookService.registerWebhook(user, savedRepository.getId()); | ||||||||||||||||||||||||||||||||
| return savedRepository; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+63
to
66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 웹훅 등록은 트랜잭션 커밋 후로 지연시켜야 외부 부작용과 롤백 불일치를 막을 수 있습니다. 현재는 DB 저장 → 웹훅 호출 순이며, 이후 예외로 롤백되면 GitHub에는 훅이 남고 DB에는 레코드가 없는 불일치가 생길 수 있습니다. 커밋 이후에 호출하도록 전환해 주세요(예: TransactionSynchronizationManager 또는 @TransactionalEventListener 사용). 아주 국소 수정 예시: - GithubRepository savedRepository = repositoryService.save(createCommand);
- webHookService.registerWebhook(user, savedRepository.getId());
- return savedRepository;
+ GithubRepository savedRepository = repositoryService.save(createCommand);
+ // 커밋 이후 실행
+ org.springframework.transaction.support.TransactionSynchronizationManager
+ .registerSynchronization(new org.springframework.transaction.support.TransactionSynchronization() {
+ @Override
+ public void afterCommit() {
+ webHookService.registerWebhook(user, savedRepository.getId());
+ }
+ });
+ return savedRepository;또는 도메인 이벤트 발행 → 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private GithubRepository reTrackingOrThrowException(User user, GithubRepository registeredRepo) { | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
신규/기존 분기 로직은 명확합니다. 다만 동시성 레이스를 방지하는 보강이 필요합니다.
동일 유저가 같은 repo를 거의 동시에 저장하면 둘 다
findByUserAndExternalId에서 미존재로 판단 후save로 진입할 수 있습니다. DB 유니크 제약이 있다면DataIntegrityViolationException으로 끝나고, 없다면 중복 데이터가 생깁니다.registerNewRepo내부에서 저장 시 예외를 캐치해 재조회/재연결로 폴백하는 방식을 권장합니다.가능한 보강 예시(핵심 아이디어만 제시):
registerNewRepo에서save를 try/catch로 감싸 폴백 처리(아래 코멘트 참고).🤖 Prompt for AI Agents