@clickup/ent-framework
Version:
A PostgreSQL graph-database-alike library with microsharding and row-level security
87 lines • 3.85 kB
TypeScript
import type { MaybeCallable } from "./misc";
export interface CachedRefreshedValueOptions<TValue> {
/** Delay between calling resolver. */
delayMs: MaybeCallable<number>;
/** Log a timeout Error if a resolver takes more than X ms to complete. */
warningTimeoutMs: MaybeCallable<number>;
/** The handler deps.handler() is called every deps.delayMs (typically,
* frequently); if it returns a different value than previously (using "==="
* comparison), then waiting for the next delayMs is interrupted prematurely,
* and the value gets refreshed. This allows to frequently recheck for some
* configuration changes and act accordingly. */
deps: {
delayMs: MaybeCallable<number>;
handler: () => unknown | Promise<unknown>;
};
/** The name of the resolverFn function. Used in error messages. */
resolverName?: string;
/** A resolver function that returns the value. It's assumed that this
* function would eventually either resolve or throw. */
resolverFn: () => Promise<TValue>;
/** An error handler. */
onError: (error: unknown, elapsed: number) => void;
/** A custom delay implementation. */
delay: (ms: number) => Promise<void>;
}
/**
* Utility class to provide a caching layer for a resolverFn with the following
* assumptions:
* - The value is stable and does not change frequently.
* - The resolverFn can throw or take more time to resolve (e.g. outage). In
* that case, the cached value is still valid, unless a fresh value is
* requested with refreshAndWait().
*
* The implementation is as follows:
* - Once value is accessed, we schedule an endless loop of calling resolver to
* get latest value.
* - The result is cached, so next calls will return it immediately in most of
* the cases.
* - Once every delayMs we call resolverFn to get latest value. All calls during
* this time will get previous value (if available).
*/
export declare class CachedRefreshedValue<TValue> {
readonly options: CachedRefreshedValueOptions<TValue>;
/** Latest value pulled from the cache. */
private latestValue;
/** Deferred promise containing the next value. Fulfilled promises are
* replaced right away. */
private nextValue;
/** Each time before resolverFn() is called, this value is increased. */
private resolverFnCallCount;
/** Whether the instance is destroyed or not. Used to prevent memory leaks in
* unit tests. */
private destroyedError;
/** A callback to skip the current delay() call. */
private skipDelay;
/**
* Initializes the instance.
*/
constructor(options: CachedRefreshedValueOptions<TValue>);
/**
* Returns latest cached value. If the value has been calculated at least
* once, then it is guaranteed that in the worst case, it will be returned
* immediately. I.e. this method never blocks once at least one calculation
* succeeded in the past. (But it may block during the very first call.)
*/
cached(): Promise<TValue>;
/**
* Triggers the call to resolverFn() ASAP (i.e. sooner than the next interval
* specified in delayMs) and waits for the next complete SUCCESSFUL cache
* refresh. If the method is called during the period of time when the
* resolverFn() is already running, then it waits till it finishes, and then
* waits again till the next resolverFn() call finishes, so we're sure that
* it's a strong barrier.
*/
refreshAndWait(): Promise<void>;
/**
* Destroys the instance. Stops refreshing the value and any call to it will
* result in an error.
*/
destroy(): void;
private refreshLoop;
/**
* A never throwing version of options.onError().
*/
private onError;
}
//# sourceMappingURL=CachedRefreshedValue.d.ts.map