Merge pull request #11107 from Snuffleupagus/MessageHandler-postMessage
Various `MessageHandler` improvements when using Streams
This commit is contained in:
commit
d1e6d427cd
@ -1248,17 +1248,17 @@ class PDFPageProxy {
|
|||||||
*/
|
*/
|
||||||
_tryCleanup(resetStats = false) {
|
_tryCleanup(resetStats = false) {
|
||||||
if (!this.pendingCleanup ||
|
if (!this.pendingCleanup ||
|
||||||
Object.keys(this.intentStates).some(function(intent) {
|
Object.keys(this.intentStates).some((intent) => {
|
||||||
const intentState = this.intentStates[intent];
|
const intentState = this.intentStates[intent];
|
||||||
return (intentState.renderTasks.length !== 0 ||
|
return (intentState.renderTasks.length !== 0 ||
|
||||||
!intentState.operatorList.lastChunk);
|
!intentState.operatorList.lastChunk);
|
||||||
}, this)) {
|
})) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(this.intentStates).forEach(function(intent) {
|
Object.keys(this.intentStates).forEach((intent) => {
|
||||||
delete this.intentStates[intent];
|
delete this.intentStates[intent];
|
||||||
}, this);
|
});
|
||||||
this.objs.clear();
|
this.objs.clear();
|
||||||
this.annotationsPromise = null;
|
this.annotationsPromise = null;
|
||||||
if (resetStats && this._stats instanceof StatTimer) {
|
if (resetStats && this._stats instanceof StatTimer) {
|
||||||
@ -1443,18 +1443,18 @@ class LoopbackPort {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this._defer) {
|
if (!this._defer) {
|
||||||
this._listeners.forEach(function(listener) {
|
this._listeners.forEach((listener) => {
|
||||||
listener.call(this, { data: obj, });
|
listener.call(this, { data: obj, });
|
||||||
}, this);
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cloned = new WeakMap();
|
const cloned = new WeakMap();
|
||||||
const e = { data: cloneValue(obj), };
|
const e = { data: cloneValue(obj), };
|
||||||
this._deferred.then(() => {
|
this._deferred.then(() => {
|
||||||
this._listeners.forEach(function(listener) {
|
this._listeners.forEach((listener) => {
|
||||||
listener.call(this, e);
|
listener.call(this, e);
|
||||||
}, this);
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,18 @@ import {
|
|||||||
ReadableStream, UnexpectedResponseException, UnknownErrorException
|
ReadableStream, UnexpectedResponseException, UnknownErrorException
|
||||||
} from './util';
|
} from './util';
|
||||||
|
|
||||||
|
const StreamKind = {
|
||||||
|
UNKNOWN: 0,
|
||||||
|
CANCEL: 1,
|
||||||
|
CANCEL_COMPLETE: 2,
|
||||||
|
CLOSE: 3,
|
||||||
|
ENQUEUE: 4,
|
||||||
|
ERROR: 5,
|
||||||
|
PULL: 6,
|
||||||
|
PULL_COMPLETE: 7,
|
||||||
|
START_COMPLETE: 8,
|
||||||
|
};
|
||||||
|
|
||||||
async function resolveCall(fn, args, thisArg = null) {
|
async function resolveCall(fn, args, thisArg = null) {
|
||||||
if (!fn) {
|
if (!fn) {
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -36,20 +48,11 @@ function wrapReason(reason) {
|
|||||||
return new MissingPDFException(reason.message);
|
return new MissingPDFException(reason.message);
|
||||||
case 'UnexpectedResponseException':
|
case 'UnexpectedResponseException':
|
||||||
return new UnexpectedResponseException(reason.message, reason.status);
|
return new UnexpectedResponseException(reason.message, reason.status);
|
||||||
default:
|
case 'UnknownErrorException':
|
||||||
return new UnknownErrorException(reason.message, reason.details);
|
return new UnknownErrorException(reason.message, reason.details);
|
||||||
}
|
default:
|
||||||
}
|
|
||||||
|
|
||||||
function makeReasonSerializable(reason) {
|
|
||||||
if (!(reason instanceof Error) ||
|
|
||||||
reason instanceof AbortException ||
|
|
||||||
reason instanceof MissingPDFException ||
|
|
||||||
reason instanceof UnexpectedResponseException ||
|
|
||||||
reason instanceof UnknownErrorException) {
|
|
||||||
return reason;
|
|
||||||
}
|
|
||||||
return new UnknownErrorException(reason.message, reason.toString());
|
return new UnknownErrorException(reason.message, reason.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveOrReject(capability, data) {
|
function resolveOrReject(capability, data) {
|
||||||
@ -113,7 +116,7 @@ function MessageHandler(sourceName, targetName, comObj) {
|
|||||||
targetName,
|
targetName,
|
||||||
isReply: true,
|
isReply: true,
|
||||||
callbackId: data.callbackId,
|
callbackId: data.callbackId,
|
||||||
error: makeReasonSerializable(reason),
|
error: wrapReason(reason),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (data.streamId) {
|
} else if (data.streamId) {
|
||||||
@ -143,13 +146,12 @@ MessageHandler.prototype = {
|
|||||||
* @param {Array} [transfers] - Optional list of transfers/ArrayBuffers
|
* @param {Array} [transfers] - Optional list of transfers/ArrayBuffers
|
||||||
*/
|
*/
|
||||||
send(actionName, data, transfers) {
|
send(actionName, data, transfers) {
|
||||||
var message = {
|
this.postMessage({
|
||||||
sourceName: this.sourceName,
|
sourceName: this.sourceName,
|
||||||
targetName: this.targetName,
|
targetName: this.targetName,
|
||||||
action: actionName,
|
action: actionName,
|
||||||
data,
|
data,
|
||||||
};
|
}, transfers);
|
||||||
this.postMessage(message, transfers);
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Sends a message to the comObj to invoke the action with the supplied data.
|
* Sends a message to the comObj to invoke the action with the supplied data.
|
||||||
@ -161,19 +163,18 @@ MessageHandler.prototype = {
|
|||||||
*/
|
*/
|
||||||
sendWithPromise(actionName, data, transfers) {
|
sendWithPromise(actionName, data, transfers) {
|
||||||
var callbackId = this.callbackId++;
|
var callbackId = this.callbackId++;
|
||||||
var message = {
|
|
||||||
sourceName: this.sourceName,
|
|
||||||
targetName: this.targetName,
|
|
||||||
action: actionName,
|
|
||||||
data,
|
|
||||||
callbackId,
|
|
||||||
};
|
|
||||||
var capability = createPromiseCapability();
|
var capability = createPromiseCapability();
|
||||||
this.callbacksCapabilities[callbackId] = capability;
|
this.callbacksCapabilities[callbackId] = capability;
|
||||||
try {
|
try {
|
||||||
this.postMessage(message, transfers);
|
this.postMessage({
|
||||||
} catch (e) {
|
sourceName: this.sourceName,
|
||||||
capability.reject(e);
|
targetName: this.targetName,
|
||||||
|
action: actionName,
|
||||||
|
callbackId,
|
||||||
|
data,
|
||||||
|
}, transfers);
|
||||||
|
} catch (ex) {
|
||||||
|
capability.reject(ex);
|
||||||
}
|
}
|
||||||
return capability.promise;
|
return capability.promise;
|
||||||
},
|
},
|
||||||
@ -191,6 +192,7 @@ MessageHandler.prototype = {
|
|||||||
let streamId = this.streamId++;
|
let streamId = this.streamId++;
|
||||||
let sourceName = this.sourceName;
|
let sourceName = this.sourceName;
|
||||||
let targetName = this.targetName;
|
let targetName = this.targetName;
|
||||||
|
const comObj = this.comObj;
|
||||||
|
|
||||||
return new ReadableStream({
|
return new ReadableStream({
|
||||||
start: (controller) => {
|
start: (controller) => {
|
||||||
@ -207,7 +209,7 @@ MessageHandler.prototype = {
|
|||||||
streamId,
|
streamId,
|
||||||
data,
|
data,
|
||||||
desiredSize: controller.desiredSize,
|
desiredSize: controller.desiredSize,
|
||||||
});
|
}, transfers);
|
||||||
// Return Promise for Async process, to signal success/failure.
|
// Return Promise for Async process, to signal success/failure.
|
||||||
return startCapability.promise;
|
return startCapability.promise;
|
||||||
},
|
},
|
||||||
@ -215,10 +217,10 @@ MessageHandler.prototype = {
|
|||||||
pull: (controller) => {
|
pull: (controller) => {
|
||||||
let pullCapability = createPromiseCapability();
|
let pullCapability = createPromiseCapability();
|
||||||
this.streamControllers[streamId].pullCall = pullCapability;
|
this.streamControllers[streamId].pullCall = pullCapability;
|
||||||
this.postMessage({
|
comObj.postMessage({
|
||||||
sourceName,
|
sourceName,
|
||||||
targetName,
|
targetName,
|
||||||
stream: 'pull',
|
stream: StreamKind.PULL,
|
||||||
streamId,
|
streamId,
|
||||||
desiredSize: controller.desiredSize,
|
desiredSize: controller.desiredSize,
|
||||||
});
|
});
|
||||||
@ -231,12 +233,12 @@ MessageHandler.prototype = {
|
|||||||
let cancelCapability = createPromiseCapability();
|
let cancelCapability = createPromiseCapability();
|
||||||
this.streamControllers[streamId].cancelCall = cancelCapability;
|
this.streamControllers[streamId].cancelCall = cancelCapability;
|
||||||
this.streamControllers[streamId].isClosed = true;
|
this.streamControllers[streamId].isClosed = true;
|
||||||
this.postMessage({
|
comObj.postMessage({
|
||||||
sourceName,
|
sourceName,
|
||||||
targetName,
|
targetName,
|
||||||
stream: 'cancel',
|
stream: StreamKind.CANCEL,
|
||||||
reason,
|
|
||||||
streamId,
|
streamId,
|
||||||
|
reason,
|
||||||
});
|
});
|
||||||
// Return Promise to signal success or failure.
|
// Return Promise to signal success or failure.
|
||||||
return cancelCapability.promise;
|
return cancelCapability.promise;
|
||||||
@ -252,12 +254,7 @@ MessageHandler.prototype = {
|
|||||||
let sourceName = this.sourceName;
|
let sourceName = this.sourceName;
|
||||||
let targetName = data.sourceName;
|
let targetName = data.sourceName;
|
||||||
let capability = createPromiseCapability();
|
let capability = createPromiseCapability();
|
||||||
|
const comObj = this.comObj;
|
||||||
let sendStreamRequest = ({ stream, chunk, transfers,
|
|
||||||
success, reason, }) => {
|
|
||||||
this.postMessage({ sourceName, targetName, stream, streamId,
|
|
||||||
chunk, success, reason, }, transfers);
|
|
||||||
};
|
|
||||||
|
|
||||||
let streamSink = {
|
let streamSink = {
|
||||||
enqueue(chunk, size = 1, transfers) {
|
enqueue(chunk, size = 1, transfers) {
|
||||||
@ -273,7 +270,13 @@ MessageHandler.prototype = {
|
|||||||
this.sinkCapability = createPromiseCapability();
|
this.sinkCapability = createPromiseCapability();
|
||||||
this.ready = this.sinkCapability.promise;
|
this.ready = this.sinkCapability.promise;
|
||||||
}
|
}
|
||||||
sendStreamRequest({ stream: 'enqueue', chunk, transfers, });
|
self.postMessage({
|
||||||
|
sourceName,
|
||||||
|
targetName,
|
||||||
|
stream: StreamKind.ENQUEUE,
|
||||||
|
streamId,
|
||||||
|
chunk,
|
||||||
|
}, transfers);
|
||||||
},
|
},
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
@ -281,7 +284,12 @@ MessageHandler.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.isCancelled = true;
|
this.isCancelled = true;
|
||||||
sendStreamRequest({ stream: 'close', });
|
comObj.postMessage({
|
||||||
|
sourceName,
|
||||||
|
targetName,
|
||||||
|
stream: StreamKind.CLOSE,
|
||||||
|
streamId,
|
||||||
|
});
|
||||||
delete self.streamSinks[streamId];
|
delete self.streamSinks[streamId];
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -290,7 +298,13 @@ MessageHandler.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.isCancelled = true;
|
this.isCancelled = true;
|
||||||
sendStreamRequest({ stream: 'error', reason, });
|
comObj.postMessage({
|
||||||
|
sourceName,
|
||||||
|
targetName,
|
||||||
|
stream: StreamKind.ERROR,
|
||||||
|
streamId,
|
||||||
|
reason,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
sinkCapability: capability,
|
sinkCapability: capability,
|
||||||
@ -305,9 +319,21 @@ MessageHandler.prototype = {
|
|||||||
streamSink.ready = streamSink.sinkCapability.promise;
|
streamSink.ready = streamSink.sinkCapability.promise;
|
||||||
this.streamSinks[streamId] = streamSink;
|
this.streamSinks[streamId] = streamSink;
|
||||||
resolveCall(action[0], [data.data, streamSink], action[1]).then(() => {
|
resolveCall(action[0], [data.data, streamSink], action[1]).then(() => {
|
||||||
sendStreamRequest({ stream: 'start_complete', success: true, });
|
comObj.postMessage({
|
||||||
|
sourceName,
|
||||||
|
targetName,
|
||||||
|
stream: StreamKind.START_COMPLETE,
|
||||||
|
streamId,
|
||||||
|
success: true,
|
||||||
|
});
|
||||||
}, (reason) => {
|
}, (reason) => {
|
||||||
sendStreamRequest({ stream: 'start_complete', success: false, reason, });
|
comObj.postMessage({
|
||||||
|
sourceName,
|
||||||
|
targetName,
|
||||||
|
stream: StreamKind.START_COMPLETE,
|
||||||
|
streamId,
|
||||||
|
reason,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -315,11 +341,7 @@ MessageHandler.prototype = {
|
|||||||
let sourceName = this.sourceName;
|
let sourceName = this.sourceName;
|
||||||
let targetName = data.sourceName;
|
let targetName = data.sourceName;
|
||||||
let streamId = data.streamId;
|
let streamId = data.streamId;
|
||||||
|
const comObj = this.comObj;
|
||||||
let sendStreamResponse = ({ stream, success, reason, }) => {
|
|
||||||
this.comObj.postMessage({ sourceName, targetName, stream,
|
|
||||||
success, streamId, reason, });
|
|
||||||
};
|
|
||||||
|
|
||||||
let deleteStreamController = () => {
|
let deleteStreamController = () => {
|
||||||
// Delete the `streamController` only when the start, pull, and cancel
|
// Delete the `streamController` only when the start, pull, and cancel
|
||||||
@ -336,16 +358,22 @@ MessageHandler.prototype = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
switch (data.stream) {
|
switch (data.stream) {
|
||||||
case 'start_complete':
|
case StreamKind.START_COMPLETE:
|
||||||
resolveOrReject(this.streamControllers[data.streamId].startCall, data);
|
resolveOrReject(this.streamControllers[data.streamId].startCall, data);
|
||||||
break;
|
break;
|
||||||
case 'pull_complete':
|
case StreamKind.PULL_COMPLETE:
|
||||||
resolveOrReject(this.streamControllers[data.streamId].pullCall, data);
|
resolveOrReject(this.streamControllers[data.streamId].pullCall, data);
|
||||||
break;
|
break;
|
||||||
case 'pull':
|
case StreamKind.PULL:
|
||||||
// Ignore any pull after close is called.
|
// Ignore any pull after close is called.
|
||||||
if (!this.streamSinks[data.streamId]) {
|
if (!this.streamSinks[data.streamId]) {
|
||||||
sendStreamResponse({ stream: 'pull_complete', success: true, });
|
comObj.postMessage({
|
||||||
|
sourceName,
|
||||||
|
targetName,
|
||||||
|
stream: StreamKind.PULL_COMPLETE,
|
||||||
|
streamId,
|
||||||
|
success: true,
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Pull increases the desiredSize property of sink,
|
// Pull increases the desiredSize property of sink,
|
||||||
@ -358,20 +386,31 @@ MessageHandler.prototype = {
|
|||||||
// Reset desiredSize property of sink on every pull.
|
// Reset desiredSize property of sink on every pull.
|
||||||
this.streamSinks[data.streamId].desiredSize = data.desiredSize;
|
this.streamSinks[data.streamId].desiredSize = data.desiredSize;
|
||||||
resolveCall(this.streamSinks[data.streamId].onPull).then(() => {
|
resolveCall(this.streamSinks[data.streamId].onPull).then(() => {
|
||||||
sendStreamResponse({ stream: 'pull_complete', success: true, });
|
comObj.postMessage({
|
||||||
|
sourceName,
|
||||||
|
targetName,
|
||||||
|
stream: StreamKind.PULL_COMPLETE,
|
||||||
|
streamId,
|
||||||
|
success: true,
|
||||||
|
});
|
||||||
}, (reason) => {
|
}, (reason) => {
|
||||||
sendStreamResponse({ stream: 'pull_complete',
|
comObj.postMessage({
|
||||||
success: false, reason, });
|
sourceName,
|
||||||
|
targetName,
|
||||||
|
stream: StreamKind.PULL_COMPLETE,
|
||||||
|
streamId,
|
||||||
|
reason,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'enqueue':
|
case StreamKind.ENQUEUE:
|
||||||
assert(this.streamControllers[data.streamId],
|
assert(this.streamControllers[data.streamId],
|
||||||
'enqueue should have stream controller');
|
'enqueue should have stream controller');
|
||||||
if (!this.streamControllers[data.streamId].isClosed) {
|
if (!this.streamControllers[data.streamId].isClosed) {
|
||||||
this.streamControllers[data.streamId].controller.enqueue(data.chunk);
|
this.streamControllers[data.streamId].controller.enqueue(data.chunk);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'close':
|
case StreamKind.CLOSE:
|
||||||
assert(this.streamControllers[data.streamId],
|
assert(this.streamControllers[data.streamId],
|
||||||
'close should have stream controller');
|
'close should have stream controller');
|
||||||
if (this.streamControllers[data.streamId].isClosed) {
|
if (this.streamControllers[data.streamId].isClosed) {
|
||||||
@ -381,27 +420,38 @@ MessageHandler.prototype = {
|
|||||||
this.streamControllers[data.streamId].controller.close();
|
this.streamControllers[data.streamId].controller.close();
|
||||||
deleteStreamController();
|
deleteStreamController();
|
||||||
break;
|
break;
|
||||||
case 'error':
|
case StreamKind.ERROR:
|
||||||
assert(this.streamControllers[data.streamId],
|
assert(this.streamControllers[data.streamId],
|
||||||
'error should have stream controller');
|
'error should have stream controller');
|
||||||
this.streamControllers[data.streamId].controller.
|
this.streamControllers[data.streamId].controller.
|
||||||
error(wrapReason(data.reason));
|
error(wrapReason(data.reason));
|
||||||
deleteStreamController();
|
deleteStreamController();
|
||||||
break;
|
break;
|
||||||
case 'cancel_complete':
|
case StreamKind.CANCEL_COMPLETE:
|
||||||
resolveOrReject(this.streamControllers[data.streamId].cancelCall, data);
|
resolveOrReject(this.streamControllers[data.streamId].cancelCall, data);
|
||||||
deleteStreamController();
|
deleteStreamController();
|
||||||
break;
|
break;
|
||||||
case 'cancel':
|
case StreamKind.CANCEL:
|
||||||
if (!this.streamSinks[data.streamId]) {
|
if (!this.streamSinks[data.streamId]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
resolveCall(this.streamSinks[data.streamId].onCancel,
|
resolveCall(this.streamSinks[data.streamId].onCancel,
|
||||||
[wrapReason(data.reason)]).then(() => {
|
[wrapReason(data.reason)]).then(() => {
|
||||||
sendStreamResponse({ stream: 'cancel_complete', success: true, });
|
comObj.postMessage({
|
||||||
|
sourceName,
|
||||||
|
targetName,
|
||||||
|
stream: StreamKind.CANCEL_COMPLETE,
|
||||||
|
streamId,
|
||||||
|
success: true,
|
||||||
|
});
|
||||||
}, (reason) => {
|
}, (reason) => {
|
||||||
sendStreamResponse({ stream: 'cancel_complete',
|
comObj.postMessage({
|
||||||
success: false, reason, });
|
sourceName,
|
||||||
|
targetName,
|
||||||
|
stream: StreamKind.CANCEL_COMPLETE,
|
||||||
|
streamId,
|
||||||
|
reason,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
this.streamSinks[data.streamId].sinkCapability.
|
this.streamSinks[data.streamId].sinkCapability.
|
||||||
reject(wrapReason(data.reason));
|
reject(wrapReason(data.reason));
|
||||||
|
Loading…
Reference in New Issue
Block a user