diff --git a/dateroad-api/src/main/java/org/dateroad/course/dto/CourseWithPlacesAndTagsDto.java b/dateroad-api/src/main/java/org/dateroad/course/dto/CourseWithPlacesAndTagsDto.java new file mode 100644 index 0000000..fb790b9 --- /dev/null +++ b/dateroad-api/src/main/java/org/dateroad/course/dto/CourseWithPlacesAndTagsDto.java @@ -0,0 +1,14 @@ +package org.dateroad.course.dto; + +import java.util.List; +import lombok.Builder; +import org.dateroad.place.domain.CoursePlace; +import org.dateroad.tag.domain.CourseTag; + + +@Builder +public record CourseWithPlacesAndTagsDto(List coursePlaces, List courseTags) { + public static CourseWithPlacesAndTagsDto of(List coursePlaces, List courseTags) { + return CourseWithPlacesAndTagsDto.builder().coursePlaces(coursePlaces).courseTags(courseTags).build(); + } +} diff --git a/dateroad-api/src/main/java/org/dateroad/course/service/AsyncService.java b/dateroad-api/src/main/java/org/dateroad/course/service/AsyncService.java index 429ad58..dbb49be 100644 --- a/dateroad-api/src/main/java/org/dateroad/course/service/AsyncService.java +++ b/dateroad-api/src/main/java/org/dateroad/course/service/AsyncService.java @@ -8,14 +8,17 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dateroad.code.FailureCode; +import org.dateroad.course.dto.CourseWithPlacesAndTagsDto; import org.dateroad.course.dto.request.CourseCreateEvent; import org.dateroad.course.dto.request.PointUseReq; import org.dateroad.date.domain.Course; import org.dateroad.exception.DateRoadException; import org.dateroad.image.domain.Image; import org.dateroad.image.service.ImageService; +import org.dateroad.place.domain.CoursePlace; import org.dateroad.point.event.MessageDto.FreeMessageDTO; import org.dateroad.point.event.MessageDto.PointMessageDTO; +import org.dateroad.tag.domain.CourseTag; import org.springframework.dao.QueryTimeoutException; import org.springframework.data.redis.connection.stream.RecordId; import org.springframework.data.redis.core.RedisTemplate; @@ -64,11 +67,13 @@ public void publishEventUserFree(final Long userId) { } @Transactional - public void runAsyncTasks(CourseCreateEvent event) { + public CourseWithPlacesAndTagsDto runAsyncTasks(CourseCreateEvent event) { try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) { - CompletableFuture placeFuture = CompletableFuture.runAsync(() -> coursePlaceService.createCoursePlace(event.getPlaces(), event.getCourse()), executor); - CompletableFuture tagFuture = CompletableFuture.runAsync(() -> courseTagService.createCourseTags(event.getTags(), event.getCourse()),executor); - CompletableFuture.allOf(placeFuture, tagFuture).join(); + CompletableFuture> placeFuture = CompletableFuture.supplyAsync(() -> coursePlaceService.createCoursePlace(event.getPlaces(), event.getCourse()), executor); + CompletableFuture> tagFuture = CompletableFuture.supplyAsync(() -> courseTagService.createCourseTags(event.getTags(), event.getCourse()), executor); + CompletableFuture allFutures = CompletableFuture.allOf(placeFuture, tagFuture); + allFutures.join(); + return CourseWithPlacesAndTagsDto.of(placeFuture.join(), tagFuture.join()); } } diff --git a/dateroad-api/src/main/java/org/dateroad/course/service/CoursePlaceService.java b/dateroad-api/src/main/java/org/dateroad/course/service/CoursePlaceService.java index 5d486cd..7e225ce 100644 --- a/dateroad-api/src/main/java/org/dateroad/course/service/CoursePlaceService.java +++ b/dateroad-api/src/main/java/org/dateroad/course/service/CoursePlaceService.java @@ -6,20 +6,13 @@ import org.dateroad.course.dto.request.CoursePlaceGetReq; import org.dateroad.date.domain.Course; import org.dateroad.place.domain.CoursePlace; -import org.dateroad.place.repository.CoursePlaceRepository; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class CoursePlaceService { - private final CoursePlaceRepository coursePlaceRepository; - - public float findTotalDurationByCourseId(final Long id) { - return coursePlaceRepository.findTotalDurationByCourseId(id); - } - - public void createCoursePlace(final List places, final Course course) { - List coursePlaces = places.stream() + public List createCoursePlace(final List places, final Course course) { + return places.stream() .map(placeReq -> CoursePlace.create( placeReq.getTitle(), placeReq.getDuration(), @@ -27,6 +20,5 @@ public void createCoursePlace(final List places, final Course placeReq.getSequence() )) .toList(); - coursePlaceRepository.saveAll(coursePlaces); } } diff --git a/dateroad-api/src/main/java/org/dateroad/course/service/CourseService.java b/dateroad-api/src/main/java/org/dateroad/course/service/CourseService.java index 42259e0..431a81c 100644 --- a/dateroad-api/src/main/java/org/dateroad/course/service/CourseService.java +++ b/dateroad-api/src/main/java/org/dateroad/course/service/CourseService.java @@ -11,6 +11,7 @@ import lombok.RequiredArgsConstructor; import org.dateroad.code.FailureCode; import org.dateroad.common.Constants; +import org.dateroad.course.dto.CourseWithPlacesAndTagsDto; import org.dateroad.course.dto.request.CourseCreateEvent; import org.dateroad.course.dto.request.CourseCreateReq; import org.dateroad.course.dto.request.CourseGetAllReq; @@ -43,7 +44,6 @@ import org.dateroad.user.repository.UserRepository; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -66,7 +66,6 @@ public class CourseService { private final ImageRepository imageRepository; private final CoursePlaceRepository coursePlaceRepository; private final CourseTagRepository courseTagRepository; - private final ApplicationEventPublisher eventPublisher; private final CourseRollbackService courseRollbackService; @Cacheable(value = "courses", key = "#courseGetAllReq") @@ -204,21 +203,18 @@ public CourseCreateRes createCourse(final Long userId, final CourseCreateReq cou totalTime ); Course newcourse = courseRepository.save(course); - eventPublisher.publishEvent(CourseCreateEvent.of(newcourse, places, tags)); - String thumbnail = asyncService.createCourseImages(images, newcourse);// 썸 + CourseWithPlacesAndTagsDto courseWithPlacesAndTagsDto = asyncService.runAsyncTasks(CourseCreateEvent.of(newcourse, places, tags)); + String thumbnail = asyncService.createCourseImages(images, newcourse); course.setThumbnail(thumbnail); - courseRepository.save(newcourse); // 최종적으로 썸네일을 반영하여 저장 + courseRepository.save(newcourse); + coursePlaceRepository.saveAll(courseWithPlacesAndTagsDto.coursePlaces()); + courseTagRepository.saveAll(courseWithPlacesAndTagsDto.courseTags()); RecordId recordId = asyncService.publishEvenUserPoint(userId, PointUseReq.of(Constants.COURSE_CREATE_POINT, TransactionType.POINT_GAINED, "코스 등록하기")); Long userCourseCount = courseRepository.countByUser(user); courseRollbackService.rollbackCourse(recordId); return CourseCreateRes.of(newcourse.getId(), user.getTotalPoint() + Constants.COURSE_CREATE_POINT, userCourseCount); } - @TransactionalEventListener - public void handleCourseCreatedEvent(CourseCreateEvent event) { - asyncService.runAsyncTasks(event); - } - @Transactional public DateAccessCreateRes openCourse(final Long userId, final Long courseId, final PointUseReq pointUseReq) { Course course = getCourse(courseId); diff --git a/dateroad-api/src/main/java/org/dateroad/course/service/CourseTagService.java b/dateroad-api/src/main/java/org/dateroad/course/service/CourseTagService.java index 596c47c..4ee262b 100644 --- a/dateroad-api/src/main/java/org/dateroad/course/service/CourseTagService.java +++ b/dateroad-api/src/main/java/org/dateroad/course/service/CourseTagService.java @@ -6,20 +6,14 @@ import org.dateroad.course.dto.request.TagCreateReq; import org.dateroad.date.domain.Course; import org.dateroad.tag.domain.CourseTag; -import org.dateroad.tag.repository.CourseTagRepository; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class CourseTagService { - private final CourseTagRepository courseTagRepository; - - public void createCourseTags(final List tags, final Course course) { - List coursePlaces = tags.stream() + public List createCourseTags(final List tags, final Course course) { + return tags.stream() .map(tag -> CourseTag.create(course, tag.getTag())) .toList(); - courseTagRepository.saveAll(coursePlaces); } } \ No newline at end of file