Skip to content

Commit 2d583e2

Browse files
authored
refactor(be): 라이더 배달 로직 리팩토링 (#141)
* refactor: rider 반경 검색 해당 아이디 중 상태가 OFF인 아이디 검색 제외 * refactor: kafka 설계 redis pub/sub으로 전환 * refactor: 배달료 계산 공식 전환 -> 기본 배달료 + a
1 parent bbe3d75 commit 2d583e2

File tree

10 files changed

+109
-45
lines changed

10 files changed

+109
-45
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.deliveranything.domain.delivery.event.event;
2+
3+
import com.deliveranything.domain.delivery.event.dto.RiderNotificationDto;
4+
import com.deliveranything.global.exception.CustomException;
5+
import com.deliveranything.global.exception.ErrorCode;
6+
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import java.util.List;
8+
import lombok.RequiredArgsConstructor;
9+
import org.springframework.data.redis.core.StringRedisTemplate;
10+
import org.springframework.stereotype.Service;
11+
12+
@Service
13+
@RequiredArgsConstructor
14+
public class RedisPublisher {
15+
16+
private final StringRedisTemplate redisTemplate;
17+
private final ObjectMapper objectMapper;
18+
19+
public void publish(List<RiderNotificationDto> dtoList) {
20+
dtoList.forEach(dto -> {
21+
try {
22+
String channel = "order-events";
23+
String message = objectMapper.writeValueAsString(dto);
24+
redisTemplate.convertAndSend(channel, message);
25+
} catch (Exception e) {
26+
throw new CustomException(ErrorCode.REDIS_MESSAGE_PROCESSING_ERROR);
27+
}
28+
});
29+
}
30+
}

backend/src/main/java/com/deliveranything/domain/delivery/event/event/RiderEtaPublisher.java

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
package com.deliveranything.domain.delivery.handler;
22

33
import com.deliveranything.domain.delivery.event.dto.OrderDeliveryCreatedEvent;
4-
import com.deliveranything.domain.delivery.event.event.RiderEtaPublisher;
4+
import com.deliveranything.domain.delivery.event.event.RedisPublisher;
55
import com.deliveranything.domain.delivery.service.OrderNotificationService;
66
import lombok.RequiredArgsConstructor;
7-
import org.springframework.kafka.annotation.KafkaListener;
7+
import org.springframework.context.event.EventListener;
88
import org.springframework.stereotype.Component;
99

1010
@Component
1111
@RequiredArgsConstructor
1212
public class OrderDeliveryEventHandler {
1313

1414
private final OrderNotificationService orderNotificationService;
15-
private final RiderEtaPublisher riderEtaPublisher;
15+
private final RedisPublisher redisPublisher; // Kafka → Redis 변경
1616

17-
@KafkaListener(topics = "order-events", groupId = "delivery-service")
17+
@EventListener // @KafkaListener → @EventListener로 변경
1818
public void handleOrderCreated(OrderDeliveryCreatedEvent orderEvent) {
19-
// Kafka 발행 분리
2019
orderNotificationService.processOrderEvent(orderEvent)
21-
.subscribe(riderEtaPublisher::publish);
20+
.subscribe(redisPublisher::publish); // Kafka → Redis 변경
2221
}
2322
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.deliveranything.domain.delivery.handler;
2+
3+
import com.deliveranything.domain.delivery.event.dto.RiderNotificationDto;
4+
import com.deliveranything.domain.delivery.websocket.RiderWebSocketPublisher;
5+
import com.deliveranything.global.exception.CustomException;
6+
import com.deliveranything.global.exception.ErrorCode;
7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
import lombok.RequiredArgsConstructor;
9+
import lombok.extern.slf4j.Slf4j;
10+
import org.springframework.data.redis.connection.Message;
11+
import org.springframework.data.redis.connection.MessageListener;
12+
import org.springframework.stereotype.Component;
13+
14+
@Slf4j
15+
@Component
16+
@RequiredArgsConstructor
17+
public class RedisSubscriber implements MessageListener {
18+
19+
private final RiderWebSocketPublisher webSocketPublisher;
20+
private final ObjectMapper objectMapper;
21+
22+
@Override
23+
public void onMessage(Message message, byte[] pattern) {
24+
try {
25+
String channel = new String(message.getChannel());
26+
String body = new String(message.getBody());
27+
28+
if ("order-events".equals(channel)) {
29+
RiderNotificationDto dto = objectMapper.readValue(body, RiderNotificationDto.class);
30+
webSocketPublisher.publishToRider(dto.riderId(), dto);
31+
}
32+
} catch (Exception e) {
33+
throw new CustomException(ErrorCode.REDIS_MESSAGE_PROCESSING_ERROR);
34+
}
35+
}
36+
}

backend/src/main/java/com/deliveranything/domain/delivery/handler/RiderEtaConsumer.java

Lines changed: 0 additions & 19 deletions
This file was deleted.

backend/src/main/java/com/deliveranything/domain/delivery/service/OrderNotificationService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public Mono<List<RiderNotificationDto>> processOrderEvent(OrderDeliveryCreatedEv
3131

3232
return distanceKmMono.flatMap(distanceMap -> {
3333
double distanceKm = distanceMap.getOrDefault("distance", 0.0);
34-
int expectedCharge = (int) (distanceKm * 1000); // 임시 배달료 계산
34+
int expectedCharge = 1000 + (int) (distanceKm * 500); // 임시 배달료 계산
3535

3636
// 2️⃣ 반경 내 라이더 ETA 조회
3737
return reactiveRiderEtaService.findNearbyRidersEta(customerLat, customerLon, 3.0)

backend/src/main/java/com/deliveranything/domain/delivery/service/ReactiveRiderEtaService.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
import static com.deliveranything.domain.delivery.service.RiderLocationService.RIDER_GEO_KEY;
44

5+
import com.deliveranything.domain.user.entity.profile.RiderProfile;
6+
import com.deliveranything.domain.user.enums.RiderToggleStatus;
7+
import com.deliveranything.domain.user.repository.RiderProfileRepository;
8+
import com.deliveranything.global.exception.CustomException;
9+
import com.deliveranything.global.exception.ErrorCode;
510
import java.util.ArrayList;
611
import java.util.List;
712
import java.util.Map;
@@ -23,6 +28,7 @@ public class ReactiveRiderEtaService {
2328

2429
private final StringRedisTemplate redisTemplate;
2530
private final EtaService etaService;
31+
private final RiderProfileRepository riderProfileRepository;
2632

2733
//반경 내 라이더 검색 후 ETA 계산
2834
// Kafka 발행(2차 구현)
@@ -46,6 +52,11 @@ public Mono<Map<String, Double>> findNearbyRidersEta(double customerLat, double
4652

4753
for (GeoResult<RedisGeoCommands.GeoLocation<String>> result : nearbyRiders) {
4854
RedisGeoCommands.GeoLocation<String> loc = result.getContent();
55+
RiderProfile riderProfile = riderProfileRepository.findById(Long.parseLong(loc.getName()))
56+
.orElseThrow(() -> new CustomException(ErrorCode.RIDER_NOT_FOUND));
57+
if (riderProfile.getToggleStatus() == RiderToggleStatus.OFF) {
58+
continue; // OFF 상태 라이더는 제외
59+
}
4960
riderIds.add(loc.getName());
5061
riderPoints.add(loc.getPoint());
5162
}

backend/src/main/java/com/deliveranything/domain/delivery/websocket/RiderWebSocketPublisher.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class RiderWebSocketPublisher {
1212

1313
private final SimpMessagingTemplate messagingTemplate;
1414

15+
// 여기 SSE 변경 보류
1516
public void publishToRider(String riderId, RiderNotificationDto dto) {
1617
String destination = "/topic/rider/" + riderId;
1718
messagingTemplate.convertAndSend(destination, dto);

backend/src/main/java/com/deliveranything/global/config/RedisConfig.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
package com.deliveranything.global.config;
22

3+
import com.deliveranything.domain.delivery.handler.RedisSubscriber;
4+
import lombok.RequiredArgsConstructor;
35
import org.springframework.context.annotation.Bean;
46
import org.springframework.context.annotation.Configuration;
57
import org.springframework.data.redis.connection.RedisConnectionFactory;
68
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
79
import org.springframework.data.redis.core.RedisTemplate;
810
import org.springframework.data.redis.core.StringRedisTemplate;
11+
import org.springframework.data.redis.listener.PatternTopic;
12+
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
913
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
1014
import org.springframework.data.redis.serializer.StringRedisSerializer;
1115

1216
@Configuration
17+
@RequiredArgsConstructor
1318
public class RedisConfig {
1419

20+
private final RedisSubscriber redisSubscriber;
21+
1522
@Bean
1623
public LettuceConnectionFactory redisConnectionFactory() {
1724
return new LettuceConnectionFactory(); // application.yml 기반으로 host/port 세팅
@@ -34,4 +41,17 @@ public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connec
3441
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
3542
return new StringRedisTemplate(connectionFactory);
3643
}
44+
45+
// Redis Pub/Sub용 추가
46+
@Bean
47+
public RedisMessageListenerContainer redisMessageListenerContainer(
48+
RedisConnectionFactory connectionFactory) {
49+
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
50+
container.setConnectionFactory(connectionFactory);
51+
52+
// order-events 채널 구독
53+
container.addMessageListener(redisSubscriber, new PatternTopic("order-events"));
54+
55+
return container;
56+
}
3757
}

backend/src/main/java/com/deliveranything/global/exception/ErrorCode.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ public enum ErrorCode {
4343
STORE_CATEGORY_NOT_FOUND(HttpStatus.NOT_FOUND, "STORE-CATEGORY-404", "상점 카테고리를 찾을 수 없습니다."),
4444

4545
// SSE 관련 오류
46-
SSE_SUBSCRIBE_UNAVAILABLE(HttpStatus.SERVICE_UNAVAILABLE, "SSE-503", "SSE 연결에 실패했습니다.");
46+
SSE_SUBSCRIBE_UNAVAILABLE(HttpStatus.SERVICE_UNAVAILABLE, "SSE-503", "SSE 연결에 실패했습니다."),
47+
48+
// Redis 관련 오류
49+
REDIS_MESSAGE_PROCESSING_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "REDIS-500",
50+
"Redis 메시지 처리 중 오류가 발생했습니다.");
4751

4852
private final HttpStatus httpStatus;
4953
private final String code;

0 commit comments

Comments
 (0)