Skip to content

Commit d6c3a15

Browse files
committed
Move event into IoSession
1 parent 005c863 commit d6c3a15

4 files changed

Lines changed: 97 additions & 69 deletions

File tree

src/server/editorServices.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ namespace ts.server {
320320
pluginProbeLocations?: ReadonlyArray<string>;
321321
allowLocalPluginLoads?: boolean;
322322
typesMapLocation?: string;
323-
eventSender?: EventSender;
324323
}
325324

326325
type WatchFile = (host: ServerHost, file: string, cb: FileWatcherCallback, watchType: WatchType, project?: Project) => FileWatcher;
@@ -441,7 +440,7 @@ namespace ts.server {
441440
this.logger.info("No types map provided; using the default");
442441
}
443442

444-
this.typingsInstaller.attach(this, opts.eventSender);
443+
this.typingsInstaller.attach(this);
445444

446445
this.typingsCache = new TypingsCache(this.typingsInstaller);
447446

src/server/server.ts

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ namespace ts.server {
77
cancellationToken: ServerCancellationToken;
88
canUseEvents: boolean;
99
/**
10-
* If defined, specifies the socket used to send events to the client.
11-
* Otherwise, events are sent through the host.
12-
*/
10+
* If defined, specifies the socket used to send events to the client.
11+
* Otherwise, events are sent through the host.
12+
*/
1313
eventPort?: number;
1414
useSingleInferredProject: boolean;
1515
useInferredProjectPerProjectRoot: boolean;
@@ -248,7 +248,6 @@ namespace ts.server {
248248
private installer: NodeChildProcess;
249249
private installerPidReported = false;
250250
private projectService: ProjectService;
251-
private eventSender: EventSender | undefined;
252251
private activeRequestCount = 0;
253252
private requestQueue: QueuedOperation[] = [];
254253
private requestMap = createMap<QueuedOperation>(); // Maps operation ID to newest requestQueue entry with that ID
@@ -272,7 +271,11 @@ namespace ts.server {
272271
readonly globalTypingsCacheLocation: string,
273272
readonly typingSafeListLocation: string,
274273
readonly typesMapLocation: string,
275-
private readonly npmLocation: string | undefined) {
274+
private readonly npmLocation: string | undefined,
275+
/**
276+
* If undefined, event-related work will be suppressed.
277+
*/
278+
private eventSender: EventSender | undefined) {
276279
}
277280

278281
isKnownTypesPackageName(name: string): boolean {
@@ -311,16 +314,12 @@ namespace ts.server {
311314
}
312315

313316

314-
attach(projectService: ProjectService, eventSender?: EventSender) {
317+
attach(projectService: ProjectService) {
315318
this.projectService = projectService;
316319
if (this.logger.hasLevel(LogLevel.requestTime)) {
317320
this.logger.info("Binding...");
318321
}
319322

320-
if (eventSender) {
321-
this.eventSender = eventSender;
322-
}
323-
324323
const args: string[] = [Arguments.GlobalCacheLocation, this.globalTypingsCacheLocation];
325324
if (this.telemetryEnabled) {
326325
args.push(Arguments.EnableTelemetry);
@@ -519,17 +518,15 @@ namespace ts.server {
519518
}
520519
}
521520

522-
class SocketEventSender implements EventSender {
523-
private host: ServerHost;
524-
private logger: Logger;
525-
private eventPort: number;
521+
class SocketEventSender extends DefaultMessageSender {
526522
private eventSocket: NodeSocket | undefined;
527523
private socketEventQueue: { body: any, eventName: string }[] | undefined;
528524

529-
constructor(host: ServerHost, logger: Logger, eventPort: number) {
530-
this.host = host;
531-
this.logger = logger;
532-
this.eventPort = eventPort;
525+
constructor(host: ServerHost,
526+
byteLength: (buf: string, encoding?: string) => number,
527+
logger: Logger,
528+
private eventPort: number) {
529+
super(host, byteLength, logger, /*canUseEvents*/ true);
533530

534531
const s = net.connect({ port: this.eventPort }, () => {
535532
this.eventSocket = s;
@@ -541,20 +538,20 @@ namespace ts.server {
541538
this.socketEventQueue = undefined;
542539
}
543540
});
544-
}
545541

546-
public event = <T>(body: T, eventName: string) => {
547-
if (!this.eventSocket) {
548-
if (this.logger.hasLevel(LogLevel.verbose)) {
549-
this.logger.info(`eventPort: event "${eventName}" queued, but socket not yet initialized`);
542+
this.event = <T>(body: T, eventName: string) => {
543+
if (!this.eventSocket) {
544+
if (this.logger.hasLevel(LogLevel.verbose)) {
545+
this.logger.info(`eventPort: event "${eventName}" queued, but socket not yet initialized`);
546+
}
547+
(this.socketEventQueue || (this.socketEventQueue = [])).push({ body, eventName });
548+
return;
550549
}
551-
(this.socketEventQueue || (this.socketEventQueue = [])).push({ body, eventName });
552-
return;
553-
}
554-
else {
555-
Debug.assert(this.socketEventQueue === undefined);
556-
this.writeToEventSocket(body, eventName);
557-
}
550+
else {
551+
Debug.assert(this.socketEventQueue === undefined);
552+
this.writeToEventSocket(body, eventName);
553+
}
554+
};
558555
}
559556

560557
private writeToEventSocket(body: any, eventName: string): void {
@@ -566,15 +563,11 @@ namespace ts.server {
566563
constructor(options: IoSessionOptions) {
567564
const { host, eventPort, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, canUseEvents } = options;
568565

569-
let event: Event;
570-
if (canUseEvents && eventPort) {
571-
const eventSender = new SocketEventSender(host, logger, eventPort);
572-
event = eventSender.event;
573-
}
566+
const messageSender = eventPort && canUseEvents ? new SocketEventSender(host, Buffer.byteLength, logger, eventPort) : new DefaultMessageSender(host, Buffer.byteLength, logger, canUseEvents);
574567

575568
const typingsInstaller = disableAutomaticTypingAcquisition
576569
? undefined
577-
: new NodeTypingsInstaller(telemetryEnabled, logger, host, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation);
570+
: new NodeTypingsInstaller(telemetryEnabled, logger, host, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, canUseEvents ? messageSender : undefined);
578571

579572
super({
580573
host,
@@ -586,7 +579,7 @@ namespace ts.server {
586579
hrtime: process.hrtime,
587580
logger,
588581
canUseEvents,
589-
event,
582+
messageSender,
590583
globalPlugins: options.globalPlugins,
591584
pluginProbeLocations: options.pluginProbeLocations,
592585
allowLocalPluginLoads: options.allowLocalPluginLoads });

src/server/session.ts

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,58 @@ namespace ts.server {
245245
event: Event;
246246
}
247247

248+
export type Send = (msg: protocol.Message) => void;
249+
250+
export interface MessageSender extends EventSender {
251+
send: Send;
252+
event: Event;
253+
}
254+
255+
function defaultSend(
256+
host: ServerHost,
257+
byteLength: (buf: string, encoding?: string) => number,
258+
logger: Logger,
259+
canUseEvents: boolean,
260+
msg: protocol.Message) {
261+
if (msg.type === "event" && !canUseEvents) {
262+
if (logger.hasLevel(LogLevel.verbose)) {
263+
logger.info(`Session does not support events: ignored event: ${JSON.stringify(msg)}`);
264+
}
265+
return;
266+
}
267+
host.write(formatMessage(msg, logger, byteLength, host.newLine));
268+
}
269+
270+
function defaultEvent<T>(
271+
host: ServerHost,
272+
byteLength: (buf: string, encoding?: string) => number,
273+
logger: Logger,
274+
canUseEvents: boolean,
275+
body: T, eventName: string): void {
276+
const ev: protocol.Event = {
277+
seq: 0,
278+
type: "event",
279+
event: eventName,
280+
body
281+
};
282+
defaultSend(host, byteLength, logger, canUseEvents, ev);
283+
}
284+
285+
export class DefaultMessageSender implements MessageSender {
286+
constructor(protected host: ServerHost,
287+
protected byteLength: (buf: string, encoding?: string) => number,
288+
protected logger: Logger,
289+
protected canUseEvents: boolean) { }
290+
291+
public send = (msg: protocol.Message) => {
292+
defaultSend(this.host, this.byteLength, this.logger, this.canUseEvents, msg);
293+
}
294+
295+
public event = <T>(body: T, eventName: string) => {
296+
defaultEvent(this.host, this.byteLength, this.logger, this.canUseEvents, body, eventName);
297+
}
298+
}
299+
248300
export interface SessionOptions {
249301
host: ServerHost;
250302
cancellationToken: ServerCancellationToken;
@@ -259,10 +311,9 @@ namespace ts.server {
259311
*/
260312
canUseEvents: boolean;
261313
/**
262-
* An optional callback overriding the default behavior for sending events.
263-
* if set, `canUseEvents` and `eventPort` are ignored.
314+
* An optional callback overriding the default behavior for sending messages.
264315
*/
265-
event?: Event;
316+
messageSender?: MessageSender;
266317
eventHandler?: ProjectServiceEventHandler;
267318
throttleWaitMilliseconds?: number;
268319

@@ -271,9 +322,7 @@ namespace ts.server {
271322
allowLocalPluginLoads?: boolean;
272323
}
273324

274-
export class Session implements EventSender {
275-
public readonly event: Event;
276-
325+
export class Session implements MessageSender {
277326
private readonly gcTimer: GcTimer;
278327
protected projectService: ProjectService;
279328
private changeSeq = 0;
@@ -298,23 +347,13 @@ namespace ts.server {
298347
this.byteLength = opts.byteLength;
299348
this.hrtime = opts.hrtime;
300349
this.logger = opts.logger;
301-
this.canUseEvents = opts.canUseEvents || !!opts.event;
350+
this.canUseEvents = opts.canUseEvents;
302351

303352
const { throttleWaitMilliseconds } = opts;
304353

305-
if (opts.event) {
306-
this.event = opts.event;
307-
}
308-
else {
309-
this.event = function <T>(body: T, eventName: string): void {
310-
const ev: protocol.Event = {
311-
seq: 0,
312-
type: "event",
313-
event: eventName,
314-
body
315-
};
316-
this.send(ev);
317-
};
354+
if (opts.messageSender) {
355+
this.send = opts.messageSender.send;
356+
this.event = opts.messageSender.event;
318357
}
319358

320359
this.eventHandler = this.canUseEvents
@@ -340,8 +379,7 @@ namespace ts.server {
340379
eventHandler: this.eventHandler,
341380
globalPlugins: opts.globalPlugins,
342381
pluginProbeLocations: opts.pluginProbeLocations,
343-
allowLocalPluginLoads: opts.allowLocalPluginLoads,
344-
eventSender: this
382+
allowLocalPluginLoads: opts.allowLocalPluginLoads
345383
};
346384
this.projectService = new ProjectService(settings);
347385
this.gcTimer = new GcTimer(this.host, /*delay*/ 7000, this.logger);
@@ -413,13 +451,11 @@ namespace ts.server {
413451
}
414452

415453
public send(msg: protocol.Message) {
416-
if (msg.type === "event" && !this.canUseEvents) {
417-
if (this.logger.hasLevel(LogLevel.verbose)) {
418-
this.logger.info(`Session does not support events: ignored event: ${JSON.stringify(msg)}`);
419-
}
420-
return;
421-
}
422-
this.host.write(formatMessage(msg, this.logger, this.byteLength, this.host.newLine));
454+
defaultSend(this.host, this.byteLength, this.logger, this.canUseEvents, msg);
455+
}
456+
457+
public event<T>(body: T, eventName: string): void {
458+
defaultEvent(this.host, this.byteLength, this.logger, this.canUseEvents, body, eventName);
423459
}
424460

425461
// For backwards-compatibility only.

src/server/typingsCache.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace ts.server {
1010
isKnownTypesPackageName(name: string): boolean;
1111
installPackage(options: InstallPackageOptionsWithProjectRootPath): Promise<ApplyCodeActionCommandResult>;
1212
enqueueInstallTypingsRequest(p: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>): void;
13-
attach(projectService: ProjectService, eventSender?: EventSender): void;
13+
attach(projectService: ProjectService): void;
1414
onProjectClosed(p: Project): void;
1515
readonly globalTypingsCacheLocation: string;
1616
}

0 commit comments

Comments
 (0)