Skip to content

Commit

Permalink
๐Ÿ”จ Refactor/#185 - ๊ฒŒ์‹œํŒ์— ๊ธฐ๊ฐ„ ์ถ”๊ฐ€, ๊ธฐ๊ฐ„์— ๋”ฐ๋ฅธ ์Šค์ผ€์ค„๋ง ๋กœ์ง ์ถ”๊ฐ€ ๋ฐ Response ๋ณ€๊ฒฝ (#186)
Browse files Browse the repository at this point in the history
  • Loading branch information
dongkyeomjang authored Dec 1, 2024
1 parent 458139c commit 1905cff
Show file tree
Hide file tree
Showing 33 changed files with 408 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/main/java/com/daon/onjung/account/domain/Store.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public class Store {
/* -------------------------------------------- */
/* One To One Mapping ------------------------ */
/* -------------------------------------------- */
@OneToOne
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "owner_id")
private Owner owner;

Expand Down
27 changes: 27 additions & 0 deletions src/main/java/com/daon/onjung/core/listener/AppEventListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import com.daon.onjung.core.exception.type.CommonException;
import com.daon.onjung.event.repository.redis.ScheduledEventJobRepository;
import com.daon.onjung.event.application.controller.consumer.EventSchedulerConsumerV1Controller;
import com.daon.onjung.suggestion.application.controller.consumer.BoardSchedulerConsumerV1Controller;
import com.daon.onjung.suggestion.domain.redis.ScheduledBoardJob;
import com.daon.onjung.suggestion.repository.redis.ScheduledBoardJobRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
Expand All @@ -21,6 +24,7 @@ public class AppEventListener {
private final Scheduler scheduler;

private final ScheduledEventJobRepository scheduledEventJobRepository;
private final ScheduledBoardJobRepository scheduledBoardJobRepository;

@EventListener
public void handleEventScheduled(ScheduledEventJob scheduledEventJob) {
Expand All @@ -45,4 +49,27 @@ public void handleEventScheduled(ScheduledEventJob scheduledEventJob) {
}
}

@EventListener
public void handleBoardScheduled(ScheduledBoardJob scheduledBoardJob) {
JobDetail jobDetail = JobBuilder.newJob(BoardSchedulerConsumerV1Controller.class)
.withIdentity("boardJob-" + scheduledBoardJob.getJobId(), "boardGroup")
.usingJobData("boardId", scheduledBoardJob.getBoardId())
.build();
log.info("Job ๋“ฑ๋ก ์™„๋ฃŒ. boardId: {}", scheduledBoardJob.getBoardId());

Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("boardTrigger-" + scheduledBoardJob.getJobId(), "boardGroup")
.startAt(Timestamp.valueOf(scheduledBoardJob.getScheduledTime()))
.build();
log.info("boardId {}์— ๋Œ€ํ•œ Trigger ๋“ฑ๋ก ์™„๋ฃŒ.", scheduledBoardJob.getBoardId());
log.info("Trigger ์‹œ์ž‘ ์‹œ๊ฐ„: {}", trigger.getStartTime());

try {
scheduler.scheduleJob(jobDetail, trigger);
scheduledBoardJobRepository.save(scheduledBoardJob);
} catch (SchedulerException e) {
throw new CommonException(ErrorCode.SCHEDULER_ERROR);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import com.daon.onjung.event.domain.redis.ScheduledEventJob;
import com.daon.onjung.event.repository.redis.ScheduledEventJobRepository;
import com.daon.onjung.event.application.controller.consumer.EventSchedulerConsumerV1Controller;
import com.daon.onjung.suggestion.application.controller.consumer.BoardSchedulerConsumerV1Controller;
import com.daon.onjung.suggestion.domain.redis.ScheduledBoardJob;
import com.daon.onjung.suggestion.repository.redis.ScheduledBoardJobRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
Expand All @@ -20,36 +23,59 @@ public class SchedulerRecoveryListener implements CommandLineRunner {

private final ScheduledEventJobRepository scheduledEventJobRepository;
private final Scheduler scheduler;
private final ScheduledBoardJobRepository scheduledBoardJobRepository;

@Override
public void run(String... args) throws Exception {
LocalDateTime now = LocalDateTime.now();
List<ScheduledEventJob> pendingJobs = scheduledEventJobRepository.findAll();
log.info("๋ฏธ์ฒ˜๋ฆฌ Job ์กฐํšŒ ์™„๋ฃŒ. ์กฐํšŒ๋œ Job ์ˆ˜: {}", pendingJobs.size());
if (pendingJobs.isEmpty()) {
List<ScheduledEventJob> pendingEventJobs = scheduledEventJobRepository.findAll();
log.info("๋ฏธ์ฒ˜๋ฆฌ Event Job ์กฐํšŒ ์™„๋ฃŒ. ์กฐํšŒ๋œ Job ์ˆ˜: {}", pendingEventJobs.size());
if (!pendingEventJobs.isEmpty()) {
for (ScheduledEventJob job : pendingEventJobs) {
if (job == null) {
log.warn("์กฐํšŒ๋œ Job ์ค‘ null ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.");
continue;
}
if (job.getScheduledTime() == null) {
log.warn("Job์˜ scheduledTime ๊ฐ’์ด null์ž…๋‹ˆ๋‹ค. eventId: {}", job.getEventId());
continue;
}
if (job.getScheduledTime().isAfter(now)) {
log.info("๋ฏธ๋ž˜ ์ž‘์—… ์Šค์ผ€์ค„๋Ÿฌ์— ์žฌ๋“ฑ๋ก. eventId: {}", job.getEventId());
scheduleEventJob(job);
} else {
executeEventJobImmediately(job);
}
}
}

List<ScheduledBoardJob> pendingBoardJobs = scheduledBoardJobRepository.findAll();
log.info("๋ฏธ์ฒ˜๋ฆฌ Board Job ์กฐํšŒ ์™„๋ฃŒ. ์กฐํšŒ๋œ Job ์ˆ˜: {}", pendingBoardJobs.size());

if (pendingBoardJobs.isEmpty()) {
return;
}
for (ScheduledEventJob job : pendingJobs) {
for (ScheduledBoardJob job : pendingBoardJobs) {
if (job == null) {
log.warn("์กฐํšŒ๋œ Job ์ค‘ null ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.");
continue;
}
if (job.getScheduledTime() == null) {
log.warn("Job์˜ scheduledTime ๊ฐ’์ด null์ž…๋‹ˆ๋‹ค. eventId: {}", job.getEventId());
log.warn("Job์˜ scheduledTime ๊ฐ’์ด null์ž…๋‹ˆ๋‹ค. boardId: {}", job.getBoardId());
continue;
}
if (job.getScheduledTime().isAfter(now)) {
log.info("๋ฏธ๋ž˜ ์ž‘์—… ์Šค์ผ€์ค„๋Ÿฌ์— ์žฌ๋“ฑ๋ก. eventId: {}", job.getEventId());
scheduleJob(job);
log.info("๋ฏธ๋ž˜ ์ž‘์—… ์Šค์ผ€์ค„๋Ÿฌ์— ์žฌ๋“ฑ๋ก. boardId: {}", job.getBoardId());
scheduleBoardJob(job);
} else {
executeJobImmediately(job);
executeBoardJobImmediately(job);
}
}
}

private void scheduleJob(ScheduledEventJob job) throws SchedulerException {
private void scheduleEventJob(ScheduledEventJob job) throws SchedulerException {
JobDetail jobDetail = JobBuilder.newJob(EventSchedulerConsumerV1Controller.class)
.withIdentity("eventJob-" + job.getEventId(), "eventGroup")
.withIdentity("eventJob-" + job.getJobId(), "eventGroup")
.usingJobData("eventId", job.getEventId())
.build();

Expand All @@ -61,7 +87,7 @@ private void scheduleJob(ScheduledEventJob job) throws SchedulerException {
scheduler.scheduleJob(jobDetail, trigger);
}

private void executeJobImmediately(ScheduledEventJob scheduledEventJob) {
private void executeEventJobImmediately(ScheduledEventJob scheduledEventJob) {
try {
JobDetail jobDetail = JobBuilder.newJob(EventSchedulerConsumerV1Controller.class)
.withIdentity("eventJob-" + scheduledEventJob.getJobId(), "eventGroup")
Expand All @@ -86,4 +112,44 @@ private void executeJobImmediately(ScheduledEventJob scheduledEventJob) {
// ์‹คํŒจ ์‹œ ์‚ญ์ œํ•˜์ง€ ์•Š์Œ. ํ•„์š”ํ•˜๋ฉด ์žฌ์‹œ๋„ ํ์— ์ถ”๊ฐ€ํ•˜๋Š” ๋กœ์ง ๊ณ ๋ ค
}
}

private void scheduleBoardJob(ScheduledBoardJob job) throws SchedulerException {
JobDetail jobDetail = JobBuilder.newJob(BoardSchedulerConsumerV1Controller.class)
.withIdentity("boardJob-" + job.getJobId(), "boardGroup")
.usingJobData("boardId", job.getBoardId())
.build();

Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger-" + job.getJobId(), "boardGroup")
.startAt(Timestamp.valueOf(job.getScheduledTime()))
.build();

scheduler.scheduleJob(jobDetail, trigger);
}

private void executeBoardJobImmediately(ScheduledBoardJob scheduledBoardJob) {
try {
JobDetail jobDetail = JobBuilder.newJob(BoardSchedulerConsumerV1Controller.class)
.withIdentity("boardJob-" + scheduledBoardJob.getJobId(), "boardGroup")
.usingJobData("boardId", scheduledBoardJob.getBoardId())
.build();
log.info("Job ๋“ฑ๋ก ์™„๋ฃŒ. boardId: {}", scheduledBoardJob.getBoardId());

Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("boardTrigger-" + scheduledBoardJob.getJobId(), "boardGroup")
.startNow()
.build();

// ์ž‘์—… ์Šค์ผ€์ค„๋ง
scheduler.scheduleJob(jobDetail, trigger);

// ์‹คํ–‰ ์„ฑ๊ณต ์‹œ ์ž‘์—… ์‚ญ์ œ
scheduledBoardJobRepository.delete(scheduledBoardJob);

log.info("์ด์ „์— ๋“ฑ๋กํ–ˆ์ง€๋งŒ ์‹คํ–‰์•ˆ๋œ, ๊ธฐ๊ฐ„์ด ์ง€๋‚œ Job์„ ์ฆ‰์‹œ ์‹คํ–‰ํ•จ. boardId: {}", scheduledBoardJob.getBoardId());
} catch (SchedulerException e) {
log.error("Job ์ฆ‰์‹œ์‹คํ–‰์— ์‹คํŒจ. boardId: {}", scheduledBoardJob.getBoardId(), e);
// ์‹คํŒจ ์‹œ ์‚ญ์ œํ•˜์ง€ ์•Š์Œ. ํ•„์š”ํ•˜๋ฉด ์žฌ์‹œ๋„ ํ์— ์ถ”๊ฐ€ํ•˜๋Š” ๋กœ์ง ๊ณ ๋ ค
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.daon.onjung.event.application.controller.consumer;

import com.daon.onjung.event.repository.redis.ScheduledEventJobRepository;
import com.daon.onjung.event.application.usecase.ProcessCompletedEventUseCase;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -13,18 +12,12 @@
public class EventSchedulerConsumerV1Controller implements Job {

private final ProcessCompletedEventUseCase processCompletedEventUseCase;
private final ScheduledEventJobRepository scheduledEventJobRepository;

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// JobDataMap์„ ํ†ตํ•ด eventId๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
Long eventId = context.getJobDetail().getJobDataMap().getLong("eventId");

// eventId๋ฅผ ํ†ตํ•ด ScheduledEventJob์„ ์‚ญ์ œ
scheduledEventJobRepository.findByEventId(eventId)
.ifPresent(scheduledEventJobRepository::delete);
log.info("ScheduledEventJob ์‚ญ์ œ ์™„๋ฃŒ. eventId: {}", eventId);

processCompletedEventUseCase.execute(eventId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.daon.onjung.account.domain.User;
import com.daon.onjung.account.domain.type.EBankName;
import com.daon.onjung.account.repository.mysql.UserRepository;
import com.daon.onjung.event.domain.service.ScheduledEventJobService;
import com.daon.onjung.core.dto.CreateVirtualAccountResponseDto;
import com.daon.onjung.core.exception.error.ErrorCode;
import com.daon.onjung.core.exception.type.CommonException;
Expand All @@ -16,9 +15,11 @@
import com.daon.onjung.event.domain.mysql.Event;
import com.daon.onjung.event.domain.mysql.Ticket;
import com.daon.onjung.event.domain.service.EventService;
import com.daon.onjung.event.domain.service.ScheduledEventJobService;
import com.daon.onjung.event.domain.service.TicketService;
import com.daon.onjung.event.repository.mysql.EventRepository;
import com.daon.onjung.event.repository.mysql.TicketRepository;
import com.daon.onjung.event.repository.redis.ScheduledEventJobRepository;
import com.daon.onjung.onjung.repository.mysql.DonationRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -40,6 +41,7 @@ public class ProcessCompletedEventService implements ProcessCompletedEventUseCas
private final UserRepository userRepository;
private final TicketRepository ticketRepository;
private final DonationRepository donationRepository;
private final ScheduledEventJobRepository scheduledEventJobRepository;

private final EventService eventService;
private final TicketService ticketService;
Expand All @@ -55,6 +57,11 @@ public class ProcessCompletedEventService implements ProcessCompletedEventUseCas
@Transactional
public void execute(Long eventId) {

// eventId๋ฅผ ํ†ตํ•ด ScheduledEventJob์„ ์‚ญ์ œ
scheduledEventJobRepository.findByEventId(eventId)
.ifPresent(scheduledEventJobRepository::delete);
log.info("ScheduledEventJob ์‚ญ์ œ ์™„๋ฃŒ. eventId: {}", eventId);

// ์ด๋ฒคํŠธ ์กฐํšŒ
Event currentEvent = eventRepository.findById(eventId)
.orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_RESOURCE));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.daon.onjung.suggestion.application.controller.consumer;

import com.daon.onjung.suggestion.application.usecase.ProcessCompletedBoardUseCase;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;

@RequiredArgsConstructor
@Slf4j
public class BoardSchedulerConsumerV1Controller implements Job {

private final ProcessCompletedBoardUseCase processCompletedBoardUseCase;

@Override
public void execute(JobExecutionContext context) {
// JobDataMap์„ ํ†ตํ•ด boardId๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
Long boardId = context.getJobDetail().getJobDataMap().getLong("boardId");

processCompletedBoardUseCase.execute(boardId);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import com.daon.onjung.core.exception.type.CommonException;
import com.daon.onjung.suggestion.application.dto.request.CommentMessage;
import com.daon.onjung.suggestion.application.dto.response.CreateCommentResponseDto;
import com.daon.onjung.suggestion.domain.Board;
import com.daon.onjung.suggestion.domain.Comment;
import com.daon.onjung.suggestion.domain.mysql.Board;
import com.daon.onjung.suggestion.domain.mysql.Comment;
import com.daon.onjung.suggestion.domain.service.BoardService;
import com.daon.onjung.suggestion.domain.service.CommentService;
import com.daon.onjung.suggestion.repository.mysql.BoardRepository;
Expand All @@ -21,7 +21,7 @@

@Service
@RequiredArgsConstructor
public class CommentV1Consumer {
public class CommentConsumerV1Controller {

private final BoardRepository boardRepository;
private final CommentRepository commentRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
import com.daon.onjung.core.exception.error.ErrorCode;
import com.daon.onjung.core.exception.type.CommonException;
import com.daon.onjung.suggestion.application.dto.request.LikeMessage;
import com.daon.onjung.suggestion.application.dto.response.CreateOrDeleteLikeResponseDto;
import com.daon.onjung.suggestion.domain.Board;
import com.daon.onjung.suggestion.domain.Like;
import com.daon.onjung.suggestion.domain.mysql.Board;
import com.daon.onjung.suggestion.domain.mysql.Like;
import com.daon.onjung.suggestion.domain.service.BoardService;
import com.daon.onjung.suggestion.domain.service.LikeService;
import com.daon.onjung.suggestion.repository.mysql.BoardRepository;
Expand All @@ -20,7 +19,7 @@

@Service
@RequiredArgsConstructor
public class LikeV1Consumer {
public class LikeConsumerV1Controller {

private final LikeRepository likeRepository;
private final BoardRepository boardRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.daon.onjung.account.domain.User;
import com.daon.onjung.core.dto.SelfValidating;
import com.daon.onjung.core.utility.DateTimeUtil;
import com.daon.onjung.suggestion.domain.Comment;
import com.daon.onjung.suggestion.domain.mysql.Comment;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Getter;
Expand Down
Loading

0 comments on commit 1905cff

Please sign in to comment.