@redpc/core
Version:
Remoted Procedure Call (RedPC) - A javascript RPC library written with TypeScript
94 lines (65 loc) • 2.17 kB
text/typescript
import { RpcTimeout } from "errors";
import { IMessage } from "./IMessage";
export type AsyncMessageTrackerTimeoutCallback = (entry: AsyncMessageTrackerEntry) => void | Promise<void>;
export interface AsyncMessageTrackerConfig {
forcedTimeoutInMilliseconds?: number;
}
export interface AsyncMessageTrackerEntry {
id: string;
message: IMessage;
timeoutInMilliseconds?: number;
}
export interface AsyncMessageTrackerWaitResult {
id: string;
message: IMessage;
}
export class AsyncMessageTracker {
private entries: Record<string, {
entry: AsyncMessageTrackerEntry,
resolve: (value: AsyncMessageTrackerWaitResult) => void,
reject: (reason: any) => void
}>;
constructor(
private config?: AsyncMessageTrackerConfig
)
{
this.entries = {};
}
public waitForResponseOrTimeout(entry: AsyncMessageTrackerEntry): Promise<AsyncMessageTrackerWaitResult> {
return new Promise<AsyncMessageTrackerWaitResult>((resolve, reject) => {
const timeout = entry.timeoutInMilliseconds ?? this.config?.forcedTimeoutInMilliseconds;
this.entries[entry.id] = {
entry,
resolve,
reject
};
if (timeout) {
setTimeout(() => {
delete this.entries[entry.id];
reject(new RpcTimeout('Request was timed out.'));
}, timeout);
}
});
}
public respond(id: string, message: IMessage): boolean {
const entry = this.entries[id];
if (!!entry) {
entry.resolve({
id,
message
});
delete this.entries[id];
return true;
}
return false;
}
public reject(id: string, reason: any): boolean {
const entry = this.entries[id];
if (!!entry) {
entry.reject(reason);
delete this.entries[id];
return true;
}
return false;
}
}