Feature/skip caching in portfolio calculator if active filters (#3348)

* Skip caching if active filters

* Update changelog
pull/3353/head^2
Thomas Kaul 10 months ago committed by GitHub
parent 261f5844dd
commit a5833566a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added a form validation against the DTO in the platform management of the admin control panel - Added a form validation against the DTO in the platform management of the admin control panel
- Added a form validation against the DTO in the tag management of the admin control panel - Added a form validation against the DTO in the tag management of the admin control panel
### Changed
- Skipped the caching in the portfolio calculator if there are active filters (experimental)
### Fixed ### Fixed
- Fixed an issue in the calculation of the portfolio summary caused by future liabilities - Fixed an issue in the calculation of the portfolio summary caused by future liabilities

@ -32,6 +32,7 @@ export class PortfolioCalculatorFactory {
calculationType, calculationType,
currency, currency,
dateRange = 'max', dateRange = 'max',
hasFilters,
isExperimentalFeatures = false, isExperimentalFeatures = false,
userId userId
}: { }: {
@ -40,9 +41,12 @@ export class PortfolioCalculatorFactory {
calculationType: PerformanceCalculationType; calculationType: PerformanceCalculationType;
currency: string; currency: string;
dateRange?: DateRange; dateRange?: DateRange;
hasFilters: boolean;
isExperimentalFeatures?: boolean; isExperimentalFeatures?: boolean;
userId: string; userId: string;
}): PortfolioCalculator { }): PortfolioCalculator {
const useCache = !hasFilters && isExperimentalFeatures;
switch (calculationType) { switch (calculationType) {
case PerformanceCalculationType.MWR: case PerformanceCalculationType.MWR:
return new MWRPortfolioCalculator({ return new MWRPortfolioCalculator({
@ -50,7 +54,7 @@ export class PortfolioCalculatorFactory {
activities, activities,
currency, currency,
dateRange, dateRange,
isExperimentalFeatures, useCache,
userId, userId,
configurationService: this.configurationService, configurationService: this.configurationService,
currentRateService: this.currentRateService, currentRateService: this.currentRateService,
@ -64,7 +68,7 @@ export class PortfolioCalculatorFactory {
currency, currency,
currentRateService: this.currentRateService, currentRateService: this.currentRateService,
dateRange, dateRange,
isExperimentalFeatures, useCache,
userId, userId,
configurationService: this.configurationService, configurationService: this.configurationService,
exchangeRateDataService: this.exchangeRateDataService, exchangeRateDataService: this.exchangeRateDataService,

@ -56,14 +56,15 @@ export abstract class PortfolioCalculator {
private currency: string; private currency: string;
private currentRateService: CurrentRateService; private currentRateService: CurrentRateService;
private dataProviderInfos: DataProviderInfo[]; private dataProviderInfos: DataProviderInfo[];
private dateRange: DateRange;
private endDate: Date; private endDate: Date;
private exchangeRateDataService: ExchangeRateDataService; private exchangeRateDataService: ExchangeRateDataService;
private isExperimentalFeatures: boolean;
private redisCacheService: RedisCacheService; private redisCacheService: RedisCacheService;
private snapshot: PortfolioSnapshot; private snapshot: PortfolioSnapshot;
private snapshotPromise: Promise<void>; private snapshotPromise: Promise<void>;
private startDate: Date; private startDate: Date;
private transactionPoints: TransactionPoint[]; private transactionPoints: TransactionPoint[];
private useCache: boolean;
private userId: string; private userId: string;
public constructor({ public constructor({
@ -74,8 +75,8 @@ export abstract class PortfolioCalculator {
currentRateService, currentRateService,
dateRange, dateRange,
exchangeRateDataService, exchangeRateDataService,
isExperimentalFeatures,
redisCacheService, redisCacheService,
useCache,
userId userId
}: { }: {
accountBalanceItems: HistoricalDataItem[]; accountBalanceItems: HistoricalDataItem[];
@ -85,16 +86,16 @@ export abstract class PortfolioCalculator {
currentRateService: CurrentRateService; currentRateService: CurrentRateService;
dateRange: DateRange; dateRange: DateRange;
exchangeRateDataService: ExchangeRateDataService; exchangeRateDataService: ExchangeRateDataService;
isExperimentalFeatures: boolean;
redisCacheService: RedisCacheService; redisCacheService: RedisCacheService;
useCache: boolean;
userId: string; userId: string;
}) { }) {
this.accountBalanceItems = accountBalanceItems; this.accountBalanceItems = accountBalanceItems;
this.configurationService = configurationService; this.configurationService = configurationService;
this.currency = currency; this.currency = currency;
this.currentRateService = currentRateService; this.currentRateService = currentRateService;
this.dateRange = dateRange;
this.exchangeRateDataService = exchangeRateDataService; this.exchangeRateDataService = exchangeRateDataService;
this.isExperimentalFeatures = isExperimentalFeatures;
this.activities = activities this.activities = activities
.map( .map(
@ -129,6 +130,7 @@ export abstract class PortfolioCalculator {
}); });
this.redisCacheService = redisCacheService; this.redisCacheService = redisCacheService;
this.useCache = useCache;
this.userId = userId; this.userId = userId;
const { endDate, startDate } = getInterval(dateRange); const { endDate, startDate } = getInterval(dateRange);
@ -1047,11 +1049,13 @@ export abstract class PortfolioCalculator {
} }
private async initialize() { private async initialize() {
if (this.isExperimentalFeatures) { if (this.useCache) {
const startTimeTotal = performance.now(); const startTimeTotal = performance.now();
const cachedSnapshot = await this.redisCacheService.get( const cachedSnapshot = await this.redisCacheService.get(
this.redisCacheService.getPortfolioSnapshotKey(this.userId) this.redisCacheService.getPortfolioSnapshotKey({
userId: this.userId
})
); );
if (cachedSnapshot) { if (cachedSnapshot) {
@ -1074,7 +1078,9 @@ export abstract class PortfolioCalculator {
); );
this.redisCacheService.set( this.redisCacheService.set(
this.redisCacheService.getPortfolioSnapshotKey(this.userId), this.redisCacheService.getPortfolioSnapshotKey({
userId: this.userId
}),
JSON.stringify(this.snapshot), JSON.stringify(this.snapshot),
this.configurationService.get('CACHE_QUOTES_TTL') this.configurationService.get('CACHE_QUOTES_TTL')
); );

@ -123,6 +123,7 @@ describe('PortfolioCalculator', () => {
activities, activities,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: 'CHF', currency: 'CHF',
hasFilters: false,
userId: userDummyData.id userId: userDummyData.id
}); });

@ -108,6 +108,7 @@ describe('PortfolioCalculator', () => {
activities, activities,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: 'CHF', currency: 'CHF',
hasFilters: false,
userId: userDummyData.id userId: userDummyData.id
}); });

@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => {
activities, activities,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: 'CHF', currency: 'CHF',
hasFilters: false,
userId: userDummyData.id userId: userDummyData.id
}); });

@ -121,6 +121,7 @@ describe('PortfolioCalculator', () => {
activities, activities,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: 'CHF', currency: 'CHF',
hasFilters: false,
userId: userDummyData.id userId: userDummyData.id
}); });

@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => {
activities, activities,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: 'USD', currency: 'USD',
hasFilters: false,
userId: userDummyData.id userId: userDummyData.id
}); });

@ -106,6 +106,7 @@ describe('PortfolioCalculator', () => {
activities, activities,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: 'CHF', currency: 'CHF',
hasFilters: false,
userId: userDummyData.id userId: userDummyData.id
}); });

@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => {
activities, activities,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: 'USD', currency: 'USD',
hasFilters: false,
userId: userDummyData.id userId: userDummyData.id
}); });

@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => {
activities, activities,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: 'USD', currency: 'USD',
hasFilters: false,
userId: userDummyData.id userId: userDummyData.id
}); });

@ -121,6 +121,7 @@ describe('PortfolioCalculator', () => {
activities, activities,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: 'USD', currency: 'USD',
hasFilters: false,
userId: userDummyData.id userId: userDummyData.id
}); });

@ -71,6 +71,7 @@ describe('PortfolioCalculator', () => {
activities: [], activities: [],
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: 'CHF', currency: 'CHF',
hasFilters: false,
userId: userDummyData.id userId: userDummyData.id
}); });

@ -108,6 +108,7 @@ describe('PortfolioCalculator', () => {
activities, activities,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: 'CHF', currency: 'CHF',
hasFilters: false,
userId: userDummyData.id userId: userDummyData.id
}); });

@ -108,6 +108,7 @@ describe('PortfolioCalculator', () => {
activities, activities,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: 'CHF', currency: 'CHF',
hasFilters: false,
userId: userDummyData.id userId: userDummyData.id
}); });

@ -277,9 +277,11 @@ export class PortfolioService {
const portfolioCalculator = this.calculatorFactory.createCalculator({ const portfolioCalculator = this.calculatorFactory.createCalculator({
activities, activities,
dateRange,
userId, userId,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: this.request.user.Settings.settings.baseCurrency, currency: this.request.user.Settings.settings.baseCurrency,
hasFilters: filters?.length > 0,
isExperimentalFeatures: isExperimentalFeatures:
this.request.user.Settings.settings.isExperimentalFeatures this.request.user.Settings.settings.isExperimentalFeatures
}); });
@ -358,6 +360,7 @@ export class PortfolioService {
userId, userId,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: userCurrency, currency: userCurrency,
hasFilters: filters?.length > 0,
isExperimentalFeatures: isExperimentalFeatures:
this.request.user?.Settings.settings.isExperimentalFeatures this.request.user?.Settings.settings.isExperimentalFeatures
}); });
@ -660,6 +663,7 @@ export class PortfolioService {
}), }),
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: userCurrency, currency: userCurrency,
hasFilters: true,
isExperimentalFeatures: isExperimentalFeatures:
this.request.user.Settings.settings.isExperimentalFeatures this.request.user.Settings.settings.isExperimentalFeatures
}); });
@ -931,6 +935,7 @@ export class PortfolioService {
userId, userId,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: this.request.user.Settings.settings.baseCurrency, currency: this.request.user.Settings.settings.baseCurrency,
hasFilters: filters?.length > 0,
isExperimentalFeatures: isExperimentalFeatures:
this.request.user.Settings.settings.isExperimentalFeatures this.request.user.Settings.settings.isExperimentalFeatures
}); });
@ -1085,7 +1090,7 @@ export class PortfolioService {
) )
); );
const { endDate, startDate } = getInterval(dateRange); const { endDate } = getInterval(dateRange);
const { activities } = await this.orderService.getOrders({ const { activities } = await this.orderService.getOrders({
endDate, endDate,
@ -1123,6 +1128,7 @@ export class PortfolioService {
userId, userId,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: userCurrency, currency: userCurrency,
hasFilters: filters?.length > 0,
isExperimentalFeatures: isExperimentalFeatures:
this.request.user.Settings.settings.isExperimentalFeatures this.request.user.Settings.settings.isExperimentalFeatures
}); });
@ -1220,6 +1226,7 @@ export class PortfolioService {
userId, userId,
calculationType: PerformanceCalculationType.TWR, calculationType: PerformanceCalculationType.TWR,
currency: this.request.user.Settings.settings.baseCurrency, currency: this.request.user.Settings.settings.baseCurrency,
hasFilters: false,
isExperimentalFeatures: isExperimentalFeatures:
this.request.user.Settings.settings.isExperimentalFeatures this.request.user.Settings.settings.isExperimentalFeatures
}); });

@ -24,7 +24,7 @@ export class RedisCacheService {
return this.cache.get(key); return this.cache.get(key);
} }
public getPortfolioSnapshotKey(userId: string) { public getPortfolioSnapshotKey({ userId }: { userId: string }) {
return `portfolio-snapshot-${userId}`; return `portfolio-snapshot-${userId}`;
} }

@ -17,7 +17,9 @@ export class PortfolioChangedListener {
); );
this.redisCacheService.remove( this.redisCacheService.remove(
this.redisCacheService.getPortfolioSnapshotKey(event.getUserId()) this.redisCacheService.getPortfolioSnapshotKey({
userId: event.getUserId()
})
); );
} }
} }

Loading…
Cancel
Save