coc-tsserver/src/server/requestQueue.ts

81 lines
2.1 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
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. 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 queueingType: RequestQueueingType
}
export class RequestQueue {
private readonly queue: RequestItem[] = []
private sequenceNumber = 0
public get length(): number {
return this.queue.length
}
public enqueue(item: RequestItem): void {
if (item.queueingType === RequestQueueingType.Normal) {
let index = this.queue.length - 1
while (index >= 0) {
if (this.queue[index].queueingType !== RequestQueueingType.LowPriority) {
break
}
--index
}
this.queue.splice(index + 1, 0, item)
} else {
// Only normal priority requests can be reordered. All other requests just go to the end.
this.queue.push(item)
}
}
public dequeue(): RequestItem | undefined {
return this.queue.shift()
}
public tryDeletePendingRequest(seq: number): boolean {
for (let i = 0; i < this.queue.length; i++) {
if (this.queue[i].request.seq === seq) {
this.queue.splice(i, 1)
return true
}
}
return false
}
public createRequest(command: string, args: any): Proto.Request {
return {
seq: this.sequenceNumber++,
type: 'request',
command,
arguments: args
}
}
}