From c994f7f9c426876adf38343b1fda0cfa3d7c57be Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 27 Apr 2024 13:17:50 +0200 Subject: [PATCH] Handle isExperimentalFeatures flag and add logging --- .../portfolio-calculator.factory.ts | 4 ++ .../calculator/portfolio-calculator.ts | 56 ++++++++++++++----- .../src/app/portfolio/portfolio.service.ts | 24 ++++++-- .../data-provider/data-provider.service.ts | 13 +++-- 4 files changed, 73 insertions(+), 24 deletions(-) diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts index 881f0dcdd..4937f1008 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts @@ -32,6 +32,7 @@ export class PortfolioCalculatorFactory { calculationType, currency, dateRange = 'max', + isExperimentalFeatures = false, userId }: { accountBalanceItems?: HistoricalDataItem[]; @@ -39,6 +40,7 @@ export class PortfolioCalculatorFactory { calculationType: PerformanceCalculationType; currency: string; dateRange?: DateRange; + isExperimentalFeatures?: boolean; userId: string; }): PortfolioCalculator { switch (calculationType) { @@ -48,6 +50,7 @@ export class PortfolioCalculatorFactory { activities, currency, dateRange, + isExperimentalFeatures, userId, configurationService: this.configurationService, currentRateService: this.currentRateService, @@ -61,6 +64,7 @@ export class PortfolioCalculatorFactory { currency, currentRateService: this.currentRateService, dateRange, + isExperimentalFeatures, userId, configurationService: this.configurationService, exchangeRateDataService: this.exchangeRateDataService, diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 82ebd6611..ba9833948 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -29,6 +29,7 @@ import { import { PortfolioSnapshot, TimelinePosition } from '@ghostfolio/common/models'; import { DateRange, GroupBy } from '@ghostfolio/common/types'; +import { Logger } from '@nestjs/common'; import { Big } from 'big.js'; import { plainToClass } from 'class-transformer'; import { @@ -57,6 +58,7 @@ export abstract class PortfolioCalculator { private dataProviderInfos: DataProviderInfo[]; private endDate: Date; private exchangeRateDataService: ExchangeRateDataService; + private isExperimentalFeatures: boolean; private redisCacheService: RedisCacheService; private snapshot: PortfolioSnapshot; private snapshotPromise: Promise; @@ -72,6 +74,7 @@ export abstract class PortfolioCalculator { currentRateService, dateRange, exchangeRateDataService, + isExperimentalFeatures, redisCacheService, userId }: { @@ -82,6 +85,7 @@ export abstract class PortfolioCalculator { currentRateService: CurrentRateService; dateRange: DateRange; exchangeRateDataService: ExchangeRateDataService; + isExperimentalFeatures: boolean; redisCacheService: RedisCacheService; userId: string; }) { @@ -90,6 +94,7 @@ export abstract class PortfolioCalculator { this.currency = currency; this.currentRateService = currentRateService; this.exchangeRateDataService = exchangeRateDataService; + this.isExperimentalFeatures = isExperimentalFeatures; this.orders = activities .map( @@ -1036,23 +1041,48 @@ export abstract class PortfolioCalculator { } private async initialize() { - const cachedSnapshot = await this.redisCacheService.get( - this.redisCacheService.getPortfolioSnapshotKey(this.userId) - ); + if (this.isExperimentalFeatures) { + const startTimeTotal = performance.now(); - if (cachedSnapshot) { - this.snapshot = plainToClass( - PortfolioSnapshot, - JSON.parse(cachedSnapshot) + const cachedSnapshot = await this.redisCacheService.get( + this.redisCacheService.getPortfolioSnapshotKey(this.userId) ); + + if (cachedSnapshot) { + this.snapshot = plainToClass( + PortfolioSnapshot, + JSON.parse(cachedSnapshot) + ); + + Logger.debug( + `Fetched portfolio snapshot from cache in ${( + (performance.now() - startTimeTotal) / + 1000 + ).toFixed(3)} seconds`, + 'PortfolioCalculator' + ); + } else { + this.snapshot = await this.computeSnapshot( + this.startDate, + this.endDate + ); + + this.redisCacheService.set( + this.redisCacheService.getPortfolioSnapshotKey(this.userId), + JSON.stringify(this.snapshot), + this.configurationService.get('CACHE_QUOTES_TTL') + ); + + Logger.debug( + `Computed portfolio snapshot in ${( + (performance.now() - startTimeTotal) / + 1000 + ).toFixed(3)} seconds`, + 'PortfolioCalculator' + ); + } } else { this.snapshot = await this.computeSnapshot(this.startDate, this.endDate); - - this.redisCacheService.set( - this.redisCacheService.getPortfolioSnapshotKey(this.userId), - JSON.stringify(this.snapshot), - this.configurationService.get('CACHE_QUOTES_TTL') - ); } } } diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 0bb513ec2..a7e80ce1c 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -279,7 +279,9 @@ export class PortfolioService { activities, userId, calculationType: PerformanceCalculationType.TWR, - currency: this.request.user.Settings.settings.baseCurrency + currency: this.request.user.Settings.settings.baseCurrency, + isExperimentalFeatures: + this.request.user.Settings.settings.isExperimentalFeatures }); const items = await portfolioCalculator.getChart({ @@ -355,7 +357,9 @@ export class PortfolioService { dateRange, userId, calculationType: PerformanceCalculationType.TWR, - currency: userCurrency + currency: userCurrency, + isExperimentalFeatures: + this.request.user.Settings.settings.isExperimentalFeatures }); const { currentValueInBaseCurrency, hasErrors, positions } = @@ -655,7 +659,9 @@ export class PortfolioService { return ['BUY', 'DIVIDEND', 'ITEM', 'SELL'].includes(order.type); }), calculationType: PerformanceCalculationType.TWR, - currency: userCurrency + currency: userCurrency, + isExperimentalFeatures: + this.request.user.Settings.settings.isExperimentalFeatures }); const portfolioStart = portfolioCalculator.getStartDate(); @@ -924,7 +930,9 @@ export class PortfolioService { dateRange, userId, calculationType: PerformanceCalculationType.TWR, - currency: this.request.user.Settings.settings.baseCurrency + currency: this.request.user.Settings.settings.baseCurrency, + isExperimentalFeatures: + this.request.user.Settings.settings.isExperimentalFeatures }); let { hasErrors, positions } = await portfolioCalculator.getSnapshot(); @@ -1114,7 +1122,9 @@ export class PortfolioService { dateRange, userId, calculationType: PerformanceCalculationType.TWR, - currency: userCurrency + currency: userCurrency, + isExperimentalFeatures: + this.request.user.Settings.settings.isExperimentalFeatures }); const { @@ -1209,7 +1219,9 @@ export class PortfolioService { activities, userId, calculationType: PerformanceCalculationType.TWR, - currency: this.request.user.Settings.settings.baseCurrency + currency: this.request.user.Settings.settings.baseCurrency, + isExperimentalFeatures: + this.request.user.Settings.settings.isExperimentalFeatures }); let { totalFeesWithCurrencyEffect, positions, totalInvestment } = diff --git a/apps/api/src/services/data-provider/data-provider.service.ts b/apps/api/src/services/data-provider/data-provider.service.ts index 675c13377..26fc171b5 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -399,7 +399,8 @@ export class DataProviderService { numberOfItemsInCache > 1 ? 's' : '' } from cache in ${((performance.now() - startTimeTotal) / 1000).toFixed( 3 - )} seconds` + )} seconds`, + 'DataProviderService' ); } @@ -505,7 +506,8 @@ export class DataProviderService { } from ${dataSource} in ${( (performance.now() - startTimeDataSource) / 1000 - ).toFixed(3)} seconds` + ).toFixed(3)} seconds`, + 'DataProviderService' ); try { @@ -535,14 +537,15 @@ export class DataProviderService { await Promise.all(promises); - Logger.debug('------------------------------------------------'); + Logger.debug('--------------------------------------------------------'); Logger.debug( `Fetched ${items.length} quote${items.length > 1 ? 's' : ''} in ${( (performance.now() - startTimeTotal) / 1000 - ).toFixed(3)} seconds` + ).toFixed(3)} seconds`, + 'DataProviderService' ); - Logger.debug('================================================'); + Logger.debug('========================================================'); return response; }