Skip to content

Commit 481578f

Browse files
authored
Merge pull request #51 from SW-Maestro-OSS/refactor/CoinTradeStream
[CVW-039] 코인 거래내역 정보 객체 책임 리팩토링
2 parents 968cc64 + e918653 commit 481578f

File tree

19 files changed

+168
-164
lines changed

19 files changed

+168
-164
lines changed

Projects/App/Sources/DI/Assembly/DataAssembly.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ public class DataAssembly: Assembly {
4040
DefaultExchangeRateService()
4141
}
4242

43+
// MARK: DataSource
44+
container.register(CoinTradeDataSource.self) { _ in
45+
BinanceCoinTradeDataSource()
46+
}
4347

4448
// MARK: Repository
4549
container.register(UserConfigurationRepository.self) { _ in
@@ -63,8 +67,8 @@ public class DataAssembly: Assembly {
6367
BinanceSingleMarketTickerRepository()
6468
}
6569

66-
container.register(TradeRepository.self) { _ in
67-
BinanceTradeRepository()
70+
container.register(CoinTradeRepository.self) { _ in
71+
BinanceCoinTradeRepository()
6872
}
6973
}
7074
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// CoinTradeDataSource.swift
3+
// Data
4+
//
5+
// Created by choijunios on 4/21/25.
6+
//
7+
8+
import Combine
9+
10+
import Foundation
11+
import CoreUtil
12+
13+
public protocol CoinTradeDataSource {
14+
func getTradeList(symbolPair: String, tableUpdateInterval: Double?) -> AnyPublisher<HashMap<Int64, BinanceCoinTradeDTO>, Never>
15+
}
16+
17+
public final class BinanceCoinTradeDataSource: CoinTradeDataSource {
18+
// Dependency
19+
@Injected private var webSocketService: WebSocketService
20+
21+
// State
22+
private let tradeList: ThreadSafeHashMap<Int64, BinanceCoinTradeDTO> = .init()
23+
24+
public init() { }
25+
26+
public func getTradeList(symbolPair: String, tableUpdateInterval: Double?) -> AnyPublisher<HashMap<Int64, BinanceCoinTradeDTO>, Never> {
27+
webSocketService
28+
.getMessageStream()
29+
.filter { (dto: BinanceCoinTradeDTO) in
30+
dto.symbol.lowercased() == symbolPair.lowercased()
31+
}
32+
.throttle(for: .init(floatLiteral: tableUpdateInterval ?? 0.0), scheduler: DispatchQueue.global(qos: .default), latest: true)
33+
.unretained(self)
34+
.asyncTransform { source, dto in
35+
await source.tradeList.insert(key: dto.tradeTime, value: dto)
36+
return await source.tradeList.hashMap.copy()
37+
}
38+
}
39+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// BinanceTradeRepository.swift
3+
// Data
4+
//
5+
// Created by choijunios on 4/15/25.
6+
//
7+
8+
import Foundation
9+
import Combine
10+
11+
import DomainInterface
12+
import DataSource
13+
import CoreUtil
14+
15+
public final class BinanceCoinTradeRepository: CoinTradeRepository {
16+
// Dependency
17+
@Injected private var webSocketService: WebSocketService
18+
@Injected private var coinTradeDataSource: CoinTradeDataSource
19+
20+
public init() { }
21+
22+
public func getCoinTradeList(symbolPair: String, tableUpdateInterval: Double?) -> AnyPublisher<HashMap<Date, CoinTradeVO>, Never> {
23+
coinTradeDataSource
24+
.getTradeList(symbolPair: symbolPair, tableUpdateInterval: tableUpdateInterval)
25+
.map { dtoList in
26+
var entityList = HashMap<Date, CoinTradeVO>()
27+
dtoList.values.forEach { dto in
28+
let entity = dto.toEntity()
29+
entityList[entity.tradeTime] = entity
30+
}
31+
return entityList
32+
}
33+
.eraseToAnyPublisher()
34+
}
35+
}

Projects/Data/Repository/Sources/BinanceOrderbookRepository.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ public final class BinanceOrderbookRepository: OrderbookRepository {
1818
@Injected private var httpService: HTTPService
1919

2020
// Store
21-
private let bidOrderbookStore = ThreadSafeOrderbookHashMap()
22-
private let askOrderbookStore = ThreadSafeOrderbookHashMap()
21+
private let bidOrderbookStore = ThreadSafeHashMap<CVNumber, CVNumber>()
22+
private let askOrderbookStore = ThreadSafeHashMap<CVNumber, CVNumber>()
2323

2424
public init() { }
2525
}
@@ -79,7 +79,7 @@ private extension BinanceOrderbookRepository {
7979

8080
enum StoreType { case bid, ask }
8181
func adaptToStore(orderbooks: [[String]], storeType: StoreType) async {
82-
var store: ThreadSafeOrderbookHashMap
82+
var store: ThreadSafeHashMap<CVNumber, CVNumber>
8383
switch storeType {
8484
case .bid:
8585
store = bidOrderbookStore

Projects/Data/Repository/Sources/BinanceTradeRepository.swift

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

Projects/Data/Repository/Sources/Util/ThreadSafeOrderbookHashMap.swift

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

Projects/Domain/Concrete/UseCase/DefaultCoinDetailPageUseCase.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ final public class DefaultCoinDetailPageUseCase: CoinDetailPageUseCase {
1515
// Dependency
1616
@Injected private var orderbookRepository: OrderbookRepository
1717
@Injected private var singleTickerRepository: SingleMarketTickerRepository
18-
@Injected private var coinTradeRepository: TradeRepository
18+
@Injected private var coinTradeRepository: CoinTradeRepository
1919
@Injected private var webSocketHelper: WebSocketManagementHelper
2020

2121
public init() { }
@@ -49,8 +49,18 @@ public extension DefaultCoinDetailPageUseCase {
4949
singleTickerRepository.request24hTickerChange(pairSymbol: symbolPair)
5050
}
5151

52-
func getRecentTrade(symbolPair: String) -> AsyncStream<CoinTradeVO> {
53-
coinTradeRepository.getSingleTrade(symbolPair: symbolPair)
52+
func getRecentTrade(symbolPair: String, maxRowCount: UInt) -> AnyPublisher<[CoinTradeVO], Never> {
53+
coinTradeRepository
54+
.getCoinTradeList(symbolPair: symbolPair, tableUpdateInterval: 0.5)
55+
.map { entity in
56+
// 최신으로 maxRowCount개수 만큼
57+
let slicedList = entity
58+
.keys(order: .DESC, maxCount: maxRowCount)
59+
.compactMap { key in entity[key] }
60+
.prefix(Int(maxRowCount))
61+
return Array(slicedList)
62+
}
63+
.eraseToAnyPublisher()
5464
}
5565

5666
func getOrderbookTable(symbolPair: String, rowCount: UInt) -> AnyPublisher<OrderbookTableVO, Error> {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// CoinTradeRepository.swift
3+
// Domain
4+
//
5+
// Created by choijunios on 4/15/25.
6+
//
7+
8+
import Combine
9+
import Foundation
10+
11+
import CoreUtil
12+
13+
public protocol CoinTradeRepository {
14+
func getCoinTradeList(symbolPair: String, tableUpdateInterval: Double?) -> AnyPublisher<HashMap<Date, CoinTradeVO>, Never>
15+
}

Projects/Domain/Interface/Repository/TradeRepository.swift

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

Projects/Domain/Interface/UseCase/CoinDetailPageUseCase.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ public protocol CoinDetailPageUseCase {
1414
func disconnectToStreams(symbolPair: String)
1515

1616
func getOrderbookTable(symbolPair: String, rowCount: UInt) -> AnyPublisher<OrderbookTableVO, Error>
17+
func getRecentTrade(symbolPair: String, maxRowCount: UInt) -> AnyPublisher<[CoinTradeVO], Never>
1718
func get24hTickerChange(symbolPair: String) -> AsyncStream<Twenty4HourTickerForSymbolVO>
18-
func getRecentTrade(symbolPair: String) -> AsyncStream<CoinTradeVO>
1919
}

0 commit comments

Comments
 (0)