-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathparallel_hasher.ts
90 lines (75 loc) · 2.31 KB
/
parallel_hasher.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
export interface WorkerOptions {
credentials?: 'omit' | 'same-origin' | 'include';
name?: string;
type?: 'classic' | 'module';
}
declare var Worker: {
prototype: Worker;
new (stringUrl: string, options?: WorkerOptions): Worker;
};
interface HashingRequest {
blob: any;
resolve: (...d: any) => void;
reject: (...d: any) => void;
};
export class ParallelHasher {
private _queue: HashingRequest[] = [];
private _hashWorker: any;
private _processing?: HashingRequest;
private _ready: boolean = true;
constructor(workerUri: string, workerOptions?: WorkerOptions) {
const self = this;
if (Worker) {
self._hashWorker = new Worker(workerUri, workerOptions);
self._hashWorker.onmessage = self._recievedMessage.bind(self);
self._hashWorker.onerror = (err: any) => {
self._ready = false;
console.error('Hash worker failure', err);
};
} else {
self._ready = false;
console.error('Web Workers are not supported in this browser');
}
}
/**
* Hash a blob of data in the worker
* @param blob Data to hash
* @returns Promise of the Hashed result
*/
public hash(blob: any) {
const self = this;
let promise;
promise = new Promise((resolve, reject) => {
self._queue.push({
blob,
resolve,
reject,
});
self._processNext();
});
return promise;
}
/** Terminate any existing hash requests */
public terminate() {
this._ready = false;
this._hashWorker.terminate();
}
// Processes the next item in the queue
private _processNext() {
if (this._ready && !this._processing && this._queue.length > 0) {
this._processing = this._queue.pop();
this._hashWorker.postMessage(this._processing!.blob);
}
}
// Hash result is returned from the worker
private _recievedMessage(evt: any) {
const data = evt.data;
if (data.success) {
this._processing?.resolve(data.result);
} else {
this._processing?.reject(data.result);
}
this._processing = undefined;
this._processNext();
}
}