Merge pull request #838 from twiss/worker-buffer-transfer
Transfer buffers in workers
This commit is contained in:
commit
a87d03a7bd
20
src/util.js
20
src/util.js
|
@ -52,19 +52,19 @@ export default {
|
||||||
* @param {Object} obj the options object to be passed to the web worker
|
* @param {Object} obj the options object to be passed to the web worker
|
||||||
* @returns {Array<ArrayBuffer>} an array of binary data to be passed
|
* @returns {Array<ArrayBuffer>} an array of binary data to be passed
|
||||||
*/
|
*/
|
||||||
getTransferables: function(obj) {
|
getTransferables: function(obj, zero_copy) {
|
||||||
const transferables = [];
|
const transferables = [];
|
||||||
util.collectTransferables(obj, transferables);
|
util.collectTransferables(obj, transferables, zero_copy);
|
||||||
return transferables.length ? transferables : undefined;
|
return transferables.length ? transferables : undefined;
|
||||||
},
|
},
|
||||||
|
|
||||||
collectTransferables: function(obj, collection) {
|
collectTransferables: function(obj, collection, zero_copy) {
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (util.isUint8Array(obj) && collection.indexOf(obj.buffer) === -1) {
|
if (util.isUint8Array(obj)) {
|
||||||
if (config.zero_copy) {
|
if (zero_copy && collection.indexOf(obj.buffer) === -1) {
|
||||||
collection.push(obj.buffer);
|
collection.push(obj.buffer);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -79,8 +79,12 @@ export default {
|
||||||
const reader = stream.getReader(readable);
|
const reader = stream.getReader(readable);
|
||||||
const { port1, port2 } = new MessageChannel();
|
const { port1, port2 } = new MessageChannel();
|
||||||
port1.onmessage = async function({ data: { action } }) {
|
port1.onmessage = async function({ data: { action } }) {
|
||||||
if (action === 'read') port1.postMessage(await reader.read());
|
if (action === 'read') {
|
||||||
else if (action === 'cancel') port1.postMessage(await transformed.cancel());
|
const result = await reader.read();
|
||||||
|
port1.postMessage(result, util.getTransferables(result, true));
|
||||||
|
} else if (action === 'cancel') {
|
||||||
|
port1.postMessage(await transformed.cancel());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
obj[key] = port2;
|
obj[key] = port2;
|
||||||
collection.push(port2);
|
collection.push(port2);
|
||||||
|
@ -91,7 +95,7 @@ export default {
|
||||||
if (Object.prototype.toString.call(value) === '[object MessagePort]') {
|
if (Object.prototype.toString.call(value) === '[object MessagePort]') {
|
||||||
throw new Error("Can't transfer the same stream twice.");
|
throw new Error("Can't transfer the same stream twice.");
|
||||||
}
|
}
|
||||||
util.collectTransferables(value, collection);
|
util.collectTransferables(value, collection, zero_copy);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,12 +22,14 @@
|
||||||
* @see module:openpgp.destroyWorker
|
* @see module:openpgp.destroyWorker
|
||||||
* @see module:worker/worker
|
* @see module:worker/worker
|
||||||
* @requires util
|
* @requires util
|
||||||
|
* @requires config
|
||||||
* @requires crypto
|
* @requires crypto
|
||||||
* @requires packet
|
* @requires packet
|
||||||
* @module worker/async_proxy
|
* @module worker/async_proxy
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import util from '../util.js';
|
import util from '../util.js';
|
||||||
|
import config from '../config';
|
||||||
import crypto from '../crypto';
|
import crypto from '../crypto';
|
||||||
import packet from '../packet';
|
import packet from '../packet';
|
||||||
|
|
||||||
|
@ -112,7 +114,7 @@ AsyncProxy.prototype.getID = function() {
|
||||||
*/
|
*/
|
||||||
AsyncProxy.prototype.seedRandom = async function(workerId, size) {
|
AsyncProxy.prototype.seedRandom = async function(workerId, size) {
|
||||||
const buf = await crypto.random.getRandomBytes(size);
|
const buf = await crypto.random.getRandomBytes(size);
|
||||||
this.workers[workerId].postMessage({ event:'seed-random', buf }, util.getTransferables(buf));
|
this.workers[workerId].postMessage({ event:'seed-random', buf }, util.getTransferables(buf, true));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,9 +145,9 @@ AsyncProxy.prototype.delegate = function(method, options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// clone packets (for web worker structured cloning algorithm)
|
// clone packets (for web worker structured cloning algorithm)
|
||||||
this.workers[workerId].postMessage({ id:id, event:method, options:packet.clone.clonePackets(options) }, util.getTransferables(options));
|
this.workers[workerId].postMessage({ id:id, event:method, options:packet.clone.clonePackets(options) }, util.getTransferables(options, config.zero_copy));
|
||||||
this.workers[workerId].requests++;
|
this.workers[workerId].requests++;
|
||||||
|
|
||||||
// remember to handle parsing cloned packets from worker
|
// remember to handle parsing cloned packets from worker
|
||||||
|
|
|
@ -133,5 +133,5 @@ function delegate(id, method, options) {
|
||||||
* @param {Object} event Contains event type and data
|
* @param {Object} event Contains event type and data
|
||||||
*/
|
*/
|
||||||
function response(event) {
|
function response(event) {
|
||||||
self.postMessage(event, openpgp.util.getTransferables(event.data));
|
self.postMessage(event, openpgp.util.getTransferables(event.data, true));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1741,7 +1741,7 @@ describe('[Sauce Labs Group 2] OpenPGP.js public api tests', function() {
|
||||||
if (i++ < 4) {
|
if (i++ < 4) {
|
||||||
let randomBytes = await openpgp.crypto.random.getRandomBytes(10);
|
let randomBytes = await openpgp.crypto.random.getRandomBytes(10);
|
||||||
controller.enqueue(randomBytes);
|
controller.enqueue(randomBytes);
|
||||||
plaintext.push(randomBytes);
|
plaintext.push(randomBytes.slice());
|
||||||
} else {
|
} else {
|
||||||
controller.close();
|
controller.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,6 @@ describe('Util unit tests', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getTransferables', function() {
|
describe('getTransferables', function() {
|
||||||
let zero_copyVal;
|
|
||||||
const buf1 = new Uint8Array(1);
|
const buf1 = new Uint8Array(1);
|
||||||
const buf2 = new Uint8Array(1);
|
const buf2 = new Uint8Array(1);
|
||||||
const obj = {
|
const obj = {
|
||||||
|
@ -128,27 +127,18 @@ describe('Util unit tests', function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
zero_copyVal = openpgp.config.zero_copy;
|
|
||||||
openpgp.config.zero_copy = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(function() {
|
|
||||||
openpgp.config.zero_copy = zero_copyVal;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return undefined when zero_copy is false', function() {
|
it('should return undefined when zero_copy is false', function() {
|
||||||
openpgp.config.zero_copy = false;
|
openpgp.config.zero_copy = false;
|
||||||
expect(openpgp.util.getTransferables(obj)).to.be.undefined;
|
expect(openpgp.util.getTransferables(obj, false)).to.be.undefined;
|
||||||
});
|
});
|
||||||
it('should return undefined for no input', function() {
|
it('should return undefined for no input', function() {
|
||||||
expect(openpgp.util.getTransferables()).to.be.undefined;
|
expect(openpgp.util.getTransferables(undefined, true)).to.be.undefined;
|
||||||
});
|
});
|
||||||
it('should return undefined for an empty oject', function() {
|
it('should return undefined for an empty oject', function() {
|
||||||
expect(openpgp.util.getTransferables({})).to.be.undefined;
|
expect(openpgp.util.getTransferables({}, true)).to.be.undefined;
|
||||||
});
|
});
|
||||||
it('should return two buffers', function() {
|
it('should return two buffers', function() {
|
||||||
expect(openpgp.util.getTransferables(obj)).to.deep.equal([buf1.buffer, buf2.buffer]);
|
expect(openpgp.util.getTransferables(obj, true)).to.deep.equal([buf1.buffer, buf2.buffer]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user