Skip to content

Commit

Permalink
add and use getWorkerBootstrapUrl, don't use default worker factory…
Browse files Browse the repository at this point in the history
… anymore
  • Loading branch information
jrieken committed Aug 14, 2019
1 parent 9c2cc80 commit c3fcaef
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 42 deletions.
33 changes: 19 additions & 14 deletions src/vs/base/worker/defaultWorkerFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,31 @@ function getWorker(workerId: string, label: string): Worker | Promise<Worker> {
// ESM-comment-begin
if (typeof require === 'function') {
// check if the JS lives on a different origin

const workerMain = require.toUrl('./' + workerId);
if (/^(http:)|(https:)|(file:)/.test(workerMain)) {
const currentUrl = String(window.location);
const currentOrigin = currentUrl.substr(0, currentUrl.length - window.location.hash.length - window.location.search.length - window.location.pathname.length);
if (workerMain.substring(0, currentOrigin.length) !== currentOrigin) {
// this is the cross-origin case
// i.e. the webpage is running at a different origin than where the scripts are loaded from
const workerBaseUrl = workerMain.substr(0, workerMain.length - 'vs/base/worker/workerMain.js'.length);
const js = `/*${label}*/self.MonacoEnvironment={baseUrl: '${workerBaseUrl}'};importScripts('${workerMain}');/*${label}*/`;
const url = `data:text/javascript;charset=utf-8,${encodeURIComponent(js)}`;
return new Worker(url);
}
}
return new Worker(workerMain + '#' + label);
const workerUrl = getWorkerBootstrapUrl(workerMain, label);
return new Worker(workerUrl, { name: label });
}
// ESM-comment-end
throw new Error(`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`);
}

export function getWorkerBootstrapUrl(scriptPath: string, label: string): string {
if (/^(http:)|(https:)|(file:)/.test(scriptPath)) {
const currentUrl = String(window.location);
const currentOrigin = currentUrl.substr(0, currentUrl.length - window.location.hash.length - window.location.search.length - window.location.pathname.length);
if (scriptPath.substring(0, currentOrigin.length) !== currentOrigin) {
// this is the cross-origin case
// i.e. the webpage is running at a different origin than where the scripts are loaded from
const myPath = 'vs/base/worker/defaultWorkerFactory.js';
const workerBaseUrl = require.toUrl(myPath).slice(0, -myPath.length);
const js = `/*${label}*/self.MonacoEnvironment={baseUrl: '${workerBaseUrl}'};importScripts('${scriptPath}');/*${label}*/`;
const url = `data:text/javascript;charset=utf-8,${encodeURIComponent(js)}`;
return url;
}
}
return scriptPath + '#' + label;
}

function isPromiseLike<T>(obj: any): obj is PromiseLike<T> {
if (typeof obj.then === 'function') {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { DefaultWorkerFactory } from 'vs/base/worker/defaultWorkerFactory';
import { getWorkerBootstrapUrl } from 'vs/base/worker/defaultWorkerFactory';
import { Emitter, Event } from 'vs/base/common/event';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
import { VSBuffer } from 'vs/base/common/buffer';
import { createMessageOfType, MessageType, isMessageOfType } from 'vs/workbench/services/extensions/common/extensionHostProtocol';
Expand Down Expand Up @@ -49,23 +49,29 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter {
if (!this._protocol) {

const emitter = new Emitter<VSBuffer>();
const worker = new DefaultWorkerFactory('WorkerExtensionHost').create(
'vs/workbench/services/extensions/worker/extensionHostWorker', data => {
if (data instanceof ArrayBuffer) {
emitter.fire(VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength)));
} else {
console.warn('UNKNOWN data received', data);
this._onDidExit.fire([77, 'UNKNOWN data received']);
}
}, err => {
this._onDidExit.fire([81, err]);
console.error(err);

const url = getWorkerBootstrapUrl(require.toUrl('../worker/extensionHostWorkerMain.js'), 'WorkerExtensionHost');
const worker = new Worker(url);

worker.onmessage = (event) => {
const { data } = event;
if (!(data instanceof ArrayBuffer)) {
console.warn('UNKNOWN data received', data);
this._onDidExit.fire([77, 'UNKNOWN data received']);
return;
}
);

emitter.fire(VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength)));
};

worker.onerror = (event) => {
console.error(event.error);
this._onDidExit.fire([81, event.error]);
};

// keep for cleanup
this._toDispose.add(emitter);
this._toDispose.add(worker);
this._toDispose.add(toDisposable(() => worker.terminate()));

const protocol: IMessagePassingProtocol = {
onMessage: emitter.event,
Expand Down
20 changes: 7 additions & 13 deletions src/vs/workbench/services/extensions/worker/extensionHostWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { IRequestHandler } from 'vs/base/common/worker/simpleWorker';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
import { VSBuffer } from 'vs/base/common/buffer';
import { Emitter } from 'vs/base/common/event';
Expand Down Expand Up @@ -38,21 +37,18 @@ const hostUtil = new class implements IHostUtils {

//todo@joh do not allow extensions to call postMessage and other globals...

class ExtensionWorker implements IRequestHandler {

// worker-contract
readonly _requestHandlerBrand: any;
readonly onmessage: (data: any) => any;
class ExtensionWorker {

// protocol
readonly protocol: IMessagePassingProtocol;

constructor(postMessage: (message: any, transfer?: Transferable[]) => any) {
constructor() {

let emitter = new Emitter<VSBuffer>();
let terminating = false;

this.onmessage = data => {
onmessage = event => {
const { data } = event;
if (!(data instanceof ArrayBuffer)) {
console.warn('UNKNOWN data received', data);
return;
Expand Down Expand Up @@ -98,8 +94,8 @@ function connectToRenderer(protocol: IMessagePassingProtocol): Promise<IRenderer
});
}

export function create(postMessage: (message: any, transfer?: Transferable[]) => any): IRequestHandler {
const res = new ExtensionWorker(postMessage);
(function create(): void {
const res = new ExtensionWorker();

connectToRenderer(res.protocol).then(data => {

Expand All @@ -112,6 +108,4 @@ export function create(postMessage: (message: any, transfer?: Transferable[]) =>

onTerminate = () => extHostMain.terminate();
});

return res;
}
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

(function () {

let MonacoEnvironment = (<any>self).MonacoEnvironment;
let monacoBaseUrl = MonacoEnvironment && MonacoEnvironment.baseUrl ? MonacoEnvironment.baseUrl : '../../../../../';

if (typeof (<any>self).define !== 'function' || !(<any>self).define.amd) {
importScripts(monacoBaseUrl + 'vs/loader.js');
}

require.config({
baseUrl: monacoBaseUrl,
catchError: true
});

require(['vs/workbench/services/extensions/worker/extensionHostWorker'], () => { }, err => console.error(err));
})();

0 comments on commit c3fcaef

Please sign in to comment.