Actions
개선(improvement) #2611
open개선(improvement) #2310: [BE] Optimize Memory, CPU API search list flight
[BE] CRITICAL: AtomicReference Memory Retention in getListItinerary()
Start date:
12/15/2025
Due date:
12/15/2025 (about 3 months late)
% Done:
0%
Estimated time:
Part:
Build env.:
Description
Problem¶
The getListItinerary() method (Lines 2769-2988) used AtomicReference to pass data between reactive pipeline steps, causing memory retention issues.
Original Anti-Pattern Code¶
Non-basket path:
AtomicReference<JsonNode> responseJsonNodeReference = new AtomicReference<>();
Mono<Void> getListAllMono = flightListAllService.getListAll(requestBody)
.doOnNext(responseJsonNodeReference::set)
.then();
Mono<JsonNode> convertMono = Mono.defer(() -> {
return convertAllToItinerary(requestBody, responseJsonNodeReference.get());
});
return Flux.concat(getListAllMono).then(convertMono);
Basket path:
AtomicReference<FlightListItineraryBasketItemVo> basketItemReference = new AtomicReference<>();
AtomicReference<JsonNode> responseJsonNodeReference = new AtomicReference<>();
List<FlightListItineraryBasketSegmentVo> basketSegmentList = new ArrayList<>();
// Sequential execution
return Flux.concat(basketFlightItemMono, basketFlightSegmentMono,
setBasketUseReqeustBodyMono, getListAllMono, findBasketFlightItemMono)
.then(convertMono);
Solution¶
Non-basket path - Direct reactive chain:
return flightListAllService.getListAll(requestBody)
.flatMap(responseJsonNode -> convertAllToItinerary(requestBody, responseJsonNode));
Basket path - Parallel execution with Mono.zip:
return Mono.zip(
flightListItineraryFluxMapper.getBasketFlightItem(requestBodyMap),
flightListItineraryFluxMapper.getBasketFlightSegmentList(requestBodyMap),
flightListAllService.getListAll(requestBody)
).flatMap(tuple -> {
FlightListItineraryBasketItemVo basketItem = tuple.getT1();
List<FlightListItineraryBasketSegmentVo> basketSegmentList = tuple.getT2();
JsonNode responseJsonNode = tuple.getT3();
// Processing logic with direct variable access
// Proper Mono.error() for exceptions
return convertAllToItinerary(requestBody, responseJsonNode);
});
Improvements¶
- Memory: Eliminated AtomicReference holding 10-50 MB JsonNode beyond useful lifetime
- Performance: Parallel execution of 3 async operations instead of sequential (basket mode)
- Clarity: Removed confusing
Mono.defer()+doOnNext()pattern - Error Handling: Proper
Mono.error()instead of throwing exceptions inMono.fromRunnable() - GC Pressure: Variables now scoped properly, eligible for GC immediately after use
Impact¶
- Reduced memory retention by ~30-50% per basket request
- Improved request latency in basket mode by enabling parallel database and vendor calls
File¶
web-api/src/main/java/com/ohmy/api/service/flight/FlightListItineraryService.java
Updated by Dante Le 3 months ago
- Subject changed from [BE] CRITICAL-1: AtomicReference Memory Retention in getListItinerary() to [BE] CRITICAL: AtomicReference Memory Retention in getListItinerary()
- Due date set to 12/15/2025
- Status changed from 신규(New) to 진행(Doing)
- Start date set to 12/15/2025
- Estimated time deleted (
2.00 h)
Actions