提交 221aa3d6 编写于 作者: M Matt Bierner

Introduce RequestQueueingType

Allow for finer control over how requests are queued
上级 eafe48e9
......@@ -5,7 +5,7 @@
import * as assert from 'assert';
import 'mocha';
import { RequestQueue } from '../tsServer/requestQueue';
import { RequestQueue, RequestQueueingType } from '../tsServer/requestQueue';
suite('RequestQueue', () => {
test('should be empty on creation', async () => {
......@@ -33,11 +33,11 @@ suite('RequestQueue', () => {
assert.strictEqual(queue.length, 0);
const request1 = queue.createRequest('a', 1);
queue.push({ request: request1, expectsResponse: true, isAsync: false });
queue.push({ request: request1, expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.Normal });
assert.strictEqual(queue.length, 1);
const request2 = queue.createRequest('b', 2);
queue.push({ request: request2, expectsResponse: true, isAsync: false });
queue.push({ request: request2, expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.Normal });
assert.strictEqual(queue.length, 2);
{
......@@ -61,12 +61,52 @@ suite('RequestQueue', () => {
const queue = new RequestQueue();
assert.strictEqual(queue.length, 0);
const request1 = queue.createRequest('low', 1);
queue.push({ request: request1, expectsResponse: true, isAsync: false, lowPriority: true });
queue.push({ request: queue.createRequest('low-1', 1), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.LowPriority });
queue.push({ request: queue.createRequest('low-2', 1), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.LowPriority });
queue.push({ request: queue.createRequest('normal-1', 2), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.Normal });
queue.push({ request: queue.createRequest('normal-2', 2), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.Normal });
const request2 = queue.createRequest('normal', 2);
queue.push({ request: request2, expectsResponse: true, isAsync: false });
{
const item = queue.shift();
assert.strictEqual(queue.length, 3);
assert.strictEqual(item!.request.command, 'normal-1');
}
{
const item = queue.shift();
assert.strictEqual(queue.length, 2);
assert.strictEqual(item!.request.command, 'normal-2');
}
{
const item = queue.shift();
assert.strictEqual(queue.length, 1);
assert.strictEqual(item!.request.command, 'low-1');
}
{
const item = queue.shift();
assert.strictEqual(queue.length, 0);
assert.strictEqual(item!.request.command, 'low-2');
}
});
test('should not push fence requests front of low priority requests', async () => {
const queue = new RequestQueue();
assert.strictEqual(queue.length, 0);
queue.push({ request: queue.createRequest('low-1', 0), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.LowPriority });
queue.push({ request: queue.createRequest('fence', 0), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.Fence });
queue.push({ request: queue.createRequest('low-2', 0), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.LowPriority });
queue.push({ request: queue.createRequest('normal', 0), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.Normal });
{
const item = queue.shift();
assert.strictEqual(queue.length, 3);
assert.strictEqual(item!.request.command, 'low-1');
}
{
const item = queue.shift();
assert.strictEqual(queue.length, 2);
assert.strictEqual(item!.request.command, 'fence');
}
{
const item = queue.shift();
assert.strictEqual(queue.length, 1);
......@@ -75,7 +115,7 @@ suite('RequestQueue', () => {
{
const item = queue.shift();
assert.strictEqual(queue.length, 0);
assert.strictEqual(item!.request.command, 'low');
assert.strictEqual(item!.request.command, 'low-2');
}
});
});
......
......@@ -5,11 +5,31 @@
import * as Proto from '../protocol';
export enum RequestQueueingType {
/**
* Normal request that is executed in order.
*/
Normal = 1,
/**
* Request that normal requests jump in front of in the queue.
*/
LowPriority = 2,
/**
* A fence that blocks request reordering.
*
* Fences are not reordered but unlike a normal request, a fence will never jump in front of a low priority request
* in the request queue.
*/
Fence = 3,
}
export interface RequestItem {
readonly request: Proto.Request;
readonly expectsResponse: boolean;
readonly isAsync: boolean;
readonly lowPriority?: boolean;
readonly queueingType: RequestQueueingType;
}
export class RequestQueue {
......@@ -21,20 +41,21 @@ export class RequestQueue {
}
public push(item: RequestItem): void {
// insert before existing lowPriority requestItems in the queue.
if (!item.lowPriority && this.length) {
if (item.queueingType === RequestQueueingType.Normal) {
// insert before lowPriority items queue.
for (let i = this.length - 1; i > -1; i--) {
if (!this.queue[i].lowPriority) {
if (this.queue[i].queueingType !== RequestQueueingType.LowPriority) {
this.queue.splice(i + 1, 0, item);
return;
}
}
//if all of the items are lowPriority insert at top
// If all of the items are lowPriority insert at top
this.queue.unshift(item);
return;
} else {
//if none is low priority just push to end
this.queue.push(item);
}
//if none is low priority just push to end
this.queue.push(item);
}
public shift(): RequestItem | undefined {
......
......@@ -22,7 +22,7 @@ import Tracer from '../utils/tracer';
import { TypeScriptVersion, TypeScriptVersionProvider } from '../utils/versionProvider';
import { Reader } from '../utils/wireProtocol';
import { CallbackMap } from './callbackMap';
import { RequestQueue, RequestItem } from './requestQueue';
import { RequestQueue, RequestItem, RequestQueueingType } from './requestQueue';
export class TypeScriptServerSpawner {
public constructor(
......@@ -301,7 +301,7 @@ export class TypeScriptServer extends Disposable {
request: request,
expectsResponse: executeInfo.expectsResult,
isAsync: executeInfo.isAsync,
lowPriority: executeInfo.lowPriority
queueingType: getQueueingType(command, executeInfo.lowPriority)
};
let result: Promise<any>;
if (executeInfo.expectsResult) {
......@@ -405,3 +405,15 @@ export class TypeScriptServer extends Disposable {
}
}
const fenceCommands = new Set(['change', 'close', 'open']);
function getQueueingType(
command: string,
lowPriority?: boolean
): RequestQueueingType {
if (fenceCommands.has(command)) {
return RequestQueueingType.Fence;
}
return lowPriority ? RequestQueueingType.LowPriority : RequestQueueingType.Normal;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册