-
Notifications
You must be signed in to change notification settings - Fork 0
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
[BG-341]: 배치 reader querydsl로 변환 (6h / 4h) #77
Conversation
👍 |
69c16fa
to
a5eebb8
Compare
@Component | ||
class EventNotificationProcessor { | ||
@Bean | ||
fun processor(): ItemProcessor<EventNotificationQuery, NotificationWithEntityDto> = | ||
ItemProcessor { item -> | ||
val now = LocalDateTime.now() | ||
|
||
if (item.isAfter(now)) { | ||
return@ItemProcessor null | ||
} | ||
|
||
if (!item.shouldSendNotification(now)) { | ||
return@ItemProcessor null | ||
} | ||
|
||
val notification: Notification = | ||
if (item.deadline.isBefore(now)) { | ||
EventOverdue.of(item.userId, Duration.between(item.deadline, now)) | ||
} else { | ||
EventNotCompleted.of(item.userId, Duration.between(now, item.deadline)) | ||
} | ||
|
||
val eventNotificationEntity = | ||
EventNotificationEntity( | ||
title = notification.method.title, | ||
content = notification.method.message, | ||
userId = item.userId, | ||
eventId = item.eventId, | ||
) | ||
|
||
NotificationWithEntityDto.of(notification, eventNotificationEntity) | ||
} | ||
} |
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.
으음...
나는 하나의 빈으로 만들자는게
@Component
class EventNotificationProcessor : ItemProcessor<EventNotificationQuery, NotificationWithEntityDto> {
override fun process(item: EventNotificationQuery): NotificationWithEntityDto? {
val now = LocalDateTime.now()
if (item.isAfter(now)) return null
if (!item.shouldSendNotification(now)) return null
val notification: Notification =
if (item.deadline.isBefore(now)) {
EventOverdue.of(item.userId, Duration.between(item.deadline, now))
} else {
EventNotCompleted.of(item.userId, Duration.between(now, item.deadline))
}
val eventNotificationEntity =
EventNotificationEntity(
title = notification.method.title,
content = notification.method.message,
userId = item.userId,
eventId = item.eventId,
)
return NotificationWithEntityDto.of(notification, eventNotificationEntity)
}
}
이런 그림을 생각했었는데 이렇게 하는 건 어떤가?
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.
기능은 동일하고 스타일 차이긴 해 자바 스타일 코틀린 스타일? 같은
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.
어떤 스타일로 통일하지 ㅎㅎ
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.
1. 함수 정의 방식:
• 첫 번째 코드에서는 @Bean 어노테이션과 함께 함수형 스타일로 processor 함수를 정의하고 있습니다. 이 함수는 ItemProcessor 객체를 반환합니다.
• 두 번째 코드에서는 ItemProcessor 인터페이스를 구현하는 클래스의 process 메소드를 오버라이드하고 있습니다.
2. 클래스 선언 방식:
• 첫 번째 코드에서 EventNotificationProcessor는 클래스 내부에 processor라는 함수를 가지는 단순한 클래스로 선언되어 있습니다. ItemProcessor를 반환하는 이 함수는 별도로 사용될 수 있습니다.
• 두 번째 코드에서는 EventNotificationProcessor 클래스가 ItemProcessor 인터페이스를 직접 구현하여, 해당 클래스를 인스턴스화할 때 ItemProcessor 타입으로 사용할 수 있습니다.
3. 리턴 방식:
• 첫 번째 코드에서는 ItemProcessor { item -> ... } 내부에서 return@ItemProcessor을 사용하여 특정 조건을 만족하지 않을 때 null을 반환합니다.
• 두 번째 코드에서는 process 메소드 안에서 직접 return null을 사용하여 조건이 맞지 않을 경우 null을 반환합니다.
정리
• 첫 번째 코드는 더 함수형 스타일로 작성되어 있으며, ItemProcessor를 구성 요소로 반환하는 방식입니다. 이 방법은 특정한 처리 로직을 다른 곳에서 쉽게 주입하거나 교체할 수 있는 장점이 있습니다.
• 두 번째 코드는 전통적인 OOP 스타일로, 클래스 자체가 ItemProcessor를 구현하고 있습니다. 이는 더 명시적이며, 해당 클래스가 ItemProcessor 역할을 수행한다고 바로 알 수 있습니다.
이 두 스타일은 상황과 선호도에 따라 선택될 수 있으며, 기능적으로는 동일하게 동작합니다.
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.
GPT 가 그렇대 ㅎㅎ
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.
맞아 근데 writer는 내가 말한것 처럼 구현했고 processor나 reader는 저렇게 했길랭!
그럼 그냥 뭐든 통일만 하면 좋을 것 같긴한뎅!
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.
reader를 바꾸는게 좀 빡세서 @Bean
스타일로
@Component | ||
class NotificationPublisherWriter( | ||
private val notificationEventService: NotificationEventService, | ||
) : ItemWriter<NotificationWithEntityDto> { | ||
override fun write(it: Chunk<out NotificationWithEntityDto>) { | ||
it.forEach { item -> | ||
notificationEventService.publishNotificationEvent(item.notification) | ||
} | ||
} | ||
} |
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.
writer
는 하나의 빈으로 되어있긴하넹?
@Bean | ||
@StepScope | ||
fun compositeWriter(): CompositeItemWriter<NotificationWithEntityDto> = | ||
CompositeItemWriterBuilder<NotificationWithEntityDto>() | ||
.delegates(listOf(eventNotificationWriter, notificationPublisherWriter)) | ||
.build() | ||
} |
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.
compositeWriter
좋넹! 👍🏼
Why
배치 테스트 작성에서 시간이 생각보다 오래 걸렸다
추가로 테스트 환경에서의
datasource
설정하는데 오래 걸림How
Querydsl ItemReader를 추가하고
reader, processor, writer 를 분리
Prize
배치에는
@Transactional
을 사용하지 못하는데이렇게 되면 testContainer 에 데이터가 계속 추가되어
다음 테스트에 영향을 주게 된다.
Link
BG-341