提交 7beea5ca 编写于 作者: A Alex Dima

Stop simple editor worker after 5 min if it's not used

上级 0b6bef4b
......@@ -7,6 +7,7 @@
import {IWorker, IWorkerFactory} from './workerClient';
import {TPromise, ValueCallback, ErrorCallback} from 'vs/base/common/winjs.base';
import errors = require('vs/base/common/errors');
import {Disposable} from 'vs/base/common/lifecycle';
const INITIALIZE = '$initialize';
......@@ -153,7 +154,7 @@ class SimpleWorkerProtocol {
/**
* Main thread side
*/
export class SimpleWorkerClient<T> {
export class SimpleWorkerClient<T> extends Disposable {
private _worker:IWorker;
private _onModuleLoaded:TPromise<void>;
......@@ -161,9 +162,10 @@ export class SimpleWorkerClient<T> {
private _proxy: T;
constructor(workerFactory:IWorkerFactory, moduleId:string, ctor:any) {
this._worker = workerFactory.create('vs/base/common/worker/simpleWorker', (msg:string) => {
super();
this._worker = this._register(workerFactory.create('vs/base/common/worker/simpleWorker', (msg:string) => {
this._protocol.handleMessage(msg);
});
}));
this._protocol = new SimpleWorkerProtocol({
sendMessage: (msg:string): void => {
......
......@@ -14,7 +14,7 @@ import marshalling = require('vs/base/common/marshalling');
export interface IWorker {
getId():number;
postMessage(message:string):void;
terminate():void;
dispose():void;
}
export interface IWorkerCallback {
......@@ -137,7 +137,7 @@ export class WorkerClient {
}
}
}
this._worker.terminate();
this._worker.dispose();
}
private _sendMessage(type:string, payload:any, forceTimestamp:number=(new Date()).getTime()):TPromise<any> {
......
......@@ -22,7 +22,7 @@ var getWorkerUrl = env.getCrossOriginWorkerScriptUrl || defaultGetWorkerUrl;
class WebWorker implements IWorker {
private id:number;
private worker:any;
private worker:Worker;
constructor(moduleId:string, id:number, label:string, onMessageCallback:IWorkerCallback) {
this.id = id;
......@@ -41,8 +41,9 @@ class WebWorker implements IWorker {
this.worker.postMessage(msg);
}
public terminate(): void {
public dispose(): void {
this.worker.terminate();
this.worker = null;
}
}
......@@ -87,6 +88,8 @@ class FrameWorker implements IWorker {
public dispose(): void {
this._listeners = lifecycle.disposeAll(this._listeners);
window.removeEventListener('message', this.onMessage);
window.frames[this.iframeId()].close();
}
private iframeId(): string {
......@@ -116,11 +119,6 @@ class FrameWorker implements IWorker {
this.beforeLoadMessages.push(msg);
}
}
public terminate(): void {
window.removeEventListener('message', this.onMessage);
window.frames[this.iframeId()].close();
}
}
export class DefaultWorkerFactory implements IWorkerFactory {
......
......@@ -9,10 +9,21 @@ import URI from 'vs/base/common/uri';
import {TPromise} from 'vs/base/common/winjs.base';
import EditorCommon = require('vs/editor/common/editorCommon');
import {IModelService} from 'vs/editor/common/services/modelService';
import {IDisposable, disposeAll} from 'vs/base/common/lifecycle';
import {Disposable, IDisposable, disposeAll} from 'vs/base/common/lifecycle';
import {SimpleWorkerClient} from 'vs/base/common/worker/simpleWorker';
import {DefaultWorkerFactory} from 'vs/base/worker/defaultWorkerFactory';
import {EditorSimpleWorker} from 'vs/editor/common/services/editorSimpleWorkerCommon';
import {IntervalTimer} from 'vs/base/common/async';
/**
* Stop syncing a model to the worker if it was not needed for 1 min.
*/
const STOP_SYNC_MODEL_DELTA_TIME_MS = 60 * 1000;
/**
* Stop the worker if it was not needed for 5 min.
*/
const STOP_WORKER_DELTA_TIME_MS = 5 * 60 * 1000;
export class EditorWorkerServiceImpl implements IEditorWorkerService {
public serviceId = IEditorWorkerService;
......@@ -32,17 +43,43 @@ export class EditorWorkerServiceImpl implements IEditorWorkerService {
}
}
class WorkerManager {
class WorkerManager extends Disposable {
private _modelService:IModelService;
private _editorWorkerClient: EditorWorkerClient;
private _lastWorkerUsedTime: number;
constructor(modelService:IModelService) {
super();
this._modelService = modelService;
this._editorWorkerClient = null;
let stopWorkerInterval = this._register(new IntervalTimer());
stopWorkerInterval.cancelAndSet(() => this._checkStopWorker(), Math.round(STOP_WORKER_DELTA_TIME_MS / 2));
}
public dispose(): void {
if (this._editorWorkerClient) {
this._editorWorkerClient.dispose();
this._editorWorkerClient = null;
}
super.dispose();
}
private _checkStopWorker(): void {
if (!this._editorWorkerClient) {
return;
}
let timeSinceLastWorkerUsedTime = (new Date()).getTime() - this._lastWorkerUsedTime;
if (timeSinceLastWorkerUsedTime > STOP_WORKER_DELTA_TIME_MS) {
this._editorWorkerClient.dispose();
this._editorWorkerClient = null;
}
}
public withWorker(): TPromise<EditorWorkerClient> {
this._lastWorkerUsedTime = (new Date()).getTime();
if (!this._editorWorkerClient) {
this._editorWorkerClient = new EditorWorkerClient(this._modelService);
}
......@@ -50,26 +87,31 @@ class WorkerManager {
}
}
class EditorWorkerClient {
class EditorWorkerClient extends Disposable {
private _worker: SimpleWorkerClient<EditorSimpleWorker>;
private _proxy: EditorSimpleWorker;
private _modelService:IModelService;
private _syncedModels: {[uri:string]:IDisposable[];};
private _syncedModels: {[modelUrl:string]:IDisposable[];};
constructor(modelService:IModelService) {
super();
this._modelService = modelService;
this._syncedModels = Object.create(null);
this._worker = new SimpleWorkerClient<EditorSimpleWorker>(
this._worker = this._register(new SimpleWorkerClient<EditorSimpleWorker>(
new DefaultWorkerFactory(),
'vs/editor/common/services/editorSimpleWorker',
EditorSimpleWorker
);
));
this._proxy = this._worker.get();
}
public dispose(): void {
console.log('TODO: EditorWorkerClient.dispose');
for (let modelUrl in this._syncedModels) {
disposeAll(this._syncedModels[modelUrl]);
}
this._syncedModels = Object.create(null);
super.dispose();
}
public computeDiff(original:URI, modified:URI, ignoreTrimWhitespace:boolean):TPromise<EditorCommon.ILineChange[]> {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册