From 0840fbd8e68d54c7945defc7b7275cc4e8824a6f Mon Sep 17 00:00:00 2001 From: Junh-b Date: Thu, 29 May 2025 09:37:52 +0900 Subject: [PATCH 1/6] =?UTF-8?q?fix:=20TradeService=EA=B0=80=20=EB=B9=88=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=EB=A5=BC=20=EB=B0=9C=ED=96=89?= =?UTF-8?q?=ED=95=98=EB=8D=98=20issue=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit builder 패턴 사용시 build 내용이 누락되던 issue 해결 --- .../cleanengine/coin/trade/application/TradeService.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/cleanengine/coin/trade/application/TradeService.java b/src/main/java/com/cleanengine/coin/trade/application/TradeService.java index 398a9dca..2d09e30b 100644 --- a/src/main/java/com/cleanengine/coin/trade/application/TradeService.java +++ b/src/main/java/com/cleanengine/coin/trade/application/TradeService.java @@ -246,12 +246,15 @@ public void executeTrade(WaitingOrders waitingOrders, TradePair tr this.updateWalletAfterTrade(sellOrder, ticker, tradedSize, totalTradedPrice); // 체결내역 저장 - this.insertNewTrade(ticker, buyOrder, sellOrder, tradedSize, tradedPrice); + Trade trade = this.insertNewTrade(ticker, buyOrder, sellOrder, tradedSize, tradedPrice); // 호가 조회를 위한 Order Service 메서드 호출 updateOrderBookUsecase.updateOrderBookOnTradeExecuted(ticker, buyOrder.getId(), sellOrder.getId(), tradedSize); - TradeExecutedEvent tradeExecutedEvent = TradeExecutedEvent.builder().build(); + TradeExecutedEvent tradeExecutedEvent = + TradeExecutedEvent.builder() + .trade(trade) + .build(); tradeExecutedEventPublisher.publish(tradeExecutedEvent); } From 5789a3a4751d144c6686b77aa754aacb83e61bd5 Mon Sep 17 00:00:00 2001 From: Junh-b Date: Thu, 29 May 2025 09:39:51 +0900 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20TradeExecutedEvent=EA=B0=80=20orderI?= =?UTF-8?q?d=EB=8F=84=20=EB=B0=98=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TradeExecutedEvent가 체결 당시의 맥락을 온전히 담을 수 있도록 OrderId를 추가로 넣는 방식으로 변환했습니다. --- .../cleanengine/coin/trade/application/TradeExecutedEvent.java | 2 ++ .../com/cleanengine/coin/trade/application/TradeService.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/com/cleanengine/coin/trade/application/TradeExecutedEvent.java b/src/main/java/com/cleanengine/coin/trade/application/TradeExecutedEvent.java index dbbd5fef..11f90ebb 100644 --- a/src/main/java/com/cleanengine/coin/trade/application/TradeExecutedEvent.java +++ b/src/main/java/com/cleanengine/coin/trade/application/TradeExecutedEvent.java @@ -8,4 +8,6 @@ @Builder public class TradeExecutedEvent { Trade trade; + Long buyOrderId; + Long sellOrderId; } diff --git a/src/main/java/com/cleanengine/coin/trade/application/TradeService.java b/src/main/java/com/cleanengine/coin/trade/application/TradeService.java index 2d09e30b..5aa9c547 100644 --- a/src/main/java/com/cleanengine/coin/trade/application/TradeService.java +++ b/src/main/java/com/cleanengine/coin/trade/application/TradeService.java @@ -254,6 +254,8 @@ public void executeTrade(WaitingOrders waitingOrders, TradePair tr TradeExecutedEvent tradeExecutedEvent = TradeExecutedEvent.builder() .trade(trade) + .buyOrderId(buyOrder.getId()) + .sellOrderId(sellOrder.getId()) .build(); tradeExecutedEventPublisher.publish(tradeExecutedEvent); } From 6c5f79e0addb781df99a5ee6f05edd4d8da938f9 Mon Sep 17 00:00:00 2001 From: Junh-b Date: Thu, 29 May 2025 09:40:32 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20=ED=98=B8=EA=B0=80=EC=B8=A1=20?= =?UTF-8?q?=EA=B0=B1=EC=8B=A0=EC=9D=84=20EventHandler=20=EB=B0=A9=EC=8B=9D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 체결이 완료되었을 때, 동기적으로 호출하던 내용을 EventHandler 방식으로 변경했습니다. --- ...ngTradeExecutedUpdateOrderBookHandler.java | 21 +++++++++++++++++++ .../coin/trade/application/TradeService.java | 8 +------ 2 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/cleanengine/coin/orderbook/infra/SpringTradeExecutedUpdateOrderBookHandler.java diff --git a/src/main/java/com/cleanengine/coin/orderbook/infra/SpringTradeExecutedUpdateOrderBookHandler.java b/src/main/java/com/cleanengine/coin/orderbook/infra/SpringTradeExecutedUpdateOrderBookHandler.java new file mode 100644 index 00000000..6d96f693 --- /dev/null +++ b/src/main/java/com/cleanengine/coin/orderbook/infra/SpringTradeExecutedUpdateOrderBookHandler.java @@ -0,0 +1,21 @@ +package com.cleanengine.coin.orderbook.infra; + +import com.cleanengine.coin.orderbook.application.service.UpdateOrderBookUsecase; +import com.cleanengine.coin.trade.application.TradeExecutedEvent; +import com.cleanengine.coin.trade.entity.Trade; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.transaction.event.TransactionalEventListener; + +@Component +@RequiredArgsConstructor +public class SpringTradeExecutedUpdateOrderBookHandler { + private final UpdateOrderBookUsecase updateOrderBookUsecase; + + @TransactionalEventListener + public void onTradeExecutedEvent(TradeExecutedEvent tradeExecutedEvent) { + Trade trade = tradeExecutedEvent.getTrade(); + updateOrderBookUsecase.updateOrderBookOnTradeExecuted(trade.getTicker(), + tradeExecutedEvent.getBuyOrderId(), tradeExecutedEvent.getSellOrderId(), trade.getSize()); + } +} diff --git a/src/main/java/com/cleanengine/coin/trade/application/TradeService.java b/src/main/java/com/cleanengine/coin/trade/application/TradeService.java index 5aa9c547..5ffe6609 100644 --- a/src/main/java/com/cleanengine/coin/trade/application/TradeService.java +++ b/src/main/java/com/cleanengine/coin/trade/application/TradeService.java @@ -7,7 +7,6 @@ import com.cleanengine.coin.order.domain.*; import com.cleanengine.coin.order.domain.spi.WaitingOrders; import com.cleanengine.coin.order.domain.spi.WaitingOrdersManager; -import com.cleanengine.coin.orderbook.application.service.UpdateOrderBookUsecase; import com.cleanengine.coin.trade.entity.Trade; import com.cleanengine.coin.trade.repository.TradeRepository; import com.cleanengine.coin.user.domain.Account; @@ -35,21 +34,19 @@ public class TradeService { private final WalletRepository walletRepository; @Getter private final WaitingOrdersManager waitingOrdersManager; - private final UpdateOrderBookUsecase updateOrderBookUsecase; private final TradeExecutedEventPublisher tradeExecutedEventPublisher; // 1초마다 큐 로깅 private long lastLogTime = 0; private static final long LOG_INTERVAL = 1000; - public TradeService(TradeRepository tradeRepository, BuyOrderRepository buyOrderRepository, SellOrderRepository sellOrderRepository, AccountRepository accountRepository, WalletRepository walletRepository, WaitingOrdersManager waitingOrdersManager, UpdateOrderBookUsecase updateOrderBookUsecase, TradeExecutedEventPublisher tradeExecutedEventPublisher) { + public TradeService(TradeRepository tradeRepository, BuyOrderRepository buyOrderRepository, SellOrderRepository sellOrderRepository, AccountRepository accountRepository, WalletRepository walletRepository, WaitingOrdersManager waitingOrdersManager, TradeExecutedEventPublisher tradeExecutedEventPublisher) { this.tradeRepository = tradeRepository; this.buyOrderRepository = buyOrderRepository; this.sellOrderRepository = sellOrderRepository; this.accountRepository = accountRepository; this.walletRepository = walletRepository; this.waitingOrdersManager = waitingOrdersManager; - this.updateOrderBookUsecase = updateOrderBookUsecase; this.tradeExecutedEventPublisher = tradeExecutedEventPublisher; } @@ -248,9 +245,6 @@ public void executeTrade(WaitingOrders waitingOrders, TradePair tr // 체결내역 저장 Trade trade = this.insertNewTrade(ticker, buyOrder, sellOrder, tradedSize, tradedPrice); - // 호가 조회를 위한 Order Service 메서드 호출 - updateOrderBookUsecase.updateOrderBookOnTradeExecuted(ticker, buyOrder.getId(), sellOrder.getId(), tradedSize); - TradeExecutedEvent tradeExecutedEvent = TradeExecutedEvent.builder() .trade(trade) From b7b2359ce9f78565aa873daf71a25d90aed4ab18 Mon Sep 17 00:00:00 2001 From: Junh-b Date: Fri, 30 May 2025 13:59:29 +0900 Subject: [PATCH 4/6] =?UTF-8?q?fix:=20=EC=A3=BC=EB=AC=B8=20Handler=20Event?= =?UTF-8?q?=20=EB=AF=B8=EC=A7=80=EC=A0=95=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TradeExecutedEvent 발생시 핸들러가 실행되도록 수정했습니다. --- .../infra/SpringTradeExecutedUpdateOrderBookHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/cleanengine/coin/orderbook/infra/SpringTradeExecutedUpdateOrderBookHandler.java b/src/main/java/com/cleanengine/coin/orderbook/infra/SpringTradeExecutedUpdateOrderBookHandler.java index 6d96f693..1fa747ba 100644 --- a/src/main/java/com/cleanengine/coin/orderbook/infra/SpringTradeExecutedUpdateOrderBookHandler.java +++ b/src/main/java/com/cleanengine/coin/orderbook/infra/SpringTradeExecutedUpdateOrderBookHandler.java @@ -12,7 +12,7 @@ public class SpringTradeExecutedUpdateOrderBookHandler { private final UpdateOrderBookUsecase updateOrderBookUsecase; - @TransactionalEventListener + @TransactionalEventListener(TradeExecutedEvent.class) public void onTradeExecutedEvent(TradeExecutedEvent tradeExecutedEvent) { Trade trade = tradeExecutedEvent.getTrade(); updateOrderBookUsecase.updateOrderBookOnTradeExecuted(trade.getTicker(), From 60f2c0710538e82669e58f5832f473099184341d Mon Sep 17 00:00:00 2001 From: Junh-b Date: Fri, 30 May 2025 13:59:59 +0900 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20=ED=98=B8=EA=B0=80=20=EA=B0=B1?= =?UTF-8?q?=EC=8B=A0=EC=8B=9C=20=EC=9E=94=EB=9F=89=EC=9D=84=20=EA=B8=B0?= =?UTF-8?q?=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EC=B6=94=EA=B0=80=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 주문 복원 기능에 대해서도 일관적으로 동작하도록 수정했습니다. --- .../coin/orderbook/application/service/OrderBookService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/cleanengine/coin/orderbook/application/service/OrderBookService.java b/src/main/java/com/cleanengine/coin/orderbook/application/service/OrderBookService.java index 8d5358d3..3360b9e9 100644 --- a/src/main/java/com/cleanengine/coin/orderbook/application/service/OrderBookService.java +++ b/src/main/java/com/cleanengine/coin/orderbook/application/service/OrderBookService.java @@ -30,7 +30,7 @@ public void updateOrderBookOnNewOrder(Order order) { activeOrders(ticker).saveOrder(order); boolean isBuyOrder = order instanceof BuyOrder; - orderBookDomainService.updateOrderBookOnNewOrder(ticker, isBuyOrder, order.getPrice(), order.getOrderSize()); + orderBookDomainService.updateOrderBookOnNewOrder(ticker, isBuyOrder, order.getPrice(), order.getRemainingSize()); sendOrderBookUpdated(ticker); } From c86974c1ad113efeea13d69358a861a4fe00a58d Mon Sep 17 00:00:00 2001 From: Junh-b Date: Sat, 31 May 2025 18:04:11 +0900 Subject: [PATCH 6/6] =?UTF-8?q?refactor:=20=EB=8B=A4=EB=A5=B8=20handler?= =?UTF-8?q?=EC=9D=98=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=ED=95=B8=EB=93=A4?= =?UTF-8?q?=EB=A7=81=20style=EC=97=90=20=EB=A7=9E=EA=B2=8C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EventListener의 class명을 명시적으로 기재하지 않고, method의 spec을 기반으로 Spring이 event를 주입하는 방식으로 변경했습니다. --- .../adapter/in/event/SpringOrderCreatedAddQueueHandler.java | 2 +- .../in/event/SpringOrderCreatedUpdateOrderBookHandler.java | 2 +- .../infra/SpringTradeExecutedUpdateOrderBookHandler.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/cleanengine/coin/order/adapter/in/event/SpringOrderCreatedAddQueueHandler.java b/src/main/java/com/cleanengine/coin/order/adapter/in/event/SpringOrderCreatedAddQueueHandler.java index 4af03dbb..04c314da 100644 --- a/src/main/java/com/cleanengine/coin/order/adapter/in/event/SpringOrderCreatedAddQueueHandler.java +++ b/src/main/java/com/cleanengine/coin/order/adapter/in/event/SpringOrderCreatedAddQueueHandler.java @@ -16,7 +16,7 @@ public class SpringOrderCreatedAddQueueHandler { private final WaitingOrdersManager waitingOrdersManager; private final ApplicationEventPublisher applicationEventPublisher; - @TransactionalEventListener(OrderCreated.class) + @TransactionalEventListener public void handleOrderCreated(OrderCreated event) { Order order = event.order(); WaitingOrders waitingOrders = waitingOrdersManager.getWaitingOrders(order.getTicker()); diff --git a/src/main/java/com/cleanengine/coin/order/adapter/in/event/SpringOrderCreatedUpdateOrderBookHandler.java b/src/main/java/com/cleanengine/coin/order/adapter/in/event/SpringOrderCreatedUpdateOrderBookHandler.java index ba4572e9..aef0fbd9 100644 --- a/src/main/java/com/cleanengine/coin/order/adapter/in/event/SpringOrderCreatedUpdateOrderBookHandler.java +++ b/src/main/java/com/cleanengine/coin/order/adapter/in/event/SpringOrderCreatedUpdateOrderBookHandler.java @@ -11,7 +11,7 @@ public class SpringOrderCreatedUpdateOrderBookHandler { private final UpdateOrderBookUsecase updateOrderBookUsecase; - @TransactionalEventListener(OrderCreated.class) + @TransactionalEventListener public void handleOrderCreated(OrderCreated event) { updateOrderBookUsecase.updateOrderBookOnNewOrder(event.order()); } diff --git a/src/main/java/com/cleanengine/coin/orderbook/infra/SpringTradeExecutedUpdateOrderBookHandler.java b/src/main/java/com/cleanengine/coin/orderbook/infra/SpringTradeExecutedUpdateOrderBookHandler.java index 1fa747ba..6d96f693 100644 --- a/src/main/java/com/cleanengine/coin/orderbook/infra/SpringTradeExecutedUpdateOrderBookHandler.java +++ b/src/main/java/com/cleanengine/coin/orderbook/infra/SpringTradeExecutedUpdateOrderBookHandler.java @@ -12,7 +12,7 @@ public class SpringTradeExecutedUpdateOrderBookHandler { private final UpdateOrderBookUsecase updateOrderBookUsecase; - @TransactionalEventListener(TradeExecutedEvent.class) + @TransactionalEventListener public void onTradeExecutedEvent(TradeExecutedEvent tradeExecutedEvent) { Trade trade = tradeExecutedEvent.getTrade(); updateOrderBookUsecase.updateOrderBookOnTradeExecuted(trade.getTicker(),