提交 3b7f84d2 编写于 作者: A Alex Dima

There is precisely one compatibility web worker

上级 5ffd3f76
......@@ -7,9 +7,6 @@
import {globals} from 'vs/base/common/platform';
// Telemetry endpoint (used in the standalone editor) for hosts that want to collect editor telemetry
export const standaloneEditorTelemetryEndpoint: string = environment('telemetryEndpoint', null);
// Option for hosts to overwrite the worker script url (used in the standalone editor)
export const getCrossOriginWorkerScriptUrl: (workerId: string, label: string) => string = environment('getWorkerUrl', null);
......@@ -20,7 +17,3 @@ function environment(name: string, fallback: any = false): any {
return fallback;
}
export function workersCount(defaultCount: number): number {
return environment('workersCount', defaultCount);
}
......@@ -89,13 +89,10 @@ export class WorkerClient {
loaderConfiguration = (<any>window).requirejs.s.contexts._.config;
}
let MonacoEnvironment = (<any>window).MonacoEnvironment || null;
this.onModuleLoaded = this._sendMessage(workerProtocol.MessageType.INITIALIZE, {
id: this._worker.getId(),
moduleId: moduleId,
loaderConfiguration: loaderConfiguration,
MonacoEnvironment: MonacoEnvironment
loaderConfiguration: loaderConfiguration
});
this._remoteCom = new workerProtocol.RemoteCom(this);
......@@ -105,10 +102,6 @@ export class WorkerClient {
return this._remoteCom;
}
public getQueueSize(): number {
return this._messagesQueue.length + (this._waitingForWorkerReply ? 1 : 0);
}
public request(requestName:string, payload:any, forceTimestamp?:number): TPromise<any> {
if (requestName.charAt(0) === '$') {
......
......@@ -185,11 +185,6 @@ export class WorkerServer {
(<any>self).require.config(loaderConfig);
}
var MonacoEnvironment = msg.payload.MonacoEnvironment;
if (MonacoEnvironment) {
(<any>self).MonacoEnvironment = MonacoEnvironment;
}
this.loadModule(msg.payload.moduleId, (handlerModule:any) => {
this._requestHandler = handlerModule.value;
c();
......
......@@ -6,8 +6,8 @@
(function () {
'use strict';
var MonacoEnvironment = (<any>self).MonacoEnvironment;
var monacoBaseUrl = MonacoEnvironment && MonacoEnvironment.baseUrl ? MonacoEnvironment.baseUrl : '../../../';
let MonacoEnvironment = (<any>self).MonacoEnvironment;
let monacoBaseUrl = MonacoEnvironment && MonacoEnvironment.baseUrl ? MonacoEnvironment.baseUrl : '../../../';
importScripts(monacoBaseUrl + 'vs/loader.js');
......@@ -16,9 +16,9 @@
catchError: true
});
var loadCode = function(moduleId) {
let loadCode = function(moduleId) {
require([moduleId], function(ws) {
var messageHandler = ws.create((msg:any) => {
let messageHandler = ws.create((msg:any) => {
(<any>self).postMessage(msg);
}, null);
......@@ -29,8 +29,8 @@
});
};
var isFirstMessage = true;
var beforeReadyMessages:MessageEvent[] = [];
let isFirstMessage = true;
let beforeReadyMessages:MessageEvent[] = [];
self.onmessage = (message) => {
if (!isFirstMessage) {
beforeReadyMessages.push(message);
......
......@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as flags from 'vs/base/common/flags';
import {IDisposable} from 'vs/base/common/lifecycle';
import URI from 'vs/base/common/uri';
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
......@@ -237,12 +236,7 @@ export function getOrCreateStaticServices(services?: IEditorOverrideServices): I
let eventService = services.eventService || new EventService();
let configurationService = services.configurationService || new SimpleConfigurationService(contextService, eventService);
// warn the user that standaloneEdiktorTelemetryEndpint is absolete
if (flags.standaloneEditorTelemetryEndpoint) {
console.warn('standaloneEditorTelemetryEndpoint is obsolete');
}
let threadService = services.threadService || new MainThreadService(contextService, 'vs/editor/common/worker/editorWorkerServer', 1);
let threadService = services.threadService || new MainThreadService(contextService, 'vs/editor/common/worker/editorWorkerServer');
let messageService = services.messageService || new SimpleMessageService();
let extensionService = services.extensionService || new SimpleExtensionService();
let markerService = services.markerService || new MainProcessMarkerService(threadService);
......
......@@ -16,7 +16,7 @@ import {IFilesConfiguration} from 'vs/platform/files/common/files';
import {createAsyncDescriptor1} from 'vs/platform/instantiation/common/descriptors';
import {IExtensionService} from 'vs/platform/extensions/common/extensions';
import {IExtensionPointUser, IExtensionMessageCollector, ExtensionsRegistry} from 'vs/platform/extensions/common/extensionsRegistry';
import {IThreadService, Remotable, ThreadAffinity} from 'vs/platform/thread/common/thread';
import {IThreadService, Remotable} from 'vs/platform/thread/common/thread';
import * as modes from 'vs/editor/common/modes';
import {FrankensteinMode} from 'vs/editor/common/modes/abstractMode';
import {ILegacyLanguageDefinition, ModesRegistry} from 'vs/editor/common/modes/modesRegistry';
......@@ -626,7 +626,7 @@ export interface IWorkerInitData {
languages: ILanguageExtensionPoint[];
}
@Remotable.WorkerContext('ModeServiceWorkerHelper', ThreadAffinity.All)
@Remotable.WorkerContext('ModeServiceWorkerHelper')
export class ModeServiceWorkerHelper {
private _modeService:IModeService;
......
......@@ -15,7 +15,7 @@ import URI from 'vs/base/common/uri';
import {TPromise} from 'vs/base/common/winjs.base';
import {IMarker, IMarkerService} from 'vs/platform/markers/common/markers';
import {anonymize} from 'vs/platform/telemetry/common/telemetry';
import {IThreadService, Remotable, ThreadAffinity} from 'vs/platform/thread/common/thread';
import {IThreadService, Remotable} from 'vs/platform/thread/common/thread';
import {Range} from 'vs/editor/common/core/range';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {IMirrorModelEvents, MirrorModel} from 'vs/editor/common/model/mirrorModel';
......@@ -562,7 +562,7 @@ export class ModelServiceImpl implements IModelService {
}
}
@Remotable.WorkerContext('ModelServiceWorkerHelper', ThreadAffinity.All)
@Remotable.WorkerContext('ModelServiceWorkerHelper')
export class ModelServiceWorkerHelper {
private _resourceService: IResourceService;
......
......@@ -11,7 +11,7 @@ import modes = require('vs/editor/common/modes');
import htmlWorker = require('vs/languages/html/common/htmlWorker');
import { AbstractMode, createWordRegExp, ModeWorkerManager } from 'vs/editor/common/modes/abstractMode';
import { AbstractState } from 'vs/editor/common/modes/abstractState';
import {OneWorkerAttr, AllWorkersAttr} from 'vs/platform/thread/common/threadService';
import {CompatWorkerAttr} from 'vs/platform/thread/common/threadService';
import {IModeService} from 'vs/editor/common/services/modeService';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import * as htmlTokenTypes from 'vs/languages/html/common/htmlTokenTypes';
......@@ -465,27 +465,27 @@ export class HTMLMode<W extends htmlWorker.HTMLWorker> extends AbstractMode impl
}
}
static $_configureWorkers = AllWorkersAttr(HTMLMode, HTMLMode.prototype._configureWorkers);
static $_configureWorkers = CompatWorkerAttr(HTMLMode, HTMLMode.prototype._configureWorkers);
private _configureWorkers(options:any): winjs.TPromise<void> {
return this._worker((w) => w._doConfigure(options));
}
static $_provideLinks = OneWorkerAttr(HTMLMode, HTMLMode.prototype._provideLinks);
static $_provideLinks = CompatWorkerAttr(HTMLMode, HTMLMode.prototype._provideLinks);
protected _provideLinks(resource:URI):winjs.TPromise<modes.ILink[]> {
return this._worker((w) => w.provideLinks(resource));
}
static $_provideDocumentRangeFormattingEdits = OneWorkerAttr(HTMLMode, HTMLMode.prototype._provideDocumentRangeFormattingEdits);
static $_provideDocumentRangeFormattingEdits = CompatWorkerAttr(HTMLMode, HTMLMode.prototype._provideDocumentRangeFormattingEdits);
private _provideDocumentRangeFormattingEdits(resource:URI, range:editorCommon.IRange, options:modes.FormattingOptions):winjs.TPromise<editorCommon.ISingleEditOperation[]> {
return this._worker((w) => w.provideDocumentRangeFormattingEdits(resource, range, options));
}
static $_provideDocumentHighlights = OneWorkerAttr(HTMLMode, HTMLMode.prototype._provideDocumentHighlights);
static $_provideDocumentHighlights = CompatWorkerAttr(HTMLMode, HTMLMode.prototype._provideDocumentHighlights);
protected _provideDocumentHighlights(resource:URI, position:editorCommon.IPosition, strict:boolean = false): winjs.TPromise<modes.DocumentHighlight[]> {
return this._worker((w) => w.provideDocumentHighlights(resource, position, strict));
}
static $_provideCompletionItems = OneWorkerAttr(HTMLMode, HTMLMode.prototype._provideCompletionItems);
static $_provideCompletionItems = CompatWorkerAttr(HTMLMode, HTMLMode.prototype._provideCompletionItems);
protected _provideCompletionItems(resource:URI, position:editorCommon.IPosition):winjs.TPromise<modes.ISuggestResult[]> {
return this._worker((w) => w.provideCompletionItems(resource, position));
}
......
......@@ -12,8 +12,8 @@ import Platform = require('vs/platform/platform');
import jsonWorker = require('vs/languages/json/common/jsonWorker');
import tokenization = require('vs/languages/json/common/features/tokenization');
import {AbstractMode, createWordRegExp, ModeWorkerManager} from 'vs/editor/common/modes/abstractMode';
import {OneWorkerAttr, AllWorkersAttr} from 'vs/platform/thread/common/threadService';
import {IThreadService, ThreadAffinity} from 'vs/platform/thread/common/thread';
import {CompatWorkerAttr} from 'vs/platform/thread/common/threadService';
import {IThreadService} from 'vs/platform/thread/common/thread';
import {IJSONContributionRegistry, Extensions, ISchemaContributions} from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {LanguageConfigurationRegistry, LanguageConfiguration} from 'vs/editor/common/modes/languageConfigurationRegistry';
......@@ -101,9 +101,6 @@ export class JSONMode extends AbstractMode {
public creationDone(): void {
if (this._threadService.isInMainThread) {
// Pick a worker to do validation
this._pickAWorkerToValidate();
// Configure all workers
this._configureWorkerSchemas(this.getSchemaConfiguration());
var contributionRegistry = <IJSONContributionRegistry> Platform.Registry.as(Extensions.JSONContribution);
......@@ -130,47 +127,42 @@ export class JSONMode extends AbstractMode {
}
}
static $_configureWorkers = AllWorkersAttr(JSONMode, JSONMode.prototype._configureWorkers);
static $_configureWorkers = CompatWorkerAttr(JSONMode, JSONMode.prototype._configureWorkers);
private _configureWorkers(options:any): WinJS.TPromise<void> {
return this._worker((w) => w._doConfigure(options));
}
static $_configureWorkerSchemas = AllWorkersAttr(JSONMode, JSONMode.prototype._configureWorkerSchemas);
static $_configureWorkerSchemas = CompatWorkerAttr(JSONMode, JSONMode.prototype._configureWorkerSchemas);
private _configureWorkerSchemas(data:ISchemaContributions): WinJS.TPromise<boolean> {
return this._worker((w) => w.setSchemaContributions(data));
}
static $_pickAWorkerToValidate = OneWorkerAttr(JSONMode, JSONMode.prototype._pickAWorkerToValidate, ThreadAffinity.Group1);
private _pickAWorkerToValidate(): WinJS.TPromise<void> {
return this._worker((w) => w.enableValidator());
}
static $navigateValueSet = OneWorkerAttr(JSONMode, JSONMode.prototype.navigateValueSet);
static $navigateValueSet = CompatWorkerAttr(JSONMode, JSONMode.prototype.navigateValueSet);
public navigateValueSet(resource:URI, position:editorCommon.IRange, up:boolean):WinJS.TPromise<modes.IInplaceReplaceSupportResult> {
return this._worker((w) => w.navigateValueSet(resource, position, up));
}
static $_provideCompletionItems = OneWorkerAttr(JSONMode, JSONMode.prototype._provideCompletionItems);
static $_provideCompletionItems = CompatWorkerAttr(JSONMode, JSONMode.prototype._provideCompletionItems);
private _provideCompletionItems(resource:URI, position:editorCommon.IPosition):WinJS.TPromise<modes.ISuggestResult[]> {
return this._worker((w) => w.provideCompletionItems(resource, position));
}
static $_provideHover = OneWorkerAttr(JSONMode, JSONMode.prototype._provideHover);
static $_provideHover = CompatWorkerAttr(JSONMode, JSONMode.prototype._provideHover);
private _provideHover(resource:URI, position:editorCommon.IPosition): WinJS.TPromise<modes.Hover> {
return this._worker((w) => w.provideHover(resource, position));
}
static $_provideDocumentSymbols = OneWorkerAttr(JSONMode, JSONMode.prototype._provideDocumentSymbols);
static $_provideDocumentSymbols = CompatWorkerAttr(JSONMode, JSONMode.prototype._provideDocumentSymbols);
private _provideDocumentSymbols(resource:URI):WinJS.TPromise<modes.SymbolInformation[]> {
return this._worker((w) => w.provideDocumentSymbols(resource));
}
static $_provideDocumentFormattingEdits = OneWorkerAttr(JSONMode, JSONMode.prototype._provideDocumentFormattingEdits);
static $_provideDocumentFormattingEdits = CompatWorkerAttr(JSONMode, JSONMode.prototype._provideDocumentFormattingEdits);
public _provideDocumentFormattingEdits(resource:URI, options:modes.FormattingOptions):WinJS.TPromise<editorCommon.ISingleEditOperation[]> {
return this._worker((w) => w.format(resource, null, options));
}
static $_provideDocumentRangeFormattingEdits = OneWorkerAttr(JSONMode, JSONMode.prototype._provideDocumentRangeFormattingEdits);
static $_provideDocumentRangeFormattingEdits = CompatWorkerAttr(JSONMode, JSONMode.prototype._provideDocumentRangeFormattingEdits);
public _provideDocumentRangeFormattingEdits(resource:URI, range:editorCommon.IRange, options:modes.FormattingOptions):WinJS.TPromise<editorCommon.ISingleEditOperation[]> {
return this._worker((w) => w.format(resource, range, options));
}
......
......@@ -98,6 +98,9 @@ export class JSONWorker {
this._modeId,
(toValidate) => this.doValidate(toValidate)
);
if (markerService) {
this._validationHelper.enable();
}
this.requestService = requestService;
this.contextService = contextService;
......@@ -204,11 +207,6 @@ export class JSONWorker {
return WinJS.TPromise.as(true);
}
public enableValidator(): WinJS.TPromise<void> {
this._validationHelper.enable();
return WinJS.TPromise.as(null);
}
public doValidate(resources: URI[]):void {
for (var i = 0; i < resources.length; i++) {
this.doValidate1(resources[i]);
......
......@@ -4,12 +4,12 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import winjs = require('vs/base/common/winjs.base');
import {TPromise} from 'vs/base/common/winjs.base';
import abstractThreadService = require('vs/platform/thread/common/abstractThreadService');
import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService';
import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection';
import {SyncDescriptor0} from 'vs/platform/instantiation/common/descriptors';
import {IThreadService, IThreadSynchronizableObject, ThreadAffinity} from 'vs/platform/thread/common/thread';
import {IThreadService, IThreadSynchronizableObject} from 'vs/platform/thread/common/thread';
export class NullThreadService extends abstractThreadService.AbstractThreadService implements IThreadService {
public serviceId = IThreadService;
......@@ -23,15 +23,10 @@ export class NullThreadService extends abstractThreadService.AbstractThreadServi
return super._doCreateInstance(params);
}
OneWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[], affinity: ThreadAffinity): winjs.Promise {
return winjs.TPromise.as(null);
CompatWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[]): TPromise<any> {
return TPromise.as(null);
}
AllWorkers(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[]): winjs.Promise {
return winjs.TPromise.as(null);
}
protected _registerAndInstantiateMainProcessActor<T>(id: string, descriptor: SyncDescriptor0<T>): T {
return this._getOrCreateLocalInstance(id, descriptor);
}
......@@ -48,10 +43,10 @@ export class NullThreadService extends abstractThreadService.AbstractThreadServi
throw new Error('Not supported in this runtime context!');
}
protected _registerAndInstantiateWorkerActor<T>(id: string, descriptor: SyncDescriptor0<T>, whichWorker: ThreadAffinity): T {
protected _registerAndInstantiateWorkerActor<T>(id: string, descriptor: SyncDescriptor0<T>): T {
return this._getOrCreateProxyInstance({
callOnRemote: (proxyId: string, path: string, args: any[]): winjs.Promise => {
return winjs.TPromise.as(null);
callOnRemote: (proxyId: string, path: string, args: any[]): TPromise<any> => {
return TPromise.as(null);
}
}, id, descriptor);
}
......
......@@ -6,7 +6,7 @@
import {TPromise} from 'vs/base/common/winjs.base';
import remote = require('vs/base/common/remote');
import {ThreadAffinity, Remotable, IThreadSynchronizableObject} from 'vs/platform/thread/common/thread';
import {Remotable, IThreadSynchronizableObject} from 'vs/platform/thread/common/thread';
import {THREAD_SERVICE_PROPERTY_NAME} from 'vs/platform/thread/common/threadService';
import instantiation = require('vs/platform/instantiation/common/instantiation');
import {SyncDescriptor0, createSyncDescriptor, AsyncDescriptor1} from 'vs/platform/instantiation/common/descriptors';
......@@ -101,6 +101,7 @@ export abstract class AbstractThreadService implements remote.IManyHandler {
}
protected _getOrCreateProxyInstance(remoteCom: remote.IProxyHelper, id: string, descriptor: SyncDescriptor0<any>): any {
// console.log(`_getOrCreateProxyInstance: ${id}, ${descriptor}`);
if (this._proxyObjMap[id]) {
return this._proxyObjMap[id];
}
......@@ -139,7 +140,7 @@ export abstract class AbstractThreadService implements remote.IManyHandler {
}
if (Remotable.Registry.WorkerContext[id]) {
return this._registerAndInstantiateWorkerActor(id, desc, Remotable.Registry.WorkerContext[id].affinity);
return this._registerAndInstantiateWorkerActor(id, desc);
}
throw new Error('Unknown Remotable: <<' + id + '>>');
......@@ -170,7 +171,7 @@ export abstract class AbstractThreadService implements remote.IManyHandler {
protected abstract _registerMainProcessActor<T>(id: string, actor: T): void;
protected abstract _registerAndInstantiateExtHostActor<T>(id: string, descriptor: SyncDescriptor0<T>): T;
protected abstract _registerExtHostActor<T>(id: string, actor: T): void;
protected abstract _registerAndInstantiateWorkerActor<T>(id: string, descriptor: SyncDescriptor0<T>, whichWorker: ThreadAffinity): T;
protected abstract _registerAndInstantiateWorkerActor<T>(id: string, descriptor: SyncDescriptor0<T>): T;
protected abstract _registerWorkerActor<T>(id: string, actor: T): void;
}
......
......@@ -9,7 +9,7 @@ import remote = require('vs/base/common/remote');
import descriptors = require('vs/platform/instantiation/common/descriptors');
import abstractThreadService = require('./abstractThreadService');
import {IThreadService, IThreadSynchronizableObject, ThreadAffinity} from 'vs/platform/thread/common/thread';
import {IThreadService, IThreadSynchronizableObject} from 'vs/platform/thread/common/thread';
export class ExtHostThreadService extends abstractThreadService.AbstractThreadService implements IThreadService {
public serviceId = IThreadService;
......@@ -21,11 +21,7 @@ export class ExtHostThreadService extends abstractThreadService.AbstractThreadSe
this._remoteCom.setManyHandler(this);
}
OneWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[], affinity: ThreadAffinity): TPromise<any> {
return TPromise.as(null);
}
AllWorkers(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[]): TPromise<any> {
CompatWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[]): TPromise<any> {
return TPromise.as(null);
}
......@@ -45,7 +41,7 @@ export class ExtHostThreadService extends abstractThreadService.AbstractThreadSe
this._registerLocalInstance(id, actor);
}
protected _registerAndInstantiateWorkerActor<T>(id: string, descriptor: descriptors.SyncDescriptor0<T>, whichWorker: ThreadAffinity): T {
protected _registerAndInstantiateWorkerActor<T>(id: string, descriptor: descriptors.SyncDescriptor0<T>): T {
throw new Error('Not supported in this runtime context! Cannot communicate directly from Extension Host to Worker!');
}
......
......@@ -7,18 +7,12 @@
import {TPromise} from 'vs/base/common/winjs.base';
import Worker = require('vs/base/common/worker/workerClient');
import abstractThreadService = require('vs/platform/thread/common/abstractThreadService');
import Env = require('vs/base/common/flags');
import Platform = require('vs/base/common/platform');
import remote = require('vs/base/common/remote');
import {SyncDescriptor0} from 'vs/platform/instantiation/common/descriptors';
import {IThreadService, IThreadSynchronizableObject, ThreadAffinity} from 'vs/platform/thread/common/thread';
import {IThreadService, IThreadSynchronizableObject} from 'vs/platform/thread/common/thread';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {DefaultWorkerFactory} from 'vs/base/worker/defaultWorkerFactory';
interface IAffinityMap {
[qualifiedMethodName: string]: number;
}
export interface IWorker {
getRemoteCom(): remote.IRemoteCom;
}
......@@ -31,32 +25,28 @@ export class MainThreadService extends abstractThreadService.AbstractThreadServi
public serviceId = IThreadService;
static MAXIMUM_WORKER_CREATION_DELAY = 500; // 500ms
private _workerPool: Worker.WorkerClient[];
private _worker: Worker.WorkerClient;
private _contextService: IWorkspaceContextService;
private _affinityScrambler: IAffinityMap;
private _workersCreatedPromise: TPromise<void>;
private _workerCreatedPromise: TPromise<void>;
private _triggerWorkersCreatedPromise: (value: void) => void;
private _workerFactory: Worker.IWorkerFactory;
private _workerModuleId: string;
private _defaultWorkerCount: number;
constructor(contextService: IWorkspaceContextService, workerModuleId: string, defaultWorkerCount: number) {
constructor(contextService: IWorkspaceContextService, workerModuleId: string) {
super(true);
this._contextService = contextService;
this._workerModuleId = workerModuleId;
this._defaultWorkerCount = defaultWorkerCount;
this._workerFactory = new DefaultWorkerFactory(true);
if (!this.isInMainThread) {
throw new Error('Incorrect Service usage: this service must be used only in the main thread');
}
this._workerPool = [];
this._affinityScrambler = {};
this._worker = null;
this._workersCreatedPromise = new TPromise<void>((c, e, p) => {
this._workerCreatedPromise = new TPromise<void>((c, e, p) => {
this._triggerWorkersCreatedPromise = c;
}, () => {
// Not cancelable
......@@ -70,15 +60,7 @@ export class MainThreadService extends abstractThreadService.AbstractThreadServi
if (this._triggerWorkersCreatedPromise) {
// Workers not created yet
let createCount = Env.workersCount(this._defaultWorkerCount);
if (!Platform.hasWebWorkerSupport()) {
// Create at most 1 compatibility worker
createCount = Math.min(createCount, 1);
}
for (let i = 0; i < createCount; i++) {
this._createWorker();
}
this._createWorker();
let complete = this._triggerWorkersCreatedPromise;
this._triggerWorkersCreatedPromise = null;
......@@ -93,7 +75,7 @@ export class MainThreadService extends abstractThreadService.AbstractThreadServi
// hide the initialize promise inside this
// promise so that it won't be canceled by accident
this._workersCreatedPromise.then(() => {
this._workerCreatedPromise.then(() => {
if (!shouldCancelPromise) {
c(null);
}
......@@ -110,7 +92,7 @@ export class MainThreadService extends abstractThreadService.AbstractThreadServi
}
private _createWorker(isRetry:boolean = false): void {
let worker = new Worker.WorkerClient(
this._worker = new Worker.WorkerClient(
this._workerFactory,
this._workerModuleId,
(msg) => {
......@@ -120,77 +102,31 @@ export class MainThreadService extends abstractThreadService.AbstractThreadServi
return msg.type;
}
);
worker.getRemoteCom().setManyHandler(this);
worker.onModuleLoaded = worker.request('initialize', {
this._worker.getRemoteCom().setManyHandler(this);
this._worker.onModuleLoaded = this._worker.request('initialize', {
contextService: {
workspace: this._contextService.getWorkspace(),
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();
this._worker.dispose();
this._worker = null;
if (isRetry) {
console.warn('Creating the web worker already failed twice. Giving up!');
} else {
this._createWorker(true);
}
});
this._workerPool.push(worker);
}
private _getWorkerIndex(obj: IThreadSynchronizableObject, affinity: ThreadAffinity): number {
if (affinity === ThreadAffinity.None) {
let winners: number[] = [0],
winnersQueueSize = this._workerPool[0].getQueueSize();
for (let i = 1; i < this._workerPool.length; i++) {
let queueSize = this._workerPool[i].getQueueSize();
if (queueSize < winnersQueueSize) {
winnersQueueSize = queueSize;
winners = [i];
} else if (queueSize === winnersQueueSize) {
winners.push(i);
}
}
return winners[Math.floor(Math.random() * winners.length)];
}
let scramble = 0;
if (this._affinityScrambler.hasOwnProperty(obj.getId())) {
scramble = this._affinityScrambler[obj.getId()];
} else {
scramble = Math.floor(Math.random() * this._workerPool.length);
this._affinityScrambler[obj.getId()] = scramble;
}
return (scramble + affinity) % this._workerPool.length;
}
OneWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[], affinity: ThreadAffinity): TPromise<any> {
CompatWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[]): TPromise<any> {
return this._afterWorkers().then(() => {
if (this._workerPool.length === 0) {
if (this._worker === null) {
throw new Error('Cannot fulfill request...');
}
let workerIdx = this._getWorkerIndex(obj, affinity);
return this._remoteCall(this._workerPool[workerIdx], obj, methodName, params);
});
}
AllWorkers(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[]): TPromise<any> {
return this._afterWorkers().then(() => {
return TPromise.join(this._workerPool.map((w) => {
return this._remoteCall(w, obj, methodName, params);
}));
return this._remoteCall(this._worker, obj, methodName, params);
});
}
......@@ -218,8 +154,12 @@ export class MainThreadService extends abstractThreadService.AbstractThreadServi
throw new Error('Not supported in this runtime context!');
}
protected _registerAndInstantiateWorkerActor<T>(id: string, descriptor: SyncDescriptor0<T>, whichWorker: ThreadAffinity): T {
let helper = this._createWorkerProxyHelper(whichWorker);
protected _registerAndInstantiateWorkerActor<T>(id: string, descriptor: SyncDescriptor0<T>): T {
let helper:remote.IProxyHelper = {
callOnRemote: (proxyId: string, path: string, args: any[]): TPromise<any> => {
return this._callOnWorker(proxyId, path, args);
}
};
return this._getOrCreateProxyInstance(helper, id, descriptor);
}
......@@ -227,28 +167,12 @@ export class MainThreadService extends abstractThreadService.AbstractThreadServi
throw new Error('Not supported in this runtime context!');
}
private _createWorkerProxyHelper(whichWorker: ThreadAffinity): remote.IProxyHelper {
return {
callOnRemote: (proxyId: string, path: string, args: any[]): TPromise<any> => {
return this._callOnWorker(whichWorker, proxyId, path, args);
}
};
}
private _callOnWorker(whichWorker: ThreadAffinity, proxyId: string, path: string, args: any[]): TPromise<any> {
if (whichWorker === ThreadAffinity.None) {
return TPromise.as(null);
}
private _callOnWorker(proxyId: string, path: string, args: any[]): TPromise<any> {
return this._afterWorkers().then(() => {
if (whichWorker === ThreadAffinity.All) {
let promises = this._workerPool.map(w => w.getRemoteCom()).map(rCom => rCom.callOnRemote(proxyId, path, args));
return TPromise.join(promises);
if (this._worker === null) {
throw new Error('Cannot fulfill request...');
}
let workerIdx = whichWorker % this._workerPool.length;
let worker = this._workerPool[workerIdx];
return worker.getRemoteCom().callOnRemote(proxyId, path, args);
return this._worker.getRemoteCom().callOnRemote(proxyId, path, args);
});
}
}
\ No newline at end of file
......@@ -18,8 +18,7 @@ export interface IThreadService {
// --- BEGIN deprecated methods
isInMainThread: boolean;
OneWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, param: any[], affinity: ThreadAffinity): TPromise<any>;
AllWorkers(obj: IThreadSynchronizableObject, methodName: string, target: Function, param: any[]): TPromise<any>;
CompatWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, param: any[]): TPromise<any>;
createInstance<A1, T extends IThreadSynchronizableObject>(ctor: instantiation.IConstructorSignature1<A1, T>, a1: A1): T;
createInstance<A1, T extends IThreadSynchronizableObject>(descriptor: descriptors.AsyncDescriptor1<A1, T>, a1: A1): TPromise<T>;
......@@ -35,13 +34,6 @@ export class IRemotableCtorMap {
[identifier: string]: Function;
}
export class IRemotableCtorAffinityMap {
[identifier: string]: {
ctor: Function;
affinity: ThreadAffinity;
};
}
export class Remotable {
private static PROP_NAME = '$__REMOTABLE_ID';
......@@ -49,7 +41,7 @@ export class Remotable {
public static Registry = {
MainContext: <IRemotableCtorMap>Object.create(null),
ExtHostContext: <IRemotableCtorMap>Object.create(null),
WorkerContext: <IRemotableCtorAffinityMap>Object.create(null),
WorkerContext: <IRemotableCtorMap>Object.create(null),
};
public static getId(ctor: any): string {
......@@ -72,13 +64,10 @@ export class Remotable {
};
}
public static WorkerContext(identifier: string, whichWorker: ThreadAffinity) {
public static WorkerContext(identifier: string) {
return function(target: Function) {
Remotable._ensureUnique(identifier);
Remotable.Registry.WorkerContext[identifier] = {
ctor: target,
affinity: whichWorker
};
Remotable.Registry.WorkerContext[identifier] = target;
target[Remotable.PROP_NAME] = identifier;
};
}
......@@ -97,17 +86,3 @@ export interface IThreadSynchronizableObject {
asyncCtor?: () => TPromise<void>;
}
export enum ThreadAffinity {
None = 0,
Group1 = 1,
Group2 = 2,
Group3 = 3,
Group4 = 4,
Group5 = 5,
Group6 = 6,
Group7 = 7,
Group8 = 8,
Group9 = 9,
All = 10
}
......@@ -4,8 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import {TPromise} from 'vs/base/common/winjs.base';
import thread = require('./thread');
import {IThreadService} from './thread';
export const THREAD_SERVICE_PROPERTY_NAME = '__$$__threadService';
......@@ -18,58 +17,17 @@ function findMember(proto: any, target: any): string {
throw new Error('Member not found in prototype');
}
function findThreadService(obj: any): thread.IThreadService {
let threadService: thread.IThreadService = obj[THREAD_SERVICE_PROPERTY_NAME];
function findThreadService(obj: any): IThreadService {
let threadService: IThreadService = obj[THREAD_SERVICE_PROPERTY_NAME];
if (!threadService) {
throw new Error('Objects that use thread attributes must be instantiated with the thread service');
}
return threadService;
}
export interface IOneWorkerAnnotation {
(type: Function, target: Function, affinity?: thread.ThreadAffinity): void;
(type: Function, target: Function, condition: () => TPromise<any>, affinity?: thread.ThreadAffinity): void;
}
function OneWorkerFn(type: Function, target: Function, conditionOrAffinity?: any, affinity: thread.ThreadAffinity = thread.ThreadAffinity.None): void {
let methodName = findMember(type.prototype, target),
condition: () => TPromise<any>;
if (typeof conditionOrAffinity === 'function') {
condition = conditionOrAffinity;
} else if (typeof conditionOrAffinity !== 'undefined') {
affinity = conditionOrAffinity;
}
type.prototype[methodName] = function(...param: any[]) {
if (!condition) {
return findThreadService(this).OneWorker(this, methodName, target, param, affinity);
} else {
let that = this,
promise = condition.call(that);
if (!TPromise.is(promise)) {
promise = TPromise.as(promise);
}
return promise.then(function() {
return findThreadService(that).OneWorker(that, methodName, target, param, affinity);
});
}
};
}
export let OneWorkerAttr: IOneWorkerAnnotation = OneWorkerFn;
export function AllWorkersAttr(type: Function, target: Function): void {
export function CompatWorkerAttr(type: Function, target: Function): void {
let methodName = findMember(type.prototype, target);
type.prototype[methodName] = function(...param: any[]) {
return findThreadService(this).AllWorkers(this, methodName, target, param);
return findThreadService(this).CompatWorker(this, methodName, target, param);
};
}
......@@ -8,7 +8,7 @@ import {TPromise} from 'vs/base/common/winjs.base';
import abstractThreadService = require('vs/platform/thread/common/abstractThreadService');
import remote = require('vs/base/common/remote');
import {SyncDescriptor0} from 'vs/platform/instantiation/common/descriptors';
import {IThreadService, IThreadSynchronizableObject, ThreadAffinity} from 'vs/platform/thread/common/thread';
import {IThreadService, IThreadSynchronizableObject} from 'vs/platform/thread/common/thread';
export class WorkerThreadService extends abstractThreadService.AbstractThreadService implements IThreadService {
public serviceId = IThreadService;
......@@ -48,11 +48,7 @@ export class WorkerThreadService extends abstractThreadService.AbstractThreadSer
}
}
OneWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[], affinity: ThreadAffinity): TPromise<any> {
return target.apply(obj, params);
}
AllWorkers(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[]): TPromise<any> {
CompatWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[]): TPromise<any> {
return target.apply(obj, params);
}
......@@ -72,7 +68,7 @@ export class WorkerThreadService extends abstractThreadService.AbstractThreadSer
throw new Error('Not supported in this runtime context!');
}
protected _registerAndInstantiateWorkerActor<T>(id: string, descriptor: SyncDescriptor0<T>, whichWorker: ThreadAffinity): T {
protected _registerAndInstantiateWorkerActor<T>(id: string, descriptor: SyncDescriptor0<T>): T {
return this._getOrCreateLocalInstance(id, descriptor);
}
......
......@@ -9,8 +9,8 @@ import {IInstantiationService} from 'vs/platform/instantiation/common/instantiat
import {IModelService} from 'vs/editor/common/services/modelService';
import {IModeService} from 'vs/editor/common/services/modeService';
import {OutputWorker} from 'vs/workbench/parts/output/common/outputWorker';
import winjs = require('vs/base/common/winjs.base');
import {OneWorkerAttr} from 'vs/platform/thread/common/threadService';
import {TPromise} from 'vs/base/common/winjs.base';
import {CompatWorkerAttr} from 'vs/platform/thread/common/threadService';
import URI from 'vs/base/common/uri';
import * as modes from 'vs/editor/common/modes';
import {IEditorWorkerService} from 'vs/editor/common/services/editorWorkerService';
......@@ -38,12 +38,12 @@ export class OutputMode extends AbstractMode {
});
}
private _worker<T>(runner: (worker: OutputWorker) => winjs.TPromise<T>): winjs.TPromise<T> {
private _worker<T>(runner: (worker: OutputWorker) => TPromise<T>): TPromise<T> {
return this._modeWorkerManager.worker(runner);
}
static $_provideLinks = OneWorkerAttr(OutputMode, OutputMode.prototype._provideLinks);
private _provideLinks(resource: URI): winjs.TPromise<modes.ILink[]> {
static $_provideLinks = CompatWorkerAttr(OutputMode, OutputMode.prototype._provideLinks);
private _provideLinks(resource: URI): TPromise<modes.ILink[]> {
return this._worker((w) => w.provideLinks(resource));
}
}
\ No newline at end of file
......@@ -47,7 +47,7 @@ export class MainThreadService extends CommonMainThreadService {
@IWindowService windowService: IWindowService,
@ILifecycleService lifecycleService: ILifecycleService
) {
super(contextService, 'vs/editor/common/worker/editorWorkerServer', 1);
super(contextService, 'vs/editor/common/worker/editorWorkerServer');
this.extensionHostProcessManager = new ExtensionHostProcessManager(contextService, messageService, windowService, lifecycleService);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册