Skip to content

Commit

Permalink
Makes ICacheClient return type promise and changes LRUCache accordingly
Browse files Browse the repository at this point in the history
Signed-off-by: Konstantina Blazhukova <konstantina.blajukova@gmail.com>
  • Loading branch information
konstantinabl committed Apr 25, 2024
1 parent c118b6a commit bad263e
Show file tree
Hide file tree
Showing 10 changed files with 211 additions and 119 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ tsconfig.tsbuildinfo
**/**/coverage/
**/**/.nyc_output/
.DS_Store
*.xml
test-results.*.xml
19 changes: 12 additions & 7 deletions packages/relay/src/lib/clients/cache/ICacheClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,21 @@
*/

export interface ICacheClient {
get(key: string, callingMethod: string, requestIdPrefix?: string): any;
set(key: string, value: any, callingMethod: string, ttl?: number, requestIdPrefix?: string): void;
delete(key: string, callingMethod: string, requestIdPrefix?: string): void;
clear(): void;
multiSet(keyValuePairs: Record<string, any>, callingMethod: string, requestIdPrefix?: string): void;
get(key: string, callingMethod: string, requestIdPrefix?: string | undefined): Promise<any | null>;
set(
key: string,
value: any,
callingMethod: string,
ttl?: number | undefined,
requestIdPrefix?: string | undefined,
): Promise<void>;
multiSet(keyValuePairs: Record<string, any>, callingMethod: string, requestIdPrefix?: string): Promise<void>;
pipelineSet(
keyValuePairs: Record<string, any>,
callingMethod: string,
ttl?: number | undefined,
requestIdPrefix?: string,
): void;
disconnect(): Promise<void> | void;
): Promise<void>;
delete(key: string, callingMethod: string, requestIdPrefix?: string | undefined): Promise<void>;
clear(): Promise<void>;
}
82 changes: 53 additions & 29 deletions packages/relay/src/lib/clients/cache/localLRUCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class LocalLRUCache implements ICacheClient {
this.logger = logger;
this.register = register;

const cacheSizeCollect = () => {
const cacheSizeCollect = (): void => {
this.purgeStale();
this.cacheKeyGauge.set(this.cache.size);
};
Expand All @@ -88,7 +88,7 @@ export class LocalLRUCache implements ICacheClient {
name: metricCounterName,
help: 'Relay LRU cache gauge',
registers: [register],
async collect() {
async collect(): Promise<void> {
cacheSizeCollect();
},
});
Expand All @@ -102,16 +102,18 @@ export class LocalLRUCache implements ICacheClient {
* @param {string} requestIdPrefix - A prefix to include in log messages (optional).
* @returns {*} The cached value if found, otherwise null.
*/
public get(key: string, callingMethod: string, requestIdPrefix?: string): any {
const value = this.cache.get(key);
if (value !== undefined) {
this.logger.trace(
`${requestIdPrefix} returning cached value ${key}:${JSON.stringify(value)} on ${callingMethod} call`,
);
return value;
}

return null;
public async get(key: string, callingMethod: string, requestIdPrefix?: string): Promise<any> {
return new Promise((resolve) => {
const value = this.cache.get(key);
if (value !== undefined) {
this.logger.trace(
`${requestIdPrefix} returning cached value ${key}:${JSON.stringify(value)} on ${callingMethod} call`,
);
resolve(value);
}

resolve(null);
});
}

/**
Expand All @@ -123,10 +125,19 @@ export class LocalLRUCache implements ICacheClient {
* @param {number} ttl - Time to live for the cached value in milliseconds (optional).
* @param {string} requestIdPrefix - A prefix to include in log messages (optional).
*/
public set(key: string, value: any, callingMethod: string, ttl?: number, requestIdPrefix?: string): void {
const resolvedTtl = ttl ?? this.options.ttl;
this.logger.trace(`${requestIdPrefix} caching ${key}:${JSON.stringify(value)} for ${resolvedTtl} ms`);
this.cache.set(key, value, { ttl: resolvedTtl });
public async set(
key: string,
value: any,
callingMethod: string,
ttl?: number,
requestIdPrefix?: string,
): Promise<void> {
return new Promise((resolve) => {
const resolvedTtl = ttl ?? this.options.ttl;
this.logger.trace(`${requestIdPrefix} caching ${key}:${JSON.stringify(value)} for ${resolvedTtl} ms`);
this.cache.set(key, value, { ttl: resolvedTtl });
resolve();
});
}

/**
Expand All @@ -137,11 +148,18 @@ export class LocalLRUCache implements ICacheClient {
* @param requestIdPrefix - Optional request ID prefix for logging.
* @returns {Promise<void>} A Promise that resolves when the values are cached.
*/
public multiSet(keyValuePairs: Record<string, any>, callingMethod: string, requestIdPrefix?: string): void {
public async multiSet(
keyValuePairs: Record<string, any>,
callingMethod: string,
requestIdPrefix?: string,
): Promise<void> {
// Iterate over each entry in the keyValuePairs object
for (const [key, value] of Object.entries(keyValuePairs)) {
this.set(key, value, callingMethod, undefined, requestIdPrefix);
}
return new Promise((resolve) => {
for (const [key, value] of Object.entries(keyValuePairs)) {
this.set(key, value, callingMethod, undefined, requestIdPrefix);
}
resolve();
});
}

/**
Expand All @@ -153,16 +171,19 @@ export class LocalLRUCache implements ICacheClient {
* @param requestIdPrefix - Optional request ID prefix for logging.
* @returns {void} A Promise that resolves when the values are cached.
*/
public pipelineSet(
public async pipelineSet(
keyValuePairs: Record<string, any>,
callingMethod: string,
ttl?: number,
requestIdPrefix?: string,
): void {
): Promise<void> {
// Iterate over each entry in the keyValuePairs object
for (const [key, value] of Object.entries(keyValuePairs)) {
this.set(key, value, callingMethod, ttl, requestIdPrefix);
}
return new Promise((resolve) => {
for (const [key, value] of Object.entries(keyValuePairs)) {
this.set(key, value, callingMethod, ttl, requestIdPrefix);
}
resolve();
});
}

/**
Expand All @@ -172,9 +193,12 @@ export class LocalLRUCache implements ICacheClient {
* @param {string} callingMethod - The name of the method calling the cache.
* @param {string} requestIdPrefix - A prefix to include in log messages (optional).
*/
public delete(key: string, callingMethod: string, requestIdPrefix?: string): void {
this.logger.trace(`${requestIdPrefix} delete cache for ${key}`);
this.cache.delete(key);
public async delete(key: string, callingMethod: string, requestIdPrefix?: string): Promise<void> {
return new Promise((resolve) => {
this.logger.trace(`${requestIdPrefix} delete cache for ${key}`);
this.cache.delete(key);
resolve();
});
}

/**
Expand All @@ -189,7 +213,7 @@ export class LocalLRUCache implements ICacheClient {
* Clears the entire cache, removing all entries.
* Use this method with caution, as it wipes all cached data.
*/
public clear(): void {
public async clear(): Promise<void> {
this.cache.clear();
}

Expand Down
2 changes: 1 addition & 1 deletion packages/relay/src/lib/clients/cache/redisCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export class RedisCache implements ICacheClient {
* @param {string} [requestIdPrefix] - The optional request ID prefix.
* @returns {Promise<any | null>} The cached value or null if not found.
*/
async get(key: string, callingMethod: string, requestIdPrefix?: string | undefined) {
async get(key: string, callingMethod: string, requestIdPrefix?: string | undefined): Promise<any> {
const client = await this.getConnectedClient();
const result = await client.get(key);
if (result) {
Expand Down
41 changes: 26 additions & 15 deletions packages/relay/src/lib/clients/mirrorNodeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ export class MirrorNodeClient {

public async getBlock(hashOrBlockNumber: string | number, requestIdPrefix?: string) {
const cachedLabel = `${constants.CACHE_KEY.GET_BLOCK}.${hashOrBlockNumber}`;
const cachedResponse: any = this.cacheService.get(
const cachedResponse: any = await this.cacheService.getSharedWithFallback(
cachedLabel,
MirrorNodeClient.GET_BLOCK_ENDPOINT,
requestIdPrefix,
Expand All @@ -568,7 +568,7 @@ export class MirrorNodeClient {
requestIdPrefix,
);

this.cacheService.set(cachedLabel, block, MirrorNodeClient.GET_BLOCK_ENDPOINT, undefined, requestIdPrefix);
await this.cacheService.set(cachedLabel, block, MirrorNodeClient.GET_BLOCK_ENDPOINT, undefined, requestIdPrefix);
return block;
}

Expand Down Expand Up @@ -603,13 +603,17 @@ export class MirrorNodeClient {
return `${constants.CACHE_KEY.GET_CONTRACT}.valid.${contractIdOrAddress}`;
}

public getIsValidContractCache(contractIdOrAddress, requestIdPrefix?: string): any {
public async getIsValidContractCache(contractIdOrAddress, requestIdPrefix?: string): Promise<any> {
const cachedLabel = this.getIsValidContractCacheLabel(contractIdOrAddress);
return this.cacheService.get(cachedLabel, MirrorNodeClient.GET_CONTRACT_ENDPOINT, requestIdPrefix);
return await this.cacheService.getSharedWithFallback(
cachedLabel,
MirrorNodeClient.GET_CONTRACT_ENDPOINT,
requestIdPrefix,
);
}

public async isValidContract(contractIdOrAddress: string, requestIdPrefix?: string, retries?: number) {
const cachedResponse: any = this.getIsValidContractCache(contractIdOrAddress, requestIdPrefix);
const cachedResponse: any = await this.getIsValidContractCache(contractIdOrAddress, requestIdPrefix);
if (cachedResponse != undefined) {
return cachedResponse;
}
Expand All @@ -618,7 +622,7 @@ export class MirrorNodeClient {
const valid = contract != null;

const cachedLabel = this.getIsValidContractCacheLabel(contractIdOrAddress);
this.cacheService.set(
await this.cacheService.set(
cachedLabel,
valid,
MirrorNodeClient.GET_CONTRACT_ENDPOINT,
Expand All @@ -630,7 +634,7 @@ export class MirrorNodeClient {

public async getContractId(contractIdOrAddress: string, requestIdPrefix?: string, retries?: number) {
const cachedLabel = `${constants.CACHE_KEY.GET_CONTRACT}.id.${contractIdOrAddress}`;
const cachedResponse: any = this.cacheService.get(
const cachedResponse: any = await this.cacheService.getSharedWithFallback(
cachedLabel,
MirrorNodeClient.GET_CONTRACT_ENDPOINT,
requestIdPrefix,
Expand All @@ -648,7 +652,7 @@ export class MirrorNodeClient {

if (contract != null) {
const id = contract.contract_id;
this.cacheService.set(
await this.cacheService.set(
cachedLabel,
id,
MirrorNodeClient.GET_CONTRACT_ENDPOINT,
Expand All @@ -663,7 +667,10 @@ export class MirrorNodeClient {

public async getContractResult(transactionIdOrHash: string, requestIdPrefix?: string) {
const cacheKey = `${constants.CACHE_KEY.GET_CONTRACT_RESULT}.${transactionIdOrHash}`;
const cachedResponse = this.cacheService.get(cacheKey, MirrorNodeClient.GET_CONTRACT_RESULT_ENDPOINT);
const cachedResponse = await this.cacheService.getSharedWithFallback(
cacheKey,
MirrorNodeClient.GET_CONTRACT_RESULT_ENDPOINT,
);

if (cachedResponse) {
return cachedResponse;
Expand All @@ -681,7 +688,7 @@ export class MirrorNodeClient {
response.block_number != undefined &&
response.result === 'SUCCESS'
) {
this.cacheService.set(
await this.cacheService.set(
cacheKey,
response,
MirrorNodeClient.GET_CONTRACT_RESULT_ENDPOINT,
Expand Down Expand Up @@ -835,7 +842,11 @@ export class MirrorNodeClient {

public async getEarliestBlock(requestId?: string) {
const cachedLabel = `${constants.CACHE_KEY.GET_BLOCK}.earliest`;
const cachedResponse: any = this.cacheService.get(cachedLabel, MirrorNodeClient.GET_BLOCKS_ENDPOINT, requestId);
const cachedResponse: any = await this.cacheService.getSharedWithFallback(
cachedLabel,
MirrorNodeClient.GET_BLOCKS_ENDPOINT,
requestId,
);
if (cachedResponse != undefined) {
return cachedResponse;
}
Expand All @@ -848,7 +859,7 @@ export class MirrorNodeClient {
);
if (blocks && blocks.blocks.length > 0) {
const block = blocks.blocks[0];
this.cacheService.set(
await this.cacheService.set(
cachedLabel,
block,
MirrorNodeClient.GET_BLOCKS_ENDPOINT,
Expand Down Expand Up @@ -1094,7 +1105,7 @@ export class MirrorNodeClient {
retries?: number,
) {
const cachedLabel = `${constants.CACHE_KEY.RESOLVE_ENTITY_TYPE}_${entityIdentifier}`;
const cachedResponse: { type: string; entity: any } | undefined = this.cacheService.get(
const cachedResponse: { type: string; entity: any } | undefined = await this.cacheService.getSharedWithFallback(
cachedLabel,
callerName,
requestIdPrefix,
Expand All @@ -1120,7 +1131,7 @@ export class MirrorNodeClient {
type: constants.TYPE_CONTRACT,
entity: contract,
};
this.cacheService.set(cachedLabel, response, callerName, undefined, requestIdPrefix);
await this.cacheService.set(cachedLabel, response, callerName, undefined, requestIdPrefix);
return response;
}
}
Expand Down Expand Up @@ -1175,7 +1186,7 @@ export class MirrorNodeClient {
type,
entity: data.value,
};
this.cacheService.set(cachedLabel, response, callerName, undefined, requestIdPrefix);
await this.cacheService.set(cachedLabel, response, callerName, undefined, requestIdPrefix);
return response;
}

Expand Down
10 changes: 8 additions & 2 deletions packages/relay/src/lib/clients/sdkClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ export class SDKClient {
}

async getTinyBarGasFee(callerName: string, requestId?: string): Promise<number> {
const cachedResponse: number | undefined = this.cacheService.get(
const cachedResponse: number | undefined = await this.cacheService.getSharedWithFallback(
constants.CACHE_KEY.GET_TINYBAR_GAS_FEE,
callerName,
requestId,
Expand All @@ -218,7 +218,13 @@ export class SDKClient {
const exchangeRates = await this.getExchangeRate(callerName, requestId);
const tinyBars = this.convertGasPriceToTinyBars(schedule.fees[0].servicedata, exchangeRates);

this.cacheService.set(constants.CACHE_KEY.GET_TINYBAR_GAS_FEE, tinyBars, callerName, undefined, requestId);
await this.cacheService.set(
constants.CACHE_KEY.GET_TINYBAR_GAS_FEE,
tinyBars,
callerName,
undefined,
requestId,
);
return tinyBars;
}
}
Expand Down

0 comments on commit bad263e

Please sign in to comment.