mirror of
https://github.com/microsoft/vscode.git
synced 2026-08-05 21:07:16 +01:00
Handle better the case when web workers are not available / misconfigured
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
# Monaco Editor Change log
|
||||
|
||||
## [0.5.0]
|
||||
|
||||
### Breaking changes
|
||||
- `createWebWorker` now loads the AMD module and calls `create` and passes in as first argument a context of type `monaco.worker.IWorkerContext` and as second argument the `initData`. This breaking change was needed to allow handling the case of misconfigured web workers (running of a file protocol or a cross-domain case)
|
||||
- the `CodeActionProvider.provideCodeActions` now gets passed in a `CodeActionContext` that contains the markers at the relevant range.
|
||||
@@ -165,9 +165,21 @@ export class SimpleWorkerClient<T> extends Disposable {
|
||||
|
||||
constructor(workerFactory:IWorkerFactory, moduleId:string) {
|
||||
super();
|
||||
this._worker = this._register(workerFactory.create('vs/base/common/worker/simpleWorker', (msg:string) => {
|
||||
this._protocol.handleMessage(msg);
|
||||
}));
|
||||
|
||||
let lazyProxyFulfill : (v:T)=>void = null;
|
||||
let lazyProxyReject: (err:any)=>void = null;
|
||||
|
||||
this._worker = this._register(workerFactory.create(
|
||||
'vs/base/common/worker/simpleWorker',
|
||||
(msg:string) => {
|
||||
this._protocol.handleMessage(msg);
|
||||
},
|
||||
(err:any) => {
|
||||
// in Firefox, web workers fail lazily :(
|
||||
// we will reject the proxy
|
||||
lazyProxyReject(err);
|
||||
}
|
||||
));
|
||||
|
||||
this._protocol = new SimpleWorkerProtocol({
|
||||
sendMessage: (msg:string): void => {
|
||||
@@ -191,9 +203,6 @@ export class SimpleWorkerClient<T> extends Disposable {
|
||||
loaderConfiguration = (<any>window).requirejs.s.contexts._.config;
|
||||
}
|
||||
|
||||
let lazyProxyFulfill : (v:T)=>void = null;
|
||||
let lazyProxyReject: (err:any)=>void = null;
|
||||
|
||||
this._lazyProxy = new TPromise((c, e, p) => {
|
||||
lazyProxyFulfill = c;
|
||||
lazyProxyReject = e;
|
||||
|
||||
@@ -17,12 +17,21 @@ export interface IWorker {
|
||||
dispose():void;
|
||||
}
|
||||
|
||||
let webWorkerWarningLogged = false;
|
||||
export function logOnceWebWorkerWarning(err:any): void {
|
||||
if (!webWorkerWarningLogged) {
|
||||
webWorkerWarningLogged = true;
|
||||
console.warn('Could not create web worker(s). Falling back to loading web worker code in main thread, which might cause UI freezes. Please see https://github.com/Microsoft/monaco-editor#faq');
|
||||
}
|
||||
console.warn(err.message);
|
||||
}
|
||||
|
||||
export interface IWorkerCallback {
|
||||
(message:string):void;
|
||||
}
|
||||
|
||||
export interface IWorkerFactory {
|
||||
create(moduleId:string, callback:IWorkerCallback, onCrashCallback?:()=>void):IWorker;
|
||||
create(moduleId:string, callback:IWorkerCallback, onErrorCallback:(err:any)=>void):IWorker;
|
||||
}
|
||||
|
||||
interface IActiveRequest {
|
||||
@@ -59,7 +68,15 @@ export class WorkerClient {
|
||||
this._waitingForWorkerReply = false;
|
||||
this._lastTimerEvent = null;
|
||||
|
||||
this._worker = workerFactory.create('vs/base/common/worker/workerServer', (msg) => this._onSerializedMessage(msg));
|
||||
this._worker = workerFactory.create(
|
||||
'vs/base/common/worker/workerServer',
|
||||
(msg) => this._onSerializedMessage(msg),
|
||||
(err) => {
|
||||
// reject the onModuleLoaded promise, this signals that things are bad
|
||||
let promiseEntry:IActiveRequest = this._promises[1];
|
||||
delete this._promises[1];
|
||||
promiseEntry.error(err);
|
||||
});
|
||||
|
||||
let loaderConfiguration:any = null;
|
||||
|
||||
@@ -80,7 +97,6 @@ export class WorkerClient {
|
||||
loaderConfiguration: loaderConfiguration,
|
||||
GlobalEnvironment: GlobalEnvironment
|
||||
});
|
||||
this.onModuleLoaded.then(null, (e) => this._onError('Worker failed to load ' + moduleId, e));
|
||||
|
||||
this._remoteCom = new workerProtocol.RemoteCom(this);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import * as flags from 'vs/base/common/flags';
|
||||
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
|
||||
import {IWorker, IWorkerCallback, IWorkerFactory} from 'vs/base/common/worker/workerClient';
|
||||
import {logOnceWebWorkerWarning, IWorker, IWorkerCallback, IWorkerFactory} from 'vs/base/common/worker/workerClient';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
|
||||
function defaultGetWorkerUrl(workerId:string, label:string): string {
|
||||
@@ -24,13 +24,16 @@ class WebWorker implements IWorker {
|
||||
private id:number;
|
||||
private worker:Worker;
|
||||
|
||||
constructor(moduleId:string, id:number, label:string, onMessageCallback:IWorkerCallback) {
|
||||
constructor(moduleId:string, id:number, label:string, onMessageCallback:IWorkerCallback, onErrorCallback:(err:any)=>void) {
|
||||
this.id = id;
|
||||
this.worker = new Worker(getWorkerUrl('workerMain.js', label));
|
||||
this.postMessage(moduleId);
|
||||
this.worker.onmessage = function (ev:any) {
|
||||
onMessageCallback(ev.data);
|
||||
};
|
||||
if (typeof this.worker.addEventListener === 'function') {
|
||||
this.worker.addEventListener('error', onErrorCallback);
|
||||
}
|
||||
}
|
||||
|
||||
public getId(): number {
|
||||
@@ -125,11 +128,41 @@ export class DefaultWorkerFactory implements IWorkerFactory {
|
||||
|
||||
private static LAST_WORKER_ID = 0;
|
||||
|
||||
public create(moduleId:string, onMessageCallback:IWorkerCallback):IWorker {
|
||||
var workerId = (++DefaultWorkerFactory.LAST_WORKER_ID);
|
||||
if (typeof WebWorker !== 'undefined') {
|
||||
return new WebWorker(moduleId, workerId, 'service' + workerId, onMessageCallback);
|
||||
}
|
||||
return new FrameWorker(moduleId, workerId, onMessageCallback);
|
||||
private _fallbackToIframe:boolean;
|
||||
private _webWorkerFailedBeforeError:any;
|
||||
|
||||
constructor(fallbackToIframe:boolean) {
|
||||
this._fallbackToIframe = fallbackToIframe;
|
||||
this._webWorkerFailedBeforeError = false;
|
||||
}
|
||||
}
|
||||
|
||||
public create(moduleId:string, onMessageCallback:IWorkerCallback, onErrorCallback:(err:any)=>void):IWorker {
|
||||
let workerId = (++DefaultWorkerFactory.LAST_WORKER_ID);
|
||||
if (this._fallbackToIframe) {
|
||||
if (this._webWorkerFailedBeforeError) {
|
||||
// Avoid always trying to create web workers if they would just fail...
|
||||
return new FrameWorker(moduleId, workerId, onMessageCallback);
|
||||
}
|
||||
|
||||
try {
|
||||
return new WebWorker(moduleId, workerId, 'service' + workerId, onMessageCallback, (err) => {
|
||||
logOnceWebWorkerWarning(err);
|
||||
this._webWorkerFailedBeforeError = err;
|
||||
onErrorCallback(err);
|
||||
});
|
||||
} catch(err) {
|
||||
logOnceWebWorkerWarning(err);
|
||||
return new FrameWorker(moduleId, workerId, onMessageCallback);
|
||||
}
|
||||
}
|
||||
|
||||
if (this._webWorkerFailedBeforeError) {
|
||||
throw this._webWorkerFailedBeforeError;
|
||||
}
|
||||
return new WebWorker(moduleId, workerId, 'service' + workerId, onMessageCallback, (err) => {
|
||||
logOnceWebWorkerWarning(err);
|
||||
this._webWorkerFailedBeforeError = err;
|
||||
onErrorCallback(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import {TPromise} from 'vs/base/common/winjs.base';
|
||||
import {IDisposable} from 'vs/base/common/lifecycle';
|
||||
import {IRequestHandler} from 'vs/base/common/worker/simpleWorker';
|
||||
import {Range} from 'vs/editor/common/core/range';
|
||||
import {fuzzyContiguousFilter} from 'vs/base/common/filters';
|
||||
@@ -23,13 +24,37 @@ import {createMonacoBaseAPI} from 'vs/editor/common/standalone/standaloneBase';
|
||||
export interface IMirrorModel {
|
||||
uri: URI;
|
||||
version: number;
|
||||
getText(): string;
|
||||
getValue(): string;
|
||||
}
|
||||
|
||||
export interface IWorkerContext {
|
||||
/**
|
||||
* Get all available mirror models in this worker.
|
||||
*/
|
||||
getMirrorModels(): IMirrorModel[];
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class MirrorModel extends MirrorModel2 {
|
||||
export interface ICommonModel {
|
||||
uri: URI;
|
||||
version: number;
|
||||
getValue(): string;
|
||||
|
||||
getLinesContent(): string[];
|
||||
getLineCount(): number;
|
||||
getLineContent(lineNumber:number): string;
|
||||
getWordUntilPosition(position: editorCommon.IPosition, wordDefinition:RegExp): editorCommon.IWordAtPosition;
|
||||
getAllUniqueWords(wordDefinition:RegExp, skipWordOnce?:string) : string[];
|
||||
getValueInRange(range:editorCommon.IRange): string;
|
||||
getWordAtPosition(position:editorCommon.IPosition, wordDefinition:RegExp): Range;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class MirrorModel extends MirrorModel2 implements ICommonModel {
|
||||
|
||||
public get uri(): URI {
|
||||
return this._uri;
|
||||
@@ -39,6 +64,10 @@ export class MirrorModel extends MirrorModel2 {
|
||||
return this._versionId;
|
||||
}
|
||||
|
||||
public getValue(): string {
|
||||
return this.getText();
|
||||
}
|
||||
|
||||
public getLinesContent(): string[] {
|
||||
return this._lines.slice(0);
|
||||
}
|
||||
@@ -146,47 +175,21 @@ export class MirrorModel extends MirrorModel2 {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class EditorSimpleWorkerImpl implements IRequestHandler {
|
||||
_requestHandlerTrait: any;
|
||||
|
||||
private _models:{[uri:string]:MirrorModel;};
|
||||
export abstract class BaseEditorSimpleWorker {
|
||||
private _foreignModule: any;
|
||||
|
||||
constructor() {
|
||||
this._models = Object.create(null);
|
||||
this._foreignModule = null;
|
||||
}
|
||||
|
||||
public getModels(): MirrorModel[] {
|
||||
let all: MirrorModel[] = [];
|
||||
Object.keys(this._models).forEach((key) => all.push(this._models[key]));
|
||||
return all;
|
||||
}
|
||||
|
||||
public acceptNewModel(data:IRawModelData): void {
|
||||
this._models[data.url] = new MirrorModel(URI.parse(data.url), data.value.lines, data.value.EOL, data.versionId);
|
||||
}
|
||||
|
||||
public acceptModelChanged(strURL: string, events: editorCommon.IModelContentChangedEvent2[]): void {
|
||||
if (!this._models[strURL]) {
|
||||
return;
|
||||
}
|
||||
let model = this._models[strURL];
|
||||
model.onEvents(events);
|
||||
}
|
||||
|
||||
public acceptRemovedModel(strURL: string): void {
|
||||
if (!this._models[strURL]) {
|
||||
return;
|
||||
}
|
||||
delete this._models[strURL];
|
||||
}
|
||||
protected abstract _getModel(uri:string): ICommonModel;
|
||||
protected abstract _getModels(): ICommonModel[];
|
||||
|
||||
// ---- BEGIN diff --------------------------------------------------------------------------
|
||||
|
||||
public computeDiff(originalUrl:string, modifiedUrl:string, ignoreTrimWhitespace:boolean): TPromise<editorCommon.ILineChange[]> {
|
||||
let original = this._models[originalUrl];
|
||||
let modified = this._models[modifiedUrl];
|
||||
let original = this._getModel(originalUrl);
|
||||
let modified = this._getModel(modifiedUrl);
|
||||
if (!original || !modified) {
|
||||
return null;
|
||||
}
|
||||
@@ -202,8 +205,8 @@ export class EditorSimpleWorkerImpl implements IRequestHandler {
|
||||
}
|
||||
|
||||
public computeDirtyDiff(originalUrl:string, modifiedUrl:string, ignoreTrimWhitespace:boolean):TPromise<editorCommon.IChange[]> {
|
||||
let original = this._models[originalUrl];
|
||||
let modified = this._models[modifiedUrl];
|
||||
let original = this._getModel(originalUrl);
|
||||
let modified = this._getModel(modifiedUrl);
|
||||
if (!original || !modified) {
|
||||
return null;
|
||||
}
|
||||
@@ -221,7 +224,7 @@ export class EditorSimpleWorkerImpl implements IRequestHandler {
|
||||
// ---- END diff --------------------------------------------------------------------------
|
||||
|
||||
public computeLinks(modelUrl:string):TPromise<ILink[]> {
|
||||
let model = this._models[modelUrl];
|
||||
let model = this._getModel(modelUrl);
|
||||
if (!model) {
|
||||
return null;
|
||||
}
|
||||
@@ -232,7 +235,7 @@ export class EditorSimpleWorkerImpl implements IRequestHandler {
|
||||
// ---- BEGIN suggest --------------------------------------------------------------------------
|
||||
|
||||
public textualSuggest(modelUrl:string, position: editorCommon.IPosition, wordDef:string, wordDefFlags:string): TPromise<ISuggestResult[]> {
|
||||
let model = this._models[modelUrl];
|
||||
let model = this._getModel(modelUrl);
|
||||
if (!model) {
|
||||
return null;
|
||||
}
|
||||
@@ -240,7 +243,7 @@ export class EditorSimpleWorkerImpl implements IRequestHandler {
|
||||
return TPromise.as(this._suggestFiltered(model, position, new RegExp(wordDef, wordDefFlags)));
|
||||
}
|
||||
|
||||
private _suggestFiltered(model:MirrorModel, position: editorCommon.IPosition, wordDefRegExp: RegExp): ISuggestResult[] {
|
||||
private _suggestFiltered(model:ICommonModel, position: editorCommon.IPosition, wordDefRegExp: RegExp): ISuggestResult[] {
|
||||
let value = this._suggestUnfiltered(model, position, wordDefRegExp);
|
||||
|
||||
// filter suggestions
|
||||
@@ -251,7 +254,7 @@ export class EditorSimpleWorkerImpl implements IRequestHandler {
|
||||
}];
|
||||
}
|
||||
|
||||
private _suggestUnfiltered(model:MirrorModel, position:editorCommon.IPosition, wordDefRegExp: RegExp): ISuggestResult {
|
||||
private _suggestUnfiltered(model:ICommonModel, position:editorCommon.IPosition, wordDefRegExp: RegExp): ISuggestResult {
|
||||
let currentWord = model.getWordUntilPosition(position, wordDefRegExp).word;
|
||||
let allWords = model.getAllUniqueWords(wordDefRegExp, currentWord);
|
||||
|
||||
@@ -275,7 +278,7 @@ export class EditorSimpleWorkerImpl implements IRequestHandler {
|
||||
// ---- END suggest --------------------------------------------------------------------------
|
||||
|
||||
public navigateValueSet(modelUrl:string, range:editorCommon.IRange, up:boolean, wordDef:string, wordDefFlags:string): TPromise<IInplaceReplaceSupportResult> {
|
||||
let model = this._models[modelUrl];
|
||||
let model = this._getModel(modelUrl);
|
||||
if (!model) {
|
||||
return null;
|
||||
}
|
||||
@@ -304,7 +307,12 @@ export class EditorSimpleWorkerImpl implements IRequestHandler {
|
||||
return new TPromise<any>((c, e) => {
|
||||
// Use the global require to be sure to get the global config
|
||||
(<any>self).require([moduleId], (foreignModule) => {
|
||||
this._foreignModule = foreignModule.create(createData);
|
||||
let ctx: IWorkerContext = {
|
||||
getMirrorModels: ():IMirrorModel[] => {
|
||||
return this._getModels();
|
||||
}
|
||||
};
|
||||
this._foreignModule = foreignModule.create(ctx, createData);
|
||||
|
||||
let methods: string[] = [];
|
||||
for (let prop in this._foreignModule) {
|
||||
@@ -335,13 +343,51 @@ export class EditorSimpleWorkerImpl implements IRequestHandler {
|
||||
// ---- END foreign module support --------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
const instance = new EditorSimpleWorkerImpl();
|
||||
|
||||
/**
|
||||
* Get all available mirror models in this worker.
|
||||
* @internal
|
||||
*/
|
||||
export function getMirrorModels(): IMirrorModel[] {
|
||||
return instance.getModels();
|
||||
export class EditorSimpleWorkerImpl extends BaseEditorSimpleWorker implements IRequestHandler, IDisposable {
|
||||
_requestHandlerTrait: any;
|
||||
|
||||
private _models:{[uri:string]:MirrorModel;};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._models = Object.create(null);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._models = Object.create(null);
|
||||
}
|
||||
|
||||
protected _getModel(uri:string): ICommonModel {
|
||||
return this._models[uri];
|
||||
}
|
||||
|
||||
protected _getModels(): ICommonModel[] {
|
||||
let all: MirrorModel[] = [];
|
||||
Object.keys(this._models).forEach((key) => all.push(this._models[key]));
|
||||
return all;
|
||||
}
|
||||
|
||||
public acceptNewModel(data:IRawModelData): void {
|
||||
this._models[data.url] = new MirrorModel(URI.parse(data.url), data.value.lines, data.value.EOL, data.versionId);
|
||||
}
|
||||
|
||||
public acceptModelChanged(strURL: string, events: editorCommon.IModelContentChangedEvent2[]): void {
|
||||
if (!this._models[strURL]) {
|
||||
return;
|
||||
}
|
||||
let model = this._models[strURL];
|
||||
model.onEvents(events);
|
||||
}
|
||||
|
||||
public acceptRemovedModel(strURL: string): void {
|
||||
if (!this._models[strURL]) {
|
||||
return;
|
||||
}
|
||||
delete this._models[strURL];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -349,15 +395,11 @@ export function getMirrorModels(): IMirrorModel[] {
|
||||
* @internal
|
||||
*/
|
||||
export function create(): IRequestHandler {
|
||||
return instance;
|
||||
}
|
||||
|
||||
function createMonacoWorkerAPI(): typeof monaco.worker {
|
||||
return {
|
||||
getMirrorModels: getMirrorModels
|
||||
};
|
||||
return new EditorSimpleWorkerImpl();
|
||||
}
|
||||
|
||||
var global:any = self;
|
||||
global.monaco = createMonacoBaseAPI();
|
||||
global.monaco.worker = createMonacoWorkerAPI();
|
||||
let isWebWorker = (typeof global.importScripts === 'function');
|
||||
if (isWebWorker) {
|
||||
global.monaco = createMonacoBaseAPI();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import {IntervalTimer} from 'vs/base/common/async';
|
||||
import {IntervalTimer, ShallowCancelThenPromise} from 'vs/base/common/async';
|
||||
import {Disposable, IDisposable, dispose} from 'vs/base/common/lifecycle';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import {TPromise} from 'vs/base/common/winjs.base';
|
||||
@@ -16,6 +16,7 @@ import {IInplaceReplaceSupportResult, ILink, ISuggestResult} from 'vs/editor/com
|
||||
import {IEditorWorkerService} from 'vs/editor/common/services/editorWorkerService';
|
||||
import {IModelService} from 'vs/editor/common/services/modelService';
|
||||
import {EditorSimpleWorkerImpl} from 'vs/editor/common/services/editorSimpleWorker';
|
||||
import {logOnceWebWorkerWarning} from 'vs/base/common/worker/workerClient';
|
||||
|
||||
/**
|
||||
* Stop syncing a model to the worker if it was not needed for 1 min.
|
||||
@@ -211,31 +212,67 @@ class EditorModelManager extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
interface IWorkerClient<T> {
|
||||
getProxyObject(): TPromise<T>;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
class SynchronousWorkerClient<T extends IDisposable> implements IWorkerClient<T> {
|
||||
private _instance: T;
|
||||
private _proxyObj: TPromise<T>;
|
||||
|
||||
constructor(instance:T) {
|
||||
this._instance = instance;
|
||||
this._proxyObj = TPromise.as(this._instance);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._instance.dispose();
|
||||
this._instance = null;
|
||||
this._proxyObj = null;
|
||||
}
|
||||
|
||||
public getProxyObject(): TPromise<T> {
|
||||
return new ShallowCancelThenPromise(this._proxyObj);
|
||||
}
|
||||
}
|
||||
|
||||
export class EditorWorkerClient extends Disposable {
|
||||
|
||||
private _modelService: IModelService;
|
||||
private _worker: SimpleWorkerClient<EditorSimpleWorkerImpl>;
|
||||
private _worker: IWorkerClient<EditorSimpleWorkerImpl>;
|
||||
private _workerFactory: DefaultWorkerFactory;
|
||||
private _modelManager: EditorModelManager;
|
||||
|
||||
constructor(modelService: IModelService) {
|
||||
super();
|
||||
this._modelService = modelService;
|
||||
this._workerFactory = new DefaultWorkerFactory(/*do not use iframe*/false);
|
||||
this._worker = null;
|
||||
this._modelManager = null;
|
||||
}
|
||||
|
||||
private _getOrCreateWorker(): SimpleWorkerClient<EditorSimpleWorkerImpl> {
|
||||
private _getOrCreateWorker(): IWorkerClient<EditorSimpleWorkerImpl> {
|
||||
if (!this._worker) {
|
||||
this._worker = this._register(new SimpleWorkerClient<EditorSimpleWorkerImpl>(
|
||||
new DefaultWorkerFactory(),
|
||||
'vs/editor/common/services/editorSimpleWorker'
|
||||
));
|
||||
try {
|
||||
this._worker = this._register(new SimpleWorkerClient<EditorSimpleWorkerImpl>(
|
||||
this._workerFactory,
|
||||
'vs/editor/common/services/editorSimpleWorker'
|
||||
));
|
||||
} catch (err) {
|
||||
logOnceWebWorkerWarning(err);
|
||||
this._worker = new SynchronousWorkerClient(new EditorSimpleWorkerImpl());
|
||||
}
|
||||
}
|
||||
return this._worker;
|
||||
}
|
||||
|
||||
protected _getProxy(): TPromise<EditorSimpleWorkerImpl> {
|
||||
return this._getOrCreateWorker().getProxyObject();
|
||||
return this._getOrCreateWorker().getProxyObject().then(null, (err) => {
|
||||
logOnceWebWorkerWarning(err);
|
||||
this._worker = new SynchronousWorkerClient(new EditorSimpleWorkerImpl());
|
||||
return this._getOrCreateWorker().getProxyObject();
|
||||
});
|
||||
}
|
||||
|
||||
private _getOrCreateModelManager(proxy: EditorSimpleWorkerImpl): EditorModelManager {
|
||||
|
||||
@@ -17,7 +17,6 @@ import URI from 'vs/base/common/uri';
|
||||
export function createMonacoBaseAPI(): typeof monaco {
|
||||
return {
|
||||
editor: undefined,
|
||||
worker: undefined,
|
||||
languages: undefined,
|
||||
CancellationTokenSource: CancellationTokenSource,
|
||||
Emitter: Emitter,
|
||||
|
||||
Vendored
+7
-5
@@ -4725,12 +4725,14 @@ declare module monaco.worker {
|
||||
export interface IMirrorModel {
|
||||
uri: Uri;
|
||||
version: number;
|
||||
getText(): string;
|
||||
getValue(): string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available mirror models in this worker.
|
||||
*/
|
||||
export function getMirrorModels(): IMirrorModel[];
|
||||
export interface IWorkerContext {
|
||||
/**
|
||||
* Get all available mirror models in this worker.
|
||||
*/
|
||||
getMirrorModels(): IMirrorModel[];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,7 +47,7 @@ export class MainThreadService extends abstractThreadService.AbstractThreadServi
|
||||
this._contextService = contextService;
|
||||
this._workerModuleId = workerModuleId;
|
||||
this._defaultWorkerCount = defaultWorkerCount;
|
||||
this._workerFactory = new DefaultWorkerFactory();
|
||||
this._workerFactory = new DefaultWorkerFactory(true);
|
||||
|
||||
if (!this.isInMainThread) {
|
||||
throw new Error('Incorrect Service usage: this service must be used only in the main thread');
|
||||
@@ -105,15 +105,11 @@ export class MainThreadService extends abstractThreadService.AbstractThreadServi
|
||||
});
|
||||
}
|
||||
|
||||
private _createWorker(): void {
|
||||
this._workerPool.push(this._doCreateWorker());
|
||||
}
|
||||
|
||||
private _shortName(major: string, minor: string): string {
|
||||
return major.substring(major.length - 14) + '.' + minor.substr(0, 14);
|
||||
}
|
||||
|
||||
private _doCreateWorker(): Worker.WorkerClient {
|
||||
private _createWorker(isRetry:boolean = false): void {
|
||||
let worker = new Worker.WorkerClient(
|
||||
this._workerFactory,
|
||||
this._workerModuleId,
|
||||
@@ -131,9 +127,22 @@ export class MainThreadService extends abstractThreadService.AbstractThreadServi
|
||||
configuration: this._contextService.getConfiguration(),
|
||||
options: this._contextService.getOptions()
|
||||
}
|
||||
}).then(null, (err) => {
|
||||
for (var i = 0; i < this._workerPool.length; i++) {
|
||||
if (this._workerPool[i] === worker) {
|
||||
this._workerPool.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
worker.dispose();
|
||||
if (isRetry) {
|
||||
console.warn('Creating the web worker already failed twice. Giving up!');
|
||||
} else {
|
||||
this._createWorker(true);
|
||||
}
|
||||
});
|
||||
|
||||
return worker;
|
||||
this._workerPool.push(worker);
|
||||
}
|
||||
|
||||
private _getWorkerIndex(obj: IThreadSynchronizableObject, affinity: ThreadAffinity): number {
|
||||
|
||||
Reference in New Issue
Block a user