|
@@ -1,8 +1,9 @@
|
|
|
package com.danielbohry.stocks.service;
|
|
package com.danielbohry.stocks.service;
|
|
|
|
|
|
|
|
-import com.danielbohry.stocks.client.InferenceClient;
|
|
|
|
|
|
|
+import com.danielbohry.stocks.client.FinanceClient;
|
|
|
import com.danielbohry.stocks.domain.Quote;
|
|
import com.danielbohry.stocks.domain.Quote;
|
|
|
import com.danielbohry.stocks.domain.StockInfo;
|
|
import com.danielbohry.stocks.domain.StockInfo;
|
|
|
|
|
+import com.danielbohry.stocks.exception.NotFoundException;
|
|
|
import com.danielbohry.stocks.repository.StockInfoRepository;
|
|
import com.danielbohry.stocks.repository.StockInfoRepository;
|
|
|
import com.danielbohry.stocks.repository.StockRepository;
|
|
import com.danielbohry.stocks.repository.StockRepository;
|
|
|
import lombok.AllArgsConstructor;
|
|
import lombok.AllArgsConstructor;
|
|
@@ -11,7 +12,6 @@ import org.springframework.scheduling.annotation.Async;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
-import java.util.Optional;
|
|
|
|
|
import java.util.Set;
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
import static java.util.stream.Collectors.toSet;
|
|
import static java.util.stream.Collectors.toSet;
|
|
@@ -21,10 +21,15 @@ import static java.util.stream.Collectors.toSet;
|
|
|
@AllArgsConstructor
|
|
@AllArgsConstructor
|
|
|
public class StockInfoService {
|
|
public class StockInfoService {
|
|
|
|
|
|
|
|
- private InferenceClient client;
|
|
|
|
|
|
|
+ private FinanceClient client;
|
|
|
private StockRepository stockRepository;
|
|
private StockRepository stockRepository;
|
|
|
private StockInfoRepository infoRepository;
|
|
private StockInfoRepository infoRepository;
|
|
|
|
|
|
|
|
|
|
+ public StockInfo get(String code) {
|
|
|
|
|
+ return infoRepository.findById(code)
|
|
|
|
|
+ .orElseThrow(() -> new NotFoundException("No stock found with id: " + code));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@Async("stockInfoExecutor")
|
|
@Async("stockInfoExecutor")
|
|
|
public void generate() {
|
|
public void generate() {
|
|
|
List<Quote> stocks = stockRepository.findAll();
|
|
List<Quote> stocks = stockRepository.findAll();
|
|
@@ -37,18 +42,18 @@ public class StockInfoService {
|
|
|
.map(StockInfo::getCode)
|
|
.map(StockInfo::getCode)
|
|
|
.collect(toSet());
|
|
.collect(toSet());
|
|
|
|
|
|
|
|
- stocks.stream()
|
|
|
|
|
|
|
+ List<Quote> request = stocks.stream()
|
|
|
.filter(stock -> !existingIds.contains(stock.getCode()))
|
|
.filter(stock -> !existingIds.contains(stock.getCode()))
|
|
|
.filter(stock -> !stock.getCode().contains(":"))
|
|
.filter(stock -> !stock.getCode().contains(":"))
|
|
|
- .forEach(stock -> {
|
|
|
|
|
- try {
|
|
|
|
|
- log.info("Generating stock info for {}", stock.getCode());
|
|
|
|
|
- Optional.ofNullable(client.infer(stock))
|
|
|
|
|
- .ifPresent(info -> infoRepository.save(info));
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- log.error("Failed to infer stock info for code: {}", stock.getCode(), e);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ .toList();
|
|
|
|
|
+
|
|
|
|
|
+ int batchSize = 20;
|
|
|
|
|
+ for (int i = 0; i < request.size(); i += batchSize) {
|
|
|
|
|
+ int end = Math.min(i + batchSize, request.size());
|
|
|
|
|
+ List<Quote> batch = request.subList(i, end);
|
|
|
|
|
+ List<StockInfo> stockInfos = client.fetchStockInfo(batch);
|
|
|
|
|
+ infoRepository.saveAll(stockInfos);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|