|
27 | 27 | import java.time.LocalDate; |
28 | 28 | import java.time.LocalDateTime; |
29 | 29 | import java.time.ZoneId; |
| 30 | +import java.util.ArrayList; |
30 | 31 | import java.util.Calendar; |
31 | 32 | import java.util.Collection; |
32 | 33 | import java.util.Date; |
| 34 | +import java.util.GregorianCalendar; |
33 | 35 | import java.util.LinkedList; |
34 | 36 | import java.util.List; |
35 | 37 | import java.util.Map; |
36 | 38 | import java.util.Optional; |
37 | 39 | import java.util.concurrent.CompletableFuture; |
38 | 40 | import java.util.concurrent.ConcurrentHashMap; |
| 41 | +import java.util.concurrent.ForkJoinPool; |
39 | 42 | import java.util.concurrent.TimeUnit; |
40 | 43 | import java.util.concurrent.atomic.AtomicInteger; |
41 | 44 | import java.util.function.BiConsumer; |
@@ -81,7 +84,7 @@ private record GetSetMethodFunctions(Function<QuoteCb, BigDecimal> getter, BiCon |
81 | 84 | private boolean cpuConstraint; |
82 | 85 | private final List<String> nonValueFieldNames = List.of("_id", "createdAt", "class"); |
83 | 86 | private final List<PropertyDescriptor> propertyDescriptors; |
84 | | - private final Scheduler mongoScheduler = Schedulers.newBoundedElastic(5, 10, "mongoImport", 10); |
| 87 | + private final Scheduler mongoScheduler = Schedulers.newBoundedElastic(10, 10, "mongoImport", 10); |
85 | 88 | @Value("${single.instance.deployment:false}") |
86 | 89 | private boolean singleInstanceDeployment; |
87 | 90 |
|
@@ -195,73 +198,106 @@ private String createHourDayAvg() { |
195 | 198 | private void createCbHourlyAvg() { |
196 | 199 | LOG.info("createCbHourlyAvg()"); |
197 | 200 | LocalDateTime startAll = LocalDateTime.now(); |
198 | | - MyTimeFrame timeFrame = this.serviceUtils.createTimeFrame(CB_HOUR_COL, QuoteCb.class, true); |
199 | | - SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy"); |
| 201 | + MyTimeFrame timeFrame = this.serviceUtils.createTimeFrame(CB_HOUR_COL, QuoteCb.class, true); |
200 | 202 | Calendar now = Calendar.getInstance(); |
201 | 203 | now.setTime(Date.from(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant())); |
202 | | - while (timeFrame.end().before(now)) { |
203 | | - Date start = new Date(); |
204 | | - final var nonZeroProperties = new AtomicInteger(0); |
205 | | - Query query = new Query(); |
206 | | - query.addCriteria( |
207 | | - Criteria.where(DtoUtils.CREATEDAT).gt(timeFrame.begin().getTime()).lt(timeFrame.end().getTime())); |
208 | | - // Coinbase |
209 | | - Mono<Collection<QuoteCb>> collectCb = this.myMongoRepository.find(query, QuoteCb.class) |
210 | | - .timeout(Duration.ofSeconds(5L)).doOnError(ex -> LOG.warn("Coinbase prepare hour data failed", ex)) |
211 | | - .onErrorResume(ex -> Mono.empty()).subscribeOn(this.mongoScheduler).collectList() |
212 | | - .map(quotes -> makeCbQuoteHour(quotes, timeFrame.begin(), timeFrame.end())); |
213 | | - collectCb.filter(Predicate.not(Collection::isEmpty)) |
214 | | - .map(myColl -> countRelevantProperties(nonZeroProperties, myColl)) |
215 | | - .flatMap(myColl -> this.myMongoRepository.insertAll(Mono.just(myColl), CB_HOUR_COL) |
216 | | - .timeout(Duration.ofSeconds(5L)) |
217 | | - .doOnError(ex -> LOG.warn("Coinbase prepare hour data failed", ex)) |
218 | | - .onErrorResume(ex -> Mono.empty()).subscribeOn(this.mongoScheduler).collectList()) |
219 | | - .subscribeOn(this.mongoScheduler).block(); |
220 | | - |
221 | | - timeFrame.begin().add(Calendar.DAY_OF_YEAR, 1); |
222 | | - timeFrame.end().add(Calendar.DAY_OF_YEAR, 1); |
223 | | - LOG.info("Prepared Coinbase Hour Data for: " + sdf.format(timeFrame.begin().getTime()) + " Time: " |
224 | | - + (new Date().getTime() - start.getTime()) + "ms" + " 0 < properties: " |
225 | | - + nonZeroProperties.get()); |
226 | | - } |
| 204 | + final var timeFrames = this.createTimeFrames(timeFrame, now); |
| 205 | + if (this.cpuConstraint) { |
| 206 | + timeFrames.stream().forEachOrdered(timeFrame1 -> processHourTimeFrame(timeFrame1)); |
| 207 | + } else { |
| 208 | + try (ForkJoinPool customThreadPool = new ForkJoinPool(2)) { |
| 209 | + customThreadPool.submit(() -> timeFrames.parallelStream().forEachOrdered(timeFrame1 -> processHourTimeFrame(timeFrame1))); |
| 210 | + customThreadPool.shutdown(); |
| 211 | + } |
| 212 | + } |
227 | 213 | LOG.info(this.serviceUtils.createAvgLogStatement(startAll, "Prepared Coinbase Hourly Data Time:")); |
228 | 214 | } |
229 | 215 |
|
| 216 | + private void processHourTimeFrame(MyTimeFrame timeFrame1) { |
| 217 | + Date start = new Date(); |
| 218 | + SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy"); |
| 219 | + final var nonZeroProperties = new AtomicInteger(0); |
| 220 | + Query query = new Query(); |
| 221 | + query.addCriteria( |
| 222 | + Criteria.where(DtoUtils.CREATEDAT).gt(timeFrame1.begin().getTime()).lt(timeFrame1.end().getTime())); |
| 223 | + // Coinbase |
| 224 | + Mono<Collection<QuoteCb>> collectCb = this.myMongoRepository.find(query, QuoteCb.class) |
| 225 | + .timeout(Duration.ofSeconds(5L)).doOnError(ex -> LOG.warn("Coinbase prepare hour data failed", ex)) |
| 226 | + .onErrorResume(ex -> Mono.empty()).subscribeOn(this.mongoScheduler).collectList() |
| 227 | + .map(quotes -> makeCbQuoteHour(quotes, timeFrame1.begin(), timeFrame1.end())); |
| 228 | + collectCb.filter(Predicate.not(Collection::isEmpty)) |
| 229 | + .map(myColl -> countRelevantProperties(nonZeroProperties, myColl)) |
| 230 | + .flatMap(myColl -> this.myMongoRepository.insertAll(Mono.just(myColl), CB_HOUR_COL) |
| 231 | + .timeout(Duration.ofSeconds(5L)) |
| 232 | + .doOnError(ex -> LOG.warn("Coinbase prepare hour data failed", ex)) |
| 233 | + .onErrorResume(ex -> Mono.empty()).subscribeOn(this.mongoScheduler).collectList()) |
| 234 | + .subscribeOn(this.mongoScheduler).block(); |
| 235 | + LOG.info("Prepared Coinbase Hour Data for: " + sdf.format(timeFrame1.begin().getTime()) + " Time: " |
| 236 | + + (new Date().getTime() - start.getTime()) + "ms" + " 0 < properties: " + nonZeroProperties.get()); |
| 237 | + } |
| 238 | + |
230 | 239 | private void createCbDailyAvg() { |
231 | 240 | LOG.info("createCbDailyAvg()"); |
232 | 241 | LocalDateTime startAll = LocalDateTime.now(); |
233 | | - MyTimeFrame timeFrame = this.serviceUtils.createTimeFrame(CB_DAY_COL, QuoteCb.class, false); |
234 | | - SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy"); |
235 | | - Calendar now = Calendar.getInstance(); |
| 242 | + final MyTimeFrame timeFrame = this.serviceUtils.createTimeFrame(CB_DAY_COL, QuoteCb.class, false); |
| 243 | + final Calendar now = Calendar.getInstance(); |
236 | 244 | now.setTime(Date.from(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant())); |
237 | | - while (timeFrame.end().before(now)) { |
238 | | - Date start = new Date(); |
239 | | - final var nonZeroProperties = new AtomicInteger(0); |
240 | | - Query query = new Query(); |
241 | | - query.addCriteria( |
242 | | - Criteria.where(DtoUtils.CREATEDAT).gt(timeFrame.begin().getTime()).lt(timeFrame.end().getTime())); |
243 | | - // Coinbase |
244 | | - Mono<Collection<QuoteCb>> collectCb = this.myMongoRepository.find(query, QuoteCb.class) |
245 | | - .timeout(Duration.ofSeconds(5L)).doOnError(ex -> LOG.warn("Coinbase prepare day data failed", ex)) |
246 | | - .onErrorResume(ex -> Mono.empty()).subscribeOn(this.mongoScheduler).collectList() |
247 | | - .map(quotes -> makeCbQuoteDay(quotes, timeFrame.begin(), timeFrame.end())); |
248 | | - collectCb.filter(Predicate.not(Collection::isEmpty)) |
249 | | - .map(myColl -> countRelevantProperties(nonZeroProperties, myColl)) |
250 | | - .flatMap(myColl -> this.myMongoRepository.insertAll(Mono.just(myColl), CB_DAY_COL) |
251 | | - .timeout(Duration.ofSeconds(5L)) |
252 | | - .doOnError(ex -> LOG.warn("Coinbase prepare day data failed", ex)) |
253 | | - .onErrorResume(ex -> Mono.empty()).subscribeOn(this.mongoScheduler).collectList()) |
254 | | - .subscribeOn(this.mongoScheduler).block(); |
255 | | - |
256 | | - timeFrame.begin().add(Calendar.DAY_OF_YEAR, 1); |
257 | | - timeFrame.end().add(Calendar.DAY_OF_YEAR, 1); |
258 | | - LOG.info("Prepared Coinbase Day Data for: " + sdf.format(timeFrame.begin().getTime()) + " Time: " |
259 | | - + (new Date().getTime() - start.getTime()) + "ms" + " 0 < properties: " |
260 | | - + nonZeroProperties.get()); |
261 | | - } |
| 245 | + final var timeFrames = this.createTimeFrames(timeFrame, now); |
| 246 | + if (this.cpuConstraint) { |
| 247 | + timeFrames.stream().forEachOrdered(timeFrame1 -> processDayTimeFrame(timeFrame1)); |
| 248 | + } else { |
| 249 | + try (ForkJoinPool customThreadPool = new ForkJoinPool(2)) { |
| 250 | + customThreadPool.submit(() -> timeFrames.parallelStream().forEachOrdered(timeFrame1 -> processDayTimeFrame(timeFrame1))); |
| 251 | + customThreadPool.shutdown(); |
| 252 | + } |
| 253 | + } |
262 | 254 | LOG.info(this.serviceUtils.createAvgLogStatement(startAll, "Prepared Coinbase Daily Data Time:")); |
263 | 255 | } |
264 | 256 |
|
| 257 | + private List<MyTimeFrame> createTimeFrames(final MyTimeFrame timeFrame, final Calendar now) { |
| 258 | + final var timeFrames = new ArrayList<MyTimeFrame>(); |
| 259 | + var begin = timeFrame.begin(); |
| 260 | + var end = timeFrame.end(); |
| 261 | + while (end.before(now)) { |
| 262 | + var myTimeFrame = new MyTimeFrame(begin, end); |
| 263 | + timeFrames.add(myTimeFrame); |
| 264 | + begin = nextDay(begin); |
| 265 | + end = nextDay(end); |
| 266 | + } |
| 267 | + return timeFrames; |
| 268 | + } |
| 269 | + |
| 270 | + private Calendar nextDay(Calendar begin) { |
| 271 | + var begin1 = GregorianCalendar.getInstance(); |
| 272 | + begin1.setTime(begin.getTime()); |
| 273 | + begin1.add(Calendar.DAY_OF_YEAR, 1); |
| 274 | + begin = begin1; |
| 275 | + return begin; |
| 276 | + } |
| 277 | + |
| 278 | + private void processDayTimeFrame(MyTimeFrame timeFrame1) { |
| 279 | + Date start = new Date(); |
| 280 | + final SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy"); |
| 281 | + final var nonZeroProperties = new AtomicInteger(0); |
| 282 | + Query query = new Query(); |
| 283 | + query.addCriteria( |
| 284 | + Criteria.where(DtoUtils.CREATEDAT).gt(timeFrame1.begin().getTime()).lt(timeFrame1.end().getTime())); |
| 285 | + // Coinbase |
| 286 | + Mono<Collection<QuoteCb>> collectCb = this.myMongoRepository.find(query, QuoteCb.class) |
| 287 | + .timeout(Duration.ofSeconds(5L)).doOnError(ex -> LOG.warn("Coinbase prepare day data failed", ex)) |
| 288 | + .onErrorResume(ex -> Mono.empty()).subscribeOn(this.mongoScheduler).collectList() |
| 289 | + .map(quotes -> makeCbQuoteDay(quotes, timeFrame1.begin(), timeFrame1.end())); |
| 290 | + collectCb.filter(Predicate.not(Collection::isEmpty)) |
| 291 | + .map(myColl -> countRelevantProperties(nonZeroProperties, myColl)) |
| 292 | + .flatMap(myColl -> this.myMongoRepository.insertAll(Mono.just(myColl), CB_DAY_COL) |
| 293 | + .timeout(Duration.ofSeconds(5L)) |
| 294 | + .doOnError(ex -> LOG.warn("Coinbase prepare day data failed", ex)) |
| 295 | + .onErrorResume(ex -> Mono.empty()).subscribeOn(this.mongoScheduler).collectList()) |
| 296 | + .subscribeOn(this.mongoScheduler).block(); |
| 297 | + LOG.info("Prepared Coinbase Day Data for: " + sdf.format(timeFrame1.begin().getTime()) + " Time: " |
| 298 | + + (new Date().getTime() - start.getTime()) + "ms" + " 0 < properties: " + nonZeroProperties.get()); |
| 299 | + } |
| 300 | + |
265 | 301 | private Collection<QuoteCb> countRelevantProperties(final AtomicInteger nonZeroProperties, |
266 | 302 | Collection<QuoteCb> myColl) { |
267 | 303 | var relevantProperties = myColl.stream().flatMap(myQuote -> Stream.of(this.propertiesNonZero(myQuote))) |
|
0 commit comments