/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import type * 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: number = 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: command, arguments: args }; } }