Initialize RpcCore with configured ttl (#6160)

* Initialize RpcCore with configured ttl

* lint
This commit is contained in:
Valentin Fernandez
2025-05-29 13:38:11 -03:00
committed by GitHub
parent 2f44cdb4bc
commit 448c1ce217
6 changed files with 41 additions and 10 deletions
+1
View File
@@ -154,6 +154,7 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
isPedantic: this._options.isPedantic,
provider,
rpcCacheCapacity: this._options.rpcCacheCapacity,
ttl: this._options.provider?.ttl,
userRpc: this._options.rpc
}) as (RpcCore & RpcInterface);
this._isConnected = new BehaviorSubject(this._rpcCore.provider.isConnected);
+3 -2
View File
@@ -37,6 +37,7 @@ interface Options {
* Custom size of the rpc LRUCache capacity. Defaults to `RPC_CORE_DEFAULT_CAPACITY` (1024 * 10 * 10)
*/
rpcCacheCapacity?: number;
ttl?: number | null;
userRpc?: Record<string, Record<string, DefinitionRpc | DefinitionRpcSub>>;
}
@@ -117,7 +118,7 @@ export class RpcCore {
* @param {ProviderInterface} options.provider An API provider using any of the supported providers (HTTP, SC or WebSocket)
* @param {number} [options.rpcCacheCapacity] Custom size of the rpc LRUCache capacity. Defaults to `RPC_CORE_DEFAULT_CAPACITY` (1024 * 10 * 10)
*/
constructor (instanceId: string, registry: Registry, { isPedantic = true, provider, rpcCacheCapacity, userRpc = {} }: Options) {
constructor (instanceId: string, registry: Registry, { isPedantic = true, provider, rpcCacheCapacity, ttl, userRpc = {} }: Options) {
if (!provider || !isFunction(provider.send)) {
throw new Error('Expected Provider to API create');
}
@@ -131,7 +132,7 @@ export class RpcCore {
// these are the base keys (i.e. part of jsonrpc)
this.sections.push(...sectionNames);
this.#storageCache = new LRUCache(rpcCacheCapacity || RPC_CORE_DEFAULT_CAPACITY);
this.#storageCache = new LRUCache(rpcCacheCapacity || RPC_CORE_DEFAULT_CAPACITY, ttl);
// decorate all interfaces, defined and user on this instance
this.addUserInterfaces(userRpc);
}
+14 -2
View File
@@ -42,6 +42,7 @@ export class HttpProvider implements ProviderInterface {
readonly #endpoint: string;
readonly #headers: Record<string, string>;
readonly #stats: ProviderStats;
readonly #ttl: number | null | undefined;
/**
* @param {string} endpoint The endpoint url starting with http://
@@ -49,7 +50,7 @@ export class HttpProvider implements ProviderInterface {
* @param {number} [cacheCapacity] Custom size of the HttpProvider LRUCache. Defaults to `DEFAULT_CAPACITY` (1024)
* @param {number} [cacheTtl] Custom TTL of the HttpProvider LRUCache. Determines how long an object can live in the cache. Defaults to `DEFAULT_TTL` (30000)
*/
constructor (endpoint: string = defaults.HTTP_URL, headers: Record<string, string> = {}, cacheCapacity?: number, cacheTtl?: number) {
constructor (endpoint: string = defaults.HTTP_URL, headers: Record<string, string> = {}, cacheCapacity?: number, cacheTtl?: number | null) {
if (!/^(https|http):\/\//.test(endpoint)) {
throw new Error(`Endpoint should start with 'http://' or 'https://', received '${endpoint}'`);
}
@@ -57,9 +58,13 @@ export class HttpProvider implements ProviderInterface {
this.#coder = new RpcCoder();
this.#endpoint = endpoint;
this.#headers = headers;
this.#callCache = new LRUCache(cacheCapacity === 0 ? 0 : cacheCapacity || DEFAULT_CAPACITY, cacheTtl || DEFAULT_TTL);
this.#cacheCapacity = cacheCapacity === 0 ? 0 : cacheCapacity || DEFAULT_CAPACITY;
const ttl = cacheTtl === undefined ? DEFAULT_TTL : cacheTtl;
this.#callCache = new LRUCache(cacheCapacity === 0 ? 0 : cacheCapacity || DEFAULT_CAPACITY, ttl);
this.#ttl = cacheTtl;
this.#stats = {
active: { requests: 0, subscriptions: 0 },
total: { bytesRecv: 0, bytesSent: 0, cached: 0, errors: 0, requests: 0, subscriptions: 0, timeout: 0 }
@@ -101,6 +106,13 @@ export class HttpProvider implements ProviderInterface {
return this.#stats;
}
/**
* @description Returns the connection stats
*/
public get ttl (): number | null | undefined {
return this.#ttl;
}
/**
* @summary `true` when this provider supports clone()
*/
+8 -4
View File
@@ -8,6 +8,10 @@
export const DEFAULT_CAPACITY = 1024;
export const DEFAULT_TTL = 30000;
// If the user decides to disable the TTL we set the value
// to a very high number (A year = 365 * 24 * 60 * 60 * 1000).
const DISABLED_TTL = 31_536_000_000;
class LRUNode {
readonly key: string;
#expires: number;
@@ -47,13 +51,13 @@ export class LRUCache {
readonly #ttl: number;
constructor (capacity = DEFAULT_CAPACITY, ttl = DEFAULT_TTL) {
constructor (capacity = DEFAULT_CAPACITY, ttl: number | null = DEFAULT_TTL) {
this.capacity = capacity;
this.#ttl = ttl;
this.#head = this.#tail = new LRUNode('<empty>', ttl);
ttl ? this.#ttl = ttl : this.#ttl = DISABLED_TTL;
this.#head = this.#tail = new LRUNode('<empty>', this.#ttl);
}
get ttl (): number {
get ttl (): number | null {
return this.#ttl;
}
+2
View File
@@ -57,6 +57,8 @@ export interface ProviderInterface {
readonly isConnected: boolean;
/** (optional) stats for the provider with connections/bytes */
readonly stats?: ProviderStats;
/** (optional) stats for the provider with connections/bytes */
readonly ttl?: number | null;
clone (): ProviderInterface;
connect (): Promise<void>;
+13 -2
View File
@@ -94,6 +94,7 @@ export class WsProvider implements ProviderInterface {
readonly #stats: ProviderStats;
readonly #waitingForId: Record<string, JsonRpcResponse<unknown>> = {};
readonly #cacheCapacity: number;
readonly #ttl: number | null | undefined;
#autoConnectMs: number;
#endpointIndex: number;
@@ -112,7 +113,7 @@ export class WsProvider implements ProviderInterface {
* @param {number} [cacheCapacity] Custom size of the WsProvider LRUCache. Defaults to `DEFAULT_CAPACITY` (1024)
* @param {number} [cacheTtl] Custom TTL of the WsProvider LRUCache. Determines how long an object can live in the cache. Defaults to DEFAULT_TTL` (30000)
*/
constructor (endpoint: string | string[] = defaults.WS_URL, autoConnectMs: number | false = RETRY_DELAY, headers: Record<string, string> = {}, timeout?: number, cacheCapacity?: number, cacheTtl?: number) {
constructor (endpoint: string | string[] = defaults.WS_URL, autoConnectMs: number | false = RETRY_DELAY, headers: Record<string, string> = {}, timeout?: number, cacheCapacity?: number, cacheTtl?: number | null) {
const endpoints = Array.isArray(endpoint)
? endpoint
: [endpoint];
@@ -126,7 +127,10 @@ export class WsProvider implements ProviderInterface {
throw new Error(`Endpoint should start with 'ws://', received '${endpoint}'`);
}
});
this.#callCache = new LRUCache(cacheCapacity || DEFAULT_CAPACITY, cacheTtl || DEFAULT_TTL);
const ttl = cacheTtl === undefined ? DEFAULT_TTL : cacheTtl;
this.#callCache = new LRUCache(cacheCapacity === 0 ? 0 : cacheCapacity || DEFAULT_CAPACITY, ttl);
this.#ttl = cacheTtl;
this.#cacheCapacity = cacheCapacity || DEFAULT_CAPACITY;
this.#eventemitter = new EventEmitter();
this.#autoConnectMs = autoConnectMs || 0;
@@ -288,6 +292,13 @@ export class WsProvider implements ProviderInterface {
};
}
/**
* @description Returns the connection stats
*/
public get ttl (): number | null | undefined {
return this.#ttl;
}
public get endpointStats (): EndpointStats {
return this.#endpointStats;
}