Get server working again
This commit is contained in:
Родитель
4f39877a41
Коммит
c9db693cc6
|
@ -278,17 +278,11 @@ function showMessageSoon() {
|
|||
function forwardOutput(server: OmniSharpServer) {
|
||||
|
||||
const logChannel = server.getChannel();
|
||||
const timing200Pattern = /^\[INFORMATION:OmniSharp.Middleware.LoggingMiddleware\] \/\w+: 200 \d+ms/;
|
||||
|
||||
function forward(message: string) {
|
||||
// strip stuff like: /codecheck: 200 339ms
|
||||
if(!timing200Pattern.test(message)) {
|
||||
logChannel.append(message);
|
||||
}
|
||||
logChannel.append(message);
|
||||
}
|
||||
|
||||
return vscode.Disposable.from(
|
||||
server.onStdout(forward),
|
||||
server.onStderr(forward));
|
||||
}
|
||||
|
||||
}
|
|
@ -7,11 +7,13 @@ import { Logger } from '../logger';
|
|||
import * as protocol from './protocol';
|
||||
import * as prioritization from './prioritization';
|
||||
|
||||
interface Request {
|
||||
export interface Request {
|
||||
command: string;
|
||||
data?: any;
|
||||
onSuccess(value: any): void;
|
||||
onError(err: any): void;
|
||||
startTime?: number;
|
||||
endTime?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,37 +22,47 @@ interface Request {
|
|||
*/
|
||||
class RequestQueue {
|
||||
private _pending: Request[] = [];
|
||||
private _waiting: Map<number, protocol.WireProtocol.RequestPacket> = new Map<number, protocol.WireProtocol.RequestPacket>();
|
||||
private _waiting: Map<number, Request> = new Map<number, Request>();
|
||||
|
||||
public constructor(
|
||||
private _name: string,
|
||||
private _maxSize: number,
|
||||
private _logger: Logger,
|
||||
private _makeRequest: (request: Request) => protocol.WireProtocol.RequestPacket) {
|
||||
private _makeRequest: (request: Request) => number) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue a new request.
|
||||
*/
|
||||
public enqueue(request: Request) {
|
||||
this._logger.appendLine(`Enqueuing request for ${request.command}.`);
|
||||
this._logger.appendLine(`Enqueue request for ${request.command}.`);
|
||||
this._pending.push(request);
|
||||
}
|
||||
|
||||
public dequeue(seq: number) {
|
||||
return this._waiting.delete(seq);
|
||||
/**
|
||||
* Dequeue a request that has completed.
|
||||
*/
|
||||
public dequeue(id: number) {
|
||||
const request = this._waiting.get(id);
|
||||
|
||||
if (request) {
|
||||
this._waiting.delete(id);
|
||||
this._logger.appendLine(`Dequeue request for ${request.command}.`);
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
public delete(request: Request) {
|
||||
public cancelRequest(request: Request) {
|
||||
let index = this._pending.indexOf(request);
|
||||
if (index !== -1) {
|
||||
this._pending.splice(index, 1);
|
||||
|
||||
// Do something better here.
|
||||
let err = new Error('Canceled');
|
||||
err.message = 'Canceled';
|
||||
request.onError(err);
|
||||
// Note: This calls reject() on the promise returned by OmniSharpServer.makeRequest
|
||||
request.onError(new Error(`Pending request cancelled: ${request.command}`));
|
||||
}
|
||||
|
||||
// TODO: Handle cancellation of a request already waiting on the OmniSharp server.
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,8 +91,10 @@ class RequestQueue {
|
|||
|
||||
for (let i = 0; i < slots && this._pending.length > 0; i++) {
|
||||
const item = this._pending.shift();
|
||||
const request = this._makeRequest(item);
|
||||
this._waiting.set(request.Seq, request);
|
||||
item.startTime = Date.now();
|
||||
|
||||
const id = this._makeRequest(item);
|
||||
this._waiting.set(id, item);
|
||||
|
||||
if (this.isFull()) {
|
||||
return;
|
||||
|
@ -89,7 +103,7 @@ class RequestQueue {
|
|||
}
|
||||
}
|
||||
|
||||
export class Queue {
|
||||
export class RequestQueueCollection {
|
||||
private _logger: Logger;
|
||||
private _isProcessing: boolean;
|
||||
private _priorityQueue: RequestQueue;
|
||||
|
@ -99,7 +113,7 @@ export class Queue {
|
|||
public constructor(
|
||||
logger: Logger,
|
||||
concurrency: number,
|
||||
makeRequest: (request: Request) => protocol.WireProtocol.RequestPacket
|
||||
makeRequest: (request: Request) => number
|
||||
) {
|
||||
this._priorityQueue = new RequestQueue('Priority', 1, logger, makeRequest);
|
||||
this._normalQueue = new RequestQueue('Normal', concurrency, logger, makeRequest);
|
||||
|
@ -132,7 +146,7 @@ export class Queue {
|
|||
|
||||
public cancelRequest(request: Request) {
|
||||
const queue = this.getQueue(request.command);
|
||||
queue.delete(request);
|
||||
queue.cancelRequest(request);
|
||||
}
|
||||
|
||||
public drain() {
|
|
@ -3,21 +3,19 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import {EventEmitter} from 'events';
|
||||
import {ChildProcess, exec} from 'child_process';
|
||||
import {dirname} from 'path';
|
||||
import {ReadLine, createInterface} from 'readline';
|
||||
import {launchOmniSharp} from './launcher';
|
||||
import * as protocol from './protocol';
|
||||
import {Options} from './options';
|
||||
import {Logger} from '../logger';
|
||||
import {DelayTracker} from './delayTracker';
|
||||
import {LaunchTarget, findLaunchTargets} from './launcher';
|
||||
import {PlatformInformation} from '../platform';
|
||||
import { Queue } from './queue';
|
||||
import { EventEmitter } from 'events';
|
||||
import { ChildProcess, exec } from 'child_process';
|
||||
import { ReadLine, createInterface } from 'readline';
|
||||
import { launchOmniSharp } from './launcher';
|
||||
import { Options } from './options';
|
||||
import { Logger } from '../logger';
|
||||
import { DelayTracker } from './delayTracker';
|
||||
import { LaunchTarget, findLaunchTargets } from './launcher';
|
||||
import { PlatformInformation } from '../platform';
|
||||
import { Request, RequestQueueCollection } from './requestQueue';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
import * as path from 'path';
|
||||
import * as protocol from './protocol';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
enum ServerState {
|
||||
|
@ -26,13 +24,6 @@ enum ServerState {
|
|||
Stopped
|
||||
}
|
||||
|
||||
interface Request {
|
||||
command: string;
|
||||
data?: any;
|
||||
onSuccess(value: any): void;
|
||||
onError(err: any): void;
|
||||
}
|
||||
|
||||
module Events {
|
||||
export const StateChanged = 'stateChanged';
|
||||
|
||||
|
@ -79,7 +70,7 @@ export class OmniSharpServer {
|
|||
private _eventBus = new EventEmitter();
|
||||
private _state: ServerState = ServerState.Stopped;
|
||||
private _launchTarget: LaunchTarget;
|
||||
private _requestQueue: Queue;
|
||||
private _requestQueue: RequestQueueCollection;
|
||||
private _channel: vscode.OutputChannel;
|
||||
private _logger: Logger;
|
||||
|
||||
|
@ -93,7 +84,7 @@ export class OmniSharpServer {
|
|||
|
||||
this._channel = vscode.window.createOutputChannel('OmniSharp Log');
|
||||
this._logger = new Logger(message => this._channel.append(message));
|
||||
this._requestQueue = new Queue(this._logger, 8, request => this._makeRequest(request));
|
||||
this._requestQueue = new RequestQueueCollection(this._logger, 8, request => this._makeRequest(request));
|
||||
}
|
||||
|
||||
public isRunning(): boolean {
|
||||
|
@ -124,9 +115,9 @@ export class OmniSharpServer {
|
|||
private _reportTelemetry() {
|
||||
const delayTrackers = this._delayTrackers;
|
||||
|
||||
for (const path in delayTrackers) {
|
||||
const tracker = delayTrackers[path];
|
||||
const eventName = 'omnisharp' + path;
|
||||
for (const requestName in delayTrackers) {
|
||||
const tracker = delayTrackers[requestName];
|
||||
const eventName = 'omnisharp' + requestName;
|
||||
if (tracker.hasMeasures()) {
|
||||
const measures = tracker.getMeasures();
|
||||
tracker.clearMeasures();
|
||||
|
@ -237,7 +228,7 @@ export class OmniSharpServer {
|
|||
this._launchTarget = launchTarget;
|
||||
|
||||
const solutionPath = launchTarget.target;
|
||||
const cwd = dirname(solutionPath);
|
||||
const cwd = path.dirname(solutionPath);
|
||||
let args = [
|
||||
'-s', solutionPath,
|
||||
'--hostPID', process.pid.toString(),
|
||||
|
@ -473,6 +464,7 @@ export class OmniSharpServer {
|
|||
if (listener) {
|
||||
listener.dispose();
|
||||
}
|
||||
|
||||
clearTimeout(handle);
|
||||
resolve();
|
||||
});
|
||||
|
@ -523,24 +515,25 @@ export class OmniSharpServer {
|
|||
}
|
||||
|
||||
private _handleResponsePacket(packet: protocol.WireProtocol.ResponsePacket) {
|
||||
if (!this._requestQueue.dequeue(packet.Command, packet.Request_seq)) {
|
||||
const request = this._requestQueue.dequeue(packet.Command, packet.Request_seq);
|
||||
|
||||
if (!request) {
|
||||
this._logger.appendLine(`Received response for ${packet.Command} but could not find request.`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet.Success) {
|
||||
// Handle success
|
||||
request.onSuccess(packet.Body);
|
||||
}
|
||||
else {
|
||||
// Handle failure
|
||||
request.onError(packet.Message || packet.Body);
|
||||
}
|
||||
}
|
||||
|
||||
private _handleEventPacket(packet: protocol.WireProtocol.EventPacket): void {
|
||||
if (packet.Event === 'log') {
|
||||
// handle log events
|
||||
const entry = <{ LogLevel: string; Name: string; Message: string; }>packet.Body;
|
||||
this._logger.appendLine(`[${entry.LogLevel}:${entry.Name}] ${entry.Message}`);
|
||||
this._logOutput(entry.LogLevel, entry.Name, entry.Message);
|
||||
}
|
||||
else {
|
||||
// fwd all other events
|
||||
|
@ -558,10 +551,21 @@ export class OmniSharpServer {
|
|||
Arguments: request.data
|
||||
};
|
||||
|
||||
console.log(`Making request: ${request.command} (${id})`);
|
||||
this._logger.appendLine(`Making request: ${request.command} (${id})`);
|
||||
|
||||
this._serverProcess.stdin.write(JSON.stringify(requestPacket) + '\n');
|
||||
|
||||
return requestPacket;
|
||||
return id;
|
||||
}
|
||||
|
||||
private _logOutput(logLevel: string, name: string, message: string) {
|
||||
const timing200Pattern = /^\[INFORMATION:OmniSharp.Middleware.LoggingMiddleware\] \/[\/\w]+: 200 \d+ms/;
|
||||
|
||||
const output = `[${logLevel}:${name}] ${message}`;
|
||||
|
||||
// strip stuff like: /codecheck: 200 339ms
|
||||
if (!timing200Pattern.test(output)) {
|
||||
this._logger.appendLine(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче