Page MenuHomePhabricator

D6992.id23695.diff
No OneTemporary

D6992.id23695.diff

diff --git a/web/database/utils/WorkerConnectionProxy.js b/web/database/utils/WorkerConnectionProxy.js
new file mode 100644
--- /dev/null
+++ b/web/database/utils/WorkerConnectionProxy.js
@@ -0,0 +1,75 @@
+// @flow
+
+import type {
+ WorkerRequestProxyMessage,
+ WorkerResponseMessage,
+ WorkerRequestMessage,
+ WorkerResponseProxyMessage,
+} from '../../types/worker-types.js';
+
+type PromiseCallbacks = {
+ +resolve: (result: ?WorkerResponseMessage) => void,
+ +reject: (error: Error) => void,
+};
+
+// It's important to have only ONE instance of this object to make it work
+class WorkerConnectionProxy {
+ workerPort: MessagePort;
+ messageId: number;
+ promiseCallbacks: { [index: number]: PromiseCallbacks };
+ // This function will be called when worker will send
+ // a message with an error but without any app's request
+ onError: (error: Error) => void;
+
+ constructor(port: MessagePort, onError: (error: Error) => void) {
+ this.workerPort = port;
+ this.onError = onError;
+ this.workerPort.onmessage = this.handleMessage;
+ this.messageId = 1;
+ this.promiseCallbacks = {};
+ }
+
+ handleMessage: (msg: MessageEvent) => void = (msg: MessageEvent) => {
+ const data: WorkerResponseProxyMessage = (msg.data: any);
+ const { id, error, message } = data;
+
+ if (!id || !this.promiseCallbacks[id]) {
+ if (error) {
+ this.onError(error);
+ } else if (message) {
+ this.onError(new Error(`Unknown error for message: ${message.type}`));
+ } else {
+ this.onError(new Error('Unknown error'));
+ }
+ return;
+ }
+
+ const callbacks = this.promiseCallbacks[id];
+ if (error) {
+ callbacks.reject(error);
+ } else {
+ callbacks.resolve(message);
+ }
+
+ delete this.promiseCallbacks[id];
+ };
+
+ scheduleOnWorker(
+ payload: WorkerRequestMessage,
+ ): Promise<?WorkerResponseMessage> {
+ const msgId = this.messageId++;
+ const msg: WorkerRequestProxyMessage = {
+ id: msgId,
+ message: payload,
+ };
+ return new Promise((resolve, reject) => {
+ this.promiseCallbacks[msgId] = {
+ resolve,
+ reject,
+ };
+ this.workerPort.postMessage(msg);
+ });
+ }
+}
+
+export default WorkerConnectionProxy;
diff --git a/web/database/worker/db-worker.js b/web/database/worker/db-worker.js
--- a/web/database/worker/db-worker.js
+++ b/web/database/worker/db-worker.js
@@ -8,6 +8,7 @@
type WorkerResponseMessage,
workerRequestMessageTypes,
workerResponseMessageTypes,
+ type WorkerRequestProxyMessage,
} from '../../types/worker-types.js';
const localforageConfig: PartialConfig = {
@@ -40,13 +41,24 @@
console.log('Web database worker alive!');
port.onmessage = async function (messageEvent: MessageEvent) {
- const message: WorkerRequestMessage = (messageEvent.data: any);
+ const data: WorkerRequestProxyMessage = (messageEvent.data: any);
+ const { id, message } = data;
+
+ if (!id) {
+ port.postMessage({
+ error: new Error('Request without identifier'),
+ });
+ }
try {
const result = processAppRequest(message);
- port.postMessage(result);
+ port.postMessage({
+ id,
+ message: result,
+ });
} catch (e) {
port.postMessage({
+ id,
error: e,
});
}
diff --git a/web/types/worker-types.js b/web/types/worker-types.js
--- a/web/types/worker-types.js
+++ b/web/types/worker-types.js
@@ -12,22 +12,28 @@
export type WorkerRequestMessage = PingWorkerRequestMessage;
+export type WorkerRequestProxyMessage = {
+ +id: number,
+ +message: WorkerRequestMessage,
+};
+
// The types of messages sent from worker to app
export const workerResponseMessageTypes = Object.freeze({
PONG: 0,
});
-export type ErrorWorkerResponseMessage = {
- +error: Error,
-};
export type PongWorkerResponseMessage = {
+type: 0,
+text: string,
};
-export type WorkerResponseMessage =
- | PongWorkerResponseMessage
- | ErrorWorkerResponseMessage;
+export type WorkerResponseMessage = PongWorkerResponseMessage;
+
+export type WorkerResponseProxyMessage = {
+ +id?: number,
+ +message?: WorkerResponseMessage,
+ +error?: Error,
+};
// SharedWorker types
export type SharedWorkerMessageEvent = MessageEvent & {

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 1, 4:04 AM (19 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2603340
Default Alt Text
D6992.id23695.diff (4 KB)

Event Timeline