Skip to content
This repository has been archived by the owner on Jan 24, 2024. It is now read-only.

fix(cache): Cache improvements #260

Merged
merged 4 commits into from
Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
# e.g: ENABLED_APPS="tokemak,synthetix"

ENABLED_APPS=
ENABLED_HELPERS=
API_RESOLVED_POSITIONS=
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind adding some docs related to this parameter and why we would use it?

8 changes: 3 additions & 5 deletions src/apps/curve/ethereum/curve.pool.token-fetcher.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Inject } from '@nestjs/common';
import { uniqBy } from 'lodash';
import { compact, uniqBy } from 'lodash';

import { Register } from '~app-toolkit/decorators';
import { SYNTHETIX_DEFINITION } from '~apps/synthetix';
Expand Down Expand Up @@ -104,9 +104,7 @@ export class EthereumCurvePoolTokenFetcher implements PositionFetcher<AppTokenPo
}),
]);

return uniqBy(
[v1Pools, v1MetaPools, v2Pools, v1FactoryPools, v2FactoryPools, cryptoFactoryPools].flat(),
v => v.address,
);
const tokens = compact([v1Pools, v1MetaPools, v2Pools, v1FactoryPools, v2FactoryPools, cryptoFactoryPools].flat());
return uniqBy(tokens, v => v.address);
}
}
5 changes: 2 additions & 3 deletions src/cache/cache-on-interval.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export class CacheOnIntervalService implements OnModuleInit, OnModuleDestroy {
const methodRef = instance[methodName];
const cacheKey: CacheOnIntervalOptions['key'] = this.reflector.get(CACHE_ON_INTERVAL_KEY, methodRef);
const cacheTimeout: CacheOnIntervalOptions['timeout'] = this.reflector.get(CACHE_ON_INTERVAL_TIMEOUT, methodRef);
const ttl = Math.floor(cacheTimeout / 1000);

// Don't register cache on interval when missing parameters
if (!cacheKey || !cacheTimeout) return;
Expand Down Expand Up @@ -88,7 +87,7 @@ export class CacheOnIntervalService implements OnModuleInit, OnModuleDestroy {
}
liveData
.then(d => {
return cacheManager.set(cacheKey, d, { ttl });
return cacheManager.set(cacheKey, d);
})
.then(() => {
logger.log(`Cache ready for for ${instance.constructor.name}#${methodName}`);
Expand All @@ -101,7 +100,7 @@ export class CacheOnIntervalService implements OnModuleInit, OnModuleDestroy {
const interval = setInterval(async () => {
try {
const liveData = await methodRef.apply(instance);
await cacheManager.set(cacheKey, liveData, { ttl });
await cacheManager.set(cacheKey, liveData);
} catch (e) {
logger.error(`@CacheOnInterval error for ${instance.constructor.name}#${methodName}`, e);
}
Expand Down
9 changes: 1 addition & 8 deletions src/cache/cache.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ export class CacheService implements OnModuleInit {
return typeof cacheKey === 'function' ? cacheKey(...args) : cacheKey;
}

private extractTtl(cacheTtl: CacheOptions['ttl'], args: any[]) {
if (isNil(cacheTtl)) return 0;
return typeof cacheTtl === 'function' ? cacheTtl(...args) : cacheTtl;
}

private registerCache(instance: any, methodName: string) {
const logger = this.logger;
const methodRef = instance[methodName];
Expand All @@ -52,7 +47,6 @@ export class CacheService implements OnModuleInit {
// Service references
const cacheManager = this.cacheManager;
const extractKey = this.extractKey;
const extractTtl = this.extractTtl;

// Augment the method to be cached with caching mechanism
instance[methodName] = async function (...args: any[]) {
Expand All @@ -63,9 +57,8 @@ export class CacheService implements OnModuleInit {
return cachedValue;
} else {
try {
const cacheTtl = extractTtl(rawCacheTtl, args);
const liveData = await methodRef.apply(this, args);
await cacheManager.set(cacheKey, liveData, { ttl: cacheTtl });
await cacheManager.set(cacheKey, liveData);
return liveData;
} catch (e) {
logger.error(`@Cache error for ${instance.constructor.name}#${methodName}`, e);
Expand Down
2 changes: 2 additions & 0 deletions src/main.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { compact } from 'lodash';

import { AppToolkitModule } from '~app-toolkit/app-toolkit.module';
import { AppsModule } from '~apps/apps.module';
Expand All @@ -22,6 +23,7 @@ import { StatsModule } from '~stats/stats.module';
url: process.env.ZAPPER_API_URL ?? 'https://api.zapper.fi',
key: process.env.ZAPPER_API_KEY ?? '96e0cc51-a62e-42ca-acee-910ea7d2a241',
},
apiResolvedPositions: compact((process.env.API_RESOLVED_POSITIONS ?? '').split(',')),
}),
],
}),
Expand Down
14 changes: 12 additions & 2 deletions src/position/position-source/position-source.registry.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Inject, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { partition, groupBy, map, compact } from 'lodash';

import { ContractType } from '~position/contract.interface';
Expand All @@ -10,15 +11,24 @@ import { PositionSource } from './position-source.interface';

@Injectable()
export class RegistryPositionSource implements PositionSource {
constructor(@Inject(PositionFetcherRegistry) private readonly positionFetcherRegistry: PositionFetcherRegistry) {}
constructor(
@Inject(ConfigService) private readonly configService: ConfigService,
@Inject(PositionFetcherRegistry) private readonly positionFetcherRegistry: PositionFetcherRegistry,
) {}

private getApiResolvedPositions(): string[] {
return this.configService.get('apiResolvedPositions') ?? [];
}

getSupported(definitions: AppGroupsDefinition[], contractType: ContractType) {
const defs = definitions.flatMap(({ appId, groupIds, network }) =>
groupIds.map(groupId => {
const def = { appId, groupId, network, contractType };
try {
// Will throw if not found
this.positionFetcherRegistry.get({ type: contractType, appId, groupId, network });
return { ...def, supported: true };
const isLocallyProvided = !this.getApiResolvedPositions().includes(appId);
return { ...def, supported: isLocallyProvided };
} catch (e) {
return { ...def, supported: false };
}
Expand Down