fchat-rising/learn/store/worker/client.ts

114 lines
2.6 KiB
TypeScript
Raw Normal View History

2021-01-24 00:52:27 +00:00
import _ from 'lodash';
import log from 'electron-log'; //tslint:disable-line:match-default-export-name
import { IndexedRequest, IndexedResponse, ProfileStoreCommand } from './types';
export interface WaiterDef {
id: string;
resolve(result?: any): void;
reject(result?: any): void;
2021-02-03 01:55:10 +00:00
initiated: number;
request: IndexedRequest;
2021-01-24 00:52:27 +00:00
}
export class WorkerClient {
2021-02-03 01:55:10 +00:00
// @ts-ignore
private _isVue = true;
2021-01-24 00:52:27 +00:00
private readonly worker: Worker;
private idCounter = 0;
private waiters: WaiterDef[] = [];
constructor(jsFile: string) {
this.worker = new Worker(jsFile);
this.worker.onmessage = this.generateMessageProcessor();
}
private generateId(): string {
this.idCounter++;
return `wc-${this.idCounter}`;
}
2021-02-03 01:55:10 +00:00
private when(id: string, resolve: (result?: any) => void, reject: (reason?: any) => void, request: IndexedRequest): void {
this.waiters.push({ id, resolve, reject, request, initiated: Date.now() });
2021-01-24 00:52:27 +00:00
}
private generateMessageProcessor(): ((e: Event) => void) {
return (e: Event) => {
const res = (e as any).data as IndexedResponse;
2021-02-03 01:55:10 +00:00
// log.silly('store.worker.client.msg', { res });
2021-01-24 00:52:27 +00:00
if (!res) {
log.error('store.worker.client.msg.invalid', { res });
return;
}
const waiter = _.find(this.waiters, (w) => (w.id === res.id));
if (!waiter) {
log.error('store.worker.client.msg.unknown', { res });
return;
}
if (res.state === 'ok') {
2021-09-10 23:02:50 +00:00
const t = Date.now() - waiter.initiated;
if (t > 200) {
log.info('store.worker.client.msg.slow', { t: t / 1000, req: waiter.request, res });
}
2021-01-24 00:52:27 +00:00
waiter.resolve(res.result);
} else {
2021-02-03 01:55:10 +00:00
log.error('store.worker.client.msg.err', { t: (Date.now() - waiter.initiated) / 1000, msg: res.msg, req: waiter.request });
2021-01-24 00:52:27 +00:00
waiter.reject(new Error(res.msg));
}
this.clearWaiter(waiter.id);
};
}
private clearWaiter(id: string): void {
this.waiters = _.filter(this.waiters, (w) => (w.id !== id));
2021-02-03 01:55:10 +00:00
// log.silly('store.worker.waiter.clear', this.waiters.length);
2021-01-24 00:52:27 +00:00
}
async request(cmd: ProfileStoreCommand, params: Record<string, any> = {}): Promise<any> {
const id = this.generateId();
const request: IndexedRequest = {
cmd,
id,
params
};
return new Promise(
(resolve, reject) => {
try {
this.when(
id,
resolve,
2021-02-03 01:55:10 +00:00
reject,
request
2021-01-24 00:52:27 +00:00
);
this.worker.postMessage(request);
} catch (err) {
reject(err);
this.clearWaiter(id);
}
}
);
}
}