提交 a25cfe1d 编写于 作者: A Alex Dima

Simplify IThreadService now that ICompatWorkerService is used

上级 356eaa5f
......@@ -23,7 +23,6 @@ import 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import 'vs/platform/request/common/request';
import 'vs/platform/workspace/common/workspace';
import 'vs/platform/telemetry/common/telemetry';
import 'vs/platform/thread/common/thread';
// editor common
import 'vs/editor/common/editorCommon';
......
......@@ -46,13 +46,3 @@ export function CompatWorkerAttr(type: Function, target: Function): void {
return obj.compatWorkerService.CompatWorker(obj, methodName, target, param);
};
}
// export class NullCompatWorkerService implements ICompatWorkerService {
// public serviceId = ICompatWorkerService;
// public isInMainThread = true;
// constructor() {}
// registerCompatMode(compatMode:ICompatMode): void {}
// }
// export const NULL_COMPAT_WORKER_SERVICE = new NullCompatWorkerService();
......@@ -4,29 +4,20 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
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} from 'vs/platform/thread/common/thread';
import {IThreadService} from 'vs/platform/thread/common/thread';
export class NullThreadService extends abstractThreadService.AbstractThreadService implements IThreadService {
public serviceId = IThreadService;
constructor() {
super(true);
super();
this.setInstantiationService(new InstantiationService(new ServiceCollection([IThreadService, this])));
}
protected _doCreateInstance(params: any[]): any {
return super._doCreateInstance(params);
}
CompatWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[]): TPromise<any> {
return TPromise.as(null);
}
protected _registerAndInstantiateMainProcessActor<T>(id: string, descriptor: SyncDescriptor0<T>): T {
return this._getOrCreateLocalInstance(id, descriptor);
}
......@@ -42,18 +33,6 @@ export class NullThreadService extends abstractThreadService.AbstractThreadServi
protected _registerExtHostActor<T>(id: string, actor: T): void {
throw new Error('Not supported in this runtime context!');
}
protected _registerAndInstantiateWorkerActor<T>(id: string, descriptor: SyncDescriptor0<T>): T {
return this._getOrCreateProxyInstance({
callOnRemote: (proxyId: string, path: string, args: any[]): TPromise<any> => {
return TPromise.as(null);
}
}, id, descriptor);
}
protected _registerWorkerActor<T>(id: string, actor: T): void {
throw new Error('Not supported in this runtime context!');
}
}
export const NULL_THREAD_SERVICE = new NullThreadService();
\ No newline at end of file
......@@ -6,26 +6,18 @@
import {TPromise} from 'vs/base/common/winjs.base';
import remote = require('vs/base/common/remote');
import {Remotable, IThreadSynchronizableObject} from 'vs/platform/thread/common/thread';
import {THREAD_SERVICE_PROPERTY_NAME} from 'vs/platform/thread/common/threadService';
import {Remotable} from 'vs/platform/thread/common/thread';
import instantiation = require('vs/platform/instantiation/common/instantiation');
import {SyncDescriptor0, createSyncDescriptor, AsyncDescriptor1} from 'vs/platform/instantiation/common/descriptors';
import {SyncDescriptor0, createSyncDescriptor} from 'vs/platform/instantiation/common/descriptors';
export abstract class AbstractThreadService implements remote.IManyHandler {
public isInMainThread: boolean;
protected _instantiationService: instantiation.IInstantiationService;
protected _boundObjects: { [id: string]: IThreadSynchronizableObject; };
protected _pendingObjects: TPromise<IThreadSynchronizableObject>[];
private _localObjMap: { [id: string]: any; };
private _proxyObjMap: { [id: string]: any; };
constructor(isInMainThread: boolean) {
this.isInMainThread = isInMainThread;
this._boundObjects = {};
this._pendingObjects = [];
constructor() {
this._localObjMap = Object.create(null);
this._proxyObjMap = Object.create(null);
}
......@@ -34,48 +26,6 @@ export abstract class AbstractThreadService implements remote.IManyHandler {
this._instantiationService = service;
}
createInstance<A1, T extends IThreadSynchronizableObject>(ctor: instantiation.IConstructorSignature1<A1, T>, a1: A1): T;
createInstance<A1, T extends IThreadSynchronizableObject>(descriptor: AsyncDescriptor1<A1, T>, a1: A1): TPromise<T>;
createInstance(...params: any[]): any {
return this._doCreateInstance(params);
}
protected _doCreateInstance(params: any[]): any {
let instanceOrPromise = this._instantiationService.createInstance.apply(this._instantiationService, params);
if (TPromise.is(instanceOrPromise)) {
let objInstantiated: TPromise<IThreadSynchronizableObject>;
objInstantiated = instanceOrPromise.then((instance: IThreadSynchronizableObject): any => {
return instance;
});
this._pendingObjects.push(objInstantiated);
return objInstantiated.then((instance: IThreadSynchronizableObject) => {
let r = this._finishInstance(instance);
for (let i = 0; i < this._pendingObjects.length; i++) {
if (this._pendingObjects[i] === objInstantiated) {
this._pendingObjects.splice(i, 1);
break;
}
}
return r;
});
}
return this._finishInstance(<IThreadSynchronizableObject>instanceOrPromise);
}
private _finishInstance(instance: IThreadSynchronizableObject): IThreadSynchronizableObject {
instance[THREAD_SERVICE_PROPERTY_NAME] = this;
this._boundObjects[instance.getId()] = instance;
return instance;
}
public handle(rpcId: string, methodName: string, args: any[]): any {
if (!this._localObjMap[rpcId]) {
throw new Error('Unknown actor ' + rpcId);
......@@ -89,7 +39,6 @@ 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];
}
......@@ -127,10 +76,6 @@ export abstract class AbstractThreadService implements remote.IManyHandler {
return this._registerAndInstantiateExtHostActor(id, desc);
}
if (Remotable.Registry.WorkerContext[id]) {
return this._registerAndInstantiateWorkerActor(id, desc);
}
throw new Error('Unknown Remotable: <<' + id + '>>');
}
......@@ -148,10 +93,6 @@ export abstract class AbstractThreadService implements remote.IManyHandler {
return this._registerExtHostActor(id, instance);
}
if (Remotable.Registry.WorkerContext[id]) {
return this._registerWorkerActor(id, instance);
}
throw new Error('Unknown Remotable: <<' + id + '>>');
}
......@@ -159,8 +100,6 @@ 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>): T;
protected abstract _registerWorkerActor<T>(id: string, actor: T): void;
}
function createProxyFromCtor(remote:remote.IProxyHelper, id:string, ctor:Function): any {
......
......@@ -4,27 +4,22 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import {TPromise} from 'vs/base/common/winjs.base';
import remote = require('vs/base/common/remote');
import descriptors = require('vs/platform/instantiation/common/descriptors');
import abstractThreadService = require('./abstractThreadService');
import {IThreadService, IThreadSynchronizableObject} from 'vs/platform/thread/common/thread';
import {AbstractThreadService} from './abstractThreadService';
import {IThreadService} from 'vs/platform/thread/common/thread';
export class ExtHostThreadService extends abstractThreadService.AbstractThreadService implements IThreadService {
export class ExtHostThreadService extends AbstractThreadService implements IThreadService {
public serviceId = IThreadService;
protected _remoteCom: remote.IRemoteCom;
constructor(remoteCom: remote.IRemoteCom) {
super(false);
super();
this._remoteCom = remoteCom;
this._remoteCom.setManyHandler(this);
}
CompatWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[]): TPromise<any> {
return TPromise.as(null);
}
protected _registerAndInstantiateMainProcessActor<T>(id: string, descriptor: descriptors.SyncDescriptor0<T>): T {
return this._getOrCreateProxyInstance(this._remoteCom, id, descriptor);
}
......@@ -40,12 +35,4 @@ export class ExtHostThreadService extends abstractThreadService.AbstractThreadSe
protected _registerExtHostActor<T>(id: string, actor: T): void {
this._registerLocalInstance(id, actor);
}
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!');
}
protected _registerWorkerActor<T>(id: string, actor: T): void {
throw new Error('Not supported in this runtime context!');
}
}
\ No newline at end of file
......@@ -4,25 +4,16 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import {TPromise} from 'vs/base/common/winjs.base';
import abstractThreadService = require('vs/platform/thread/common/abstractThreadService');
import {AbstractThreadService} from 'vs/platform/thread/common/abstractThreadService';
import {SyncDescriptor0} from 'vs/platform/instantiation/common/descriptors';
import {IThreadService, IThreadSynchronizableObject} from 'vs/platform/thread/common/thread';
import {IThreadService} from 'vs/platform/thread/common/thread';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
export class MainThreadService extends abstractThreadService.AbstractThreadService implements IThreadService {
export abstract class CommonMainThreadService extends AbstractThreadService implements IThreadService {
public serviceId = IThreadService;
constructor(contextService: IWorkspaceContextService, workerModuleId: string) {
super(true);
if (!this.isInMainThread) {
throw new Error('Incorrect Service usage: this service must be used only in the main thread');
}
}
CompatWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[]): TPromise<any> {
throw new Error('Not supported in this runtime context: Cannot communicate to non-existant Worker!');
super();
}
protected _registerAndInstantiateMainProcessActor<T>(id: string, descriptor: SyncDescriptor0<T>): T {
......@@ -33,19 +24,7 @@ export class MainThreadService extends abstractThreadService.AbstractThreadServi
this._registerLocalInstance(id, actor);
}
protected _registerAndInstantiateExtHostActor<T>(id: string, descriptor: SyncDescriptor0<T>): T {
throw new Error('Not supported in this runtime context: Cannot communicate to non-existant Extension Host!');
}
protected _registerExtHostActor<T>(id: string, actor: T): void {
throw new Error('Not supported in this runtime context!');
}
protected _registerAndInstantiateWorkerActor<T>(id: string, descriptor: SyncDescriptor0<T>): T {
throw new Error('Not supported in this runtime context!');
}
protected _registerWorkerActor<T>(id: string, actor: T): void {
throw new Error('Not supported in this runtime context!');
}
}
\ No newline at end of file
}
......@@ -4,29 +4,13 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import {TPromise} from 'vs/base/common/winjs.base';
import descriptors = require('vs/platform/instantiation/common/descriptors');
import instantiation = require('vs/platform/instantiation/common/instantiation');
import {createDecorator, ServiceIdentifier, IConstructorSignature0} from 'vs/platform/instantiation/common/instantiation';
// --- thread service (web workers)
export const IThreadService = instantiation.createDecorator<IThreadService>('threadService');
export const IThreadService = createDecorator<IThreadService>('threadService');
export interface IThreadService {
serviceId: instantiation.ServiceIdentifier<any>;
// --- BEGIN deprecated methods
isInMainThread: boolean;
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>;
// --- END deprecated methods
getRemotable<T>(ctor: instantiation.IConstructorSignature0<T>): T;
serviceId: ServiceIdentifier<any>;
getRemotable<T>(ctor: IConstructorSignature0<T>): T;
registerRemotableInstance(ctor: any, instance: any): void;
}
......@@ -40,8 +24,7 @@ export class Remotable {
public static Registry = {
MainContext: <IRemotableCtorMap>Object.create(null),
ExtHostContext: <IRemotableCtorMap>Object.create(null),
WorkerContext: <IRemotableCtorMap>Object.create(null),
ExtHostContext: <IRemotableCtorMap>Object.create(null)
};
public static getId(ctor: any): string {
......@@ -64,25 +47,9 @@ export class Remotable {
};
}
public static WorkerContext(identifier: string) {
return function(target: Function) {
Remotable._ensureUnique(identifier);
Remotable.Registry.WorkerContext[identifier] = target;
target[Remotable.PROP_NAME] = identifier;
};
}
private static _ensureUnique(identifier: string): void {
if (Remotable.Registry.MainContext[identifier] || Remotable.Registry.ExtHostContext[identifier] || Remotable.Registry.WorkerContext[identifier]) {
if (Remotable.Registry.MainContext[identifier] || Remotable.Registry.ExtHostContext[identifier]) {
throw new Error('Duplicate Remotable identifier found');
}
}
}
export interface IThreadSynchronizableObject {
getId(): string;
creationDone?: () => void;
asyncCtor?: () => TPromise<void>;
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {IThreadService} from './thread';
export const THREAD_SERVICE_PROPERTY_NAME = '__$$__threadService';
function findMember(proto: any, target: any): string {
for (let i in proto) {
if (proto[i] === target) {
return i;
}
}
throw new Error('Member not found in prototype');
}
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 function CompatWorkerAttr(type: Function, target: Function): void {
let methodName = findMember(type.prototype, target);
type.prototype[methodName] = function(...param: any[]) {
return findThreadService(this).CompatWorker(this, methodName, target, param);
};
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
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} from 'vs/platform/thread/common/thread';
export class WorkerThreadService extends abstractThreadService.AbstractThreadService implements IThreadService {
public serviceId = IThreadService;
protected _remoteCom: remote.IRemoteCom;
constructor(remoteCom: remote.IRemoteCom) {
super(false);
this._remoteCom = remoteCom;
this._remoteCom.setManyHandler(this);
}
private _handleRequest(identifier: string, memberName: string, args: any[]): TPromise<any> {
if (!this._boundObjects.hasOwnProperty(identifier)) {
// Wait until all objects are constructed
return TPromise.join(this._pendingObjects.slice(0)).then(() => {
if (!this._boundObjects.hasOwnProperty(identifier)) {
return TPromise.wrapError(new Error('Bound object `' + identifier + '` was not found.'));
}
// console.log(identifier + ' > ' + memberName);
let obj = this._boundObjects[identifier];
return TPromise.as(obj[memberName].apply(obj, args));
});
}
// console.log(identifier + ' > ' + memberName);
let obj = this._boundObjects[identifier];
return TPromise.as(obj[memberName].apply(obj, args));
}
public dispatch(data: { type: string; payload: any; }): TPromise<any> {
try {
let args = data.payload;
let result = this._handleRequest(args[0], args[1], args[2]);
return TPromise.is(result) ? result : TPromise.as(result);
} catch (e) {
// handler error
return TPromise.wrapError(e);
}
}
CompatWorker(obj: IThreadSynchronizableObject, methodName: string, target: Function, params: any[]): TPromise<any> {
return target.apply(obj, params);
}
protected _registerAndInstantiateMainProcessActor<T>(id: string, descriptor: SyncDescriptor0<T>): T {
throw new Error('Not supported in this runtime context! Not allowed to make requests back to the main thread!');
}
protected _registerMainProcessActor<T>(id: string, actor: T): void {
throw new Error('Not supported in this runtime context!');
}
protected _registerAndInstantiateExtHostActor<T>(id: string, descriptor: SyncDescriptor0<T>): T {
throw new Error('Not supported in this runtime context: Cannot communicate from Worker directly to Extension Host!');
}
protected _registerExtHostActor<T>(id: string, actor: T): void {
throw new Error('Not supported in this runtime context!');
}
protected _registerAndInstantiateWorkerActor<T>(id: string, descriptor: SyncDescriptor0<T>): T {
return this._getOrCreateLocalInstance(id, descriptor);
}
protected _registerWorkerActor<T>(id: string, actor: T): void {
this._registerLocalInstance(id, actor);
}
}
\ No newline at end of file
......@@ -62,7 +62,7 @@ import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollect
import {ILifecycleService} from 'vs/platform/lifecycle/common/lifecycle';
import {IMessageService} from 'vs/platform/message/common/message';
import {IThreadService} from 'vs/platform/thread/common/thread';
import {MainThreadService} from 'vs/platform/thread/common/mainThreadService';
import {CommonMainThreadService} from 'vs/platform/thread/common/mainThreadService';
import {IStatusbarService} from 'vs/platform/statusbar/common/statusbar';
import {IMenuService} from 'vs/platform/actions/common/actions';
import {MenuService} from 'vs/platform/actions/browser/menuService';
......@@ -392,8 +392,8 @@ export class Workbench implements IPartService {
}
// Some services need to be set explicitly after all services are created
if (this.threadService instanceof MainThreadService) {
(<MainThreadService>this.threadService).setInstantiationService(this.instantiationService);
if (this.threadService instanceof CommonMainThreadService) {
(<CommonMainThreadService>this.threadService).setInstantiationService(this.instantiationService);
}
(<AbstractKeybindingService><any>this.keybindingService).setInstantiationService(this.instantiationService);
......
......@@ -17,7 +17,7 @@ import {findFreePort} from 'vs/base/node/ports';
import {IMainProcessExtHostIPC, create} from 'vs/platform/extensions/common/ipcRemoteCom';
import {SyncDescriptor0} from 'vs/platform/instantiation/common/descriptors';
import {IMessageService, Severity} from 'vs/platform/message/common/message';
import {MainThreadService as CommonMainThreadService} from 'vs/platform/thread/common/mainThreadService';
import {CommonMainThreadService} from 'vs/platform/thread/common/mainThreadService';
import {ILifecycleService, ShutdownEvent} from 'vs/platform/lifecycle/common/lifecycle';
import {IConfiguration, IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {IWindowService} from 'vs/workbench/services/window/electron-browser/windowService';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册