Skip to content

Commit c90f78a

Browse files
committed
Add ping/pong to the protocol
1 parent 31518e9 commit c90f78a

File tree

8 files changed

+405
-8
lines changed

8 files changed

+405
-8
lines changed

packages/protocol/src/browser/client.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { EventEmitter } from "events";
22
import { Emitter } from "@coder/events";
33
import { logger, field } from "@coder/logger";
4-
import { NewEvalMessage, ServerMessage, EvalDoneMessage, EvalFailedMessage, ClientMessage, WorkingInitMessage, EvalEventMessage } from "../proto";
4+
import { Ping, NewEvalMessage, ServerMessage, EvalDoneMessage, EvalFailedMessage, ClientMessage, WorkingInitMessage, EvalEventMessage } from "../proto";
55
import { ReadWriteConnection, InitData, OperatingSystem, SharedProcessData } from "../common/connection";
66
import { ActiveEvalHelper, EvalHelper, Disposer, ServerActiveEvalHelper } from "../common/helpers";
77
import { stringify, parse } from "../common/util";
@@ -22,6 +22,8 @@ export class Client {
2222
private readonly sharedProcessActiveEmitter = new Emitter<SharedProcessData>();
2323
public readonly onSharedProcessActive = this.sharedProcessActiveEmitter.event;
2424

25+
private readonly pingTimeout = 10000;
26+
2527
/**
2628
* @param connection Established connection to the server
2729
*/
@@ -46,6 +48,8 @@ export class Client {
4648
this.initDataPromise = new Promise((resolve): void => {
4749
this.initDataEmitter.event(resolve);
4850
});
51+
52+
this.ping();
4953
}
5054

5155
public dispose(): void {
@@ -214,6 +218,16 @@ export class Client {
214218
socketPath: sharedProcessActiveMessage.getSocketPath(),
215219
logPath: sharedProcessActiveMessage.getLogPath(),
216220
});
221+
} else if (message.hasPong()) {
222+
setTimeout(this.ping, this.pingTimeout);
223+
} else {
224+
throw new Error("unknown message type");
217225
}
218226
}
227+
228+
private ping = (): void => {
229+
const clientMsg = new ClientMessage();
230+
clientMsg.setPing(new Ping());
231+
this.connection.send(clientMsg.serializeBinary());
232+
}
219233
}

packages/protocol/src/node/server.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as path from "path";
33
import { mkdir } from "fs";
44
import { promisify } from "util";
55
import { logger, field } from "@coder/logger";
6-
import { ClientMessage, WorkingInitMessage, ServerMessage } from "../proto";
6+
import { Pong, ClientMessage, WorkingInitMessage, ServerMessage } from "../proto";
77
import { evaluate, ActiveEvaluation } from "./evaluate";
88
import { ForkProvider } from "../common/helpers";
99
import { ReadWriteConnection } from "../common/connection";
@@ -116,6 +116,11 @@ export class Server {
116116
return;
117117
}
118118
e.onEvent(evalEventMessage);
119+
} else if (message.hasPing()) {
120+
logger.trace("Ping");
121+
const srvMsg = new ServerMessage();
122+
srvMsg.setPong(new Pong());
123+
this.connection.send(srvMsg.serializeBinary());
119124
} else {
120125
throw new Error("unknown message type");
121126
}

packages/protocol/src/proto/client.proto

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ message ClientMessage {
77
// node.proto
88
NewEvalMessage new_eval = 11;
99
EvalEventMessage eval_event = 12;
10+
11+
Ping ping = 13;
1012
}
1113
}
1214

@@ -21,6 +23,8 @@ message ServerMessage {
2123

2224
// vscode.proto
2325
SharedProcessActiveMessage shared_process_active = 17;
26+
27+
Pong pong = 18;
2428
}
2529
}
2630

packages/protocol/src/proto/client_pb.d.ts

+14
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ export class ClientMessage extends jspb.Message {
1616
getEvalEvent(): node_pb.EvalEventMessage | undefined;
1717
setEvalEvent(value?: node_pb.EvalEventMessage): void;
1818

19+
hasPing(): boolean;
20+
clearPing(): void;
21+
getPing(): node_pb.Ping | undefined;
22+
setPing(value?: node_pb.Ping): void;
23+
1924
getMsgCase(): ClientMessage.MsgCase;
2025
serializeBinary(): Uint8Array;
2126
toObject(includeInstance?: boolean): ClientMessage.AsObject;
@@ -31,12 +36,14 @@ export namespace ClientMessage {
3136
export type AsObject = {
3237
newEval?: node_pb.NewEvalMessage.AsObject,
3338
evalEvent?: node_pb.EvalEventMessage.AsObject,
39+
ping?: node_pb.Ping.AsObject,
3440
}
3541

3642
export enum MsgCase {
3743
MSG_NOT_SET = 0,
3844
NEW_EVAL = 11,
3945
EVAL_EVENT = 12,
46+
PING = 13,
4047
}
4148
}
4249

@@ -66,6 +73,11 @@ export class ServerMessage extends jspb.Message {
6673
getSharedProcessActive(): vscode_pb.SharedProcessActiveMessage | undefined;
6774
setSharedProcessActive(value?: vscode_pb.SharedProcessActiveMessage): void;
6875

76+
hasPong(): boolean;
77+
clearPong(): void;
78+
getPong(): node_pb.Pong | undefined;
79+
setPong(value?: node_pb.Pong): void;
80+
6981
getMsgCase(): ServerMessage.MsgCase;
7082
serializeBinary(): Uint8Array;
7183
toObject(includeInstance?: boolean): ServerMessage.AsObject;
@@ -84,6 +96,7 @@ export namespace ServerMessage {
8496
evalEvent?: node_pb.EvalEventMessage.AsObject,
8597
init?: WorkingInitMessage.AsObject,
8698
sharedProcessActive?: vscode_pb.SharedProcessActiveMessage.AsObject,
99+
pong?: node_pb.Pong.AsObject,
87100
}
88101

89102
export enum MsgCase {
@@ -93,6 +106,7 @@ export namespace ServerMessage {
93106
EVAL_EVENT = 15,
94107
INIT = 16,
95108
SHARED_PROCESS_ACTIVE = 17,
109+
PONG = 18,
96110
}
97111
}
98112

packages/protocol/src/proto/client_pb.js

+96-6
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,16 @@ if (goog.DEBUG && !COMPILED) {
4343
* @private {!Array<!Array<number>>}
4444
* @const
4545
*/
46-
proto.ClientMessage.oneofGroups_ = [[11,12]];
46+
proto.ClientMessage.oneofGroups_ = [[11,12,13]];
4747

4848
/**
4949
* @enum {number}
5050
*/
5151
proto.ClientMessage.MsgCase = {
5252
MSG_NOT_SET: 0,
5353
NEW_EVAL: 11,
54-
EVAL_EVENT: 12
54+
EVAL_EVENT: 12,
55+
PING: 13
5556
};
5657

5758
/**
@@ -91,7 +92,8 @@ proto.ClientMessage.prototype.toObject = function(opt_includeInstance) {
9192
proto.ClientMessage.toObject = function(includeInstance, msg) {
9293
var f, obj = {
9394
newEval: (f = msg.getNewEval()) && node_pb.NewEvalMessage.toObject(includeInstance, f),
94-
evalEvent: (f = msg.getEvalEvent()) && node_pb.EvalEventMessage.toObject(includeInstance, f)
95+
evalEvent: (f = msg.getEvalEvent()) && node_pb.EvalEventMessage.toObject(includeInstance, f),
96+
ping: (f = msg.getPing()) && node_pb.Ping.toObject(includeInstance, f)
9597
};
9698

9799
if (includeInstance) {
@@ -138,6 +140,11 @@ proto.ClientMessage.deserializeBinaryFromReader = function(msg, reader) {
138140
reader.readMessage(value,node_pb.EvalEventMessage.deserializeBinaryFromReader);
139141
msg.setEvalEvent(value);
140142
break;
143+
case 13:
144+
var value = new node_pb.Ping;
145+
reader.readMessage(value,node_pb.Ping.deserializeBinaryFromReader);
146+
msg.setPing(value);
147+
break;
141148
default:
142149
reader.skipField();
143150
break;
@@ -183,6 +190,14 @@ proto.ClientMessage.serializeBinaryToWriter = function(message, writer) {
183190
node_pb.EvalEventMessage.serializeBinaryToWriter
184191
);
185192
}
193+
f = message.getPing();
194+
if (f != null) {
195+
writer.writeMessage(
196+
13,
197+
f,
198+
node_pb.Ping.serializeBinaryToWriter
199+
);
200+
}
186201
};
187202

188203

@@ -246,6 +261,36 @@ proto.ClientMessage.prototype.hasEvalEvent = function() {
246261
};
247262

248263

264+
/**
265+
* optional Ping ping = 13;
266+
* @return {?proto.Ping}
267+
*/
268+
proto.ClientMessage.prototype.getPing = function() {
269+
return /** @type{?proto.Ping} */ (
270+
jspb.Message.getWrapperField(this, node_pb.Ping, 13));
271+
};
272+
273+
274+
/** @param {?proto.Ping|undefined} value */
275+
proto.ClientMessage.prototype.setPing = function(value) {
276+
jspb.Message.setOneofWrapperField(this, 13, proto.ClientMessage.oneofGroups_[0], value);
277+
};
278+
279+
280+
proto.ClientMessage.prototype.clearPing = function() {
281+
this.setPing(undefined);
282+
};
283+
284+
285+
/**
286+
* Returns whether this field is set.
287+
* @return {!boolean}
288+
*/
289+
proto.ClientMessage.prototype.hasPing = function() {
290+
return jspb.Message.getField(this, 13) != null;
291+
};
292+
293+
249294

250295
/**
251296
* Generated by JsPbCodeGenerator.
@@ -272,7 +317,7 @@ if (goog.DEBUG && !COMPILED) {
272317
* @private {!Array<!Array<number>>}
273318
* @const
274319
*/
275-
proto.ServerMessage.oneofGroups_ = [[13,14,15,16,17]];
320+
proto.ServerMessage.oneofGroups_ = [[13,14,15,16,17,18]];
276321

277322
/**
278323
* @enum {number}
@@ -283,7 +328,8 @@ proto.ServerMessage.MsgCase = {
283328
EVAL_DONE: 14,
284329
EVAL_EVENT: 15,
285330
INIT: 16,
286-
SHARED_PROCESS_ACTIVE: 17
331+
SHARED_PROCESS_ACTIVE: 17,
332+
PONG: 18
287333
};
288334

289335
/**
@@ -326,7 +372,8 @@ proto.ServerMessage.toObject = function(includeInstance, msg) {
326372
evalDone: (f = msg.getEvalDone()) && node_pb.EvalDoneMessage.toObject(includeInstance, f),
327373
evalEvent: (f = msg.getEvalEvent()) && node_pb.EvalEventMessage.toObject(includeInstance, f),
328374
init: (f = msg.getInit()) && proto.WorkingInitMessage.toObject(includeInstance, f),
329-
sharedProcessActive: (f = msg.getSharedProcessActive()) && vscode_pb.SharedProcessActiveMessage.toObject(includeInstance, f)
375+
sharedProcessActive: (f = msg.getSharedProcessActive()) && vscode_pb.SharedProcessActiveMessage.toObject(includeInstance, f),
376+
pong: (f = msg.getPong()) && node_pb.Pong.toObject(includeInstance, f)
330377
};
331378

332379
if (includeInstance) {
@@ -388,6 +435,11 @@ proto.ServerMessage.deserializeBinaryFromReader = function(msg, reader) {
388435
reader.readMessage(value,vscode_pb.SharedProcessActiveMessage.deserializeBinaryFromReader);
389436
msg.setSharedProcessActive(value);
390437
break;
438+
case 18:
439+
var value = new node_pb.Pong;
440+
reader.readMessage(value,node_pb.Pong.deserializeBinaryFromReader);
441+
msg.setPong(value);
442+
break;
391443
default:
392444
reader.skipField();
393445
break;
@@ -457,6 +509,14 @@ proto.ServerMessage.serializeBinaryToWriter = function(message, writer) {
457509
vscode_pb.SharedProcessActiveMessage.serializeBinaryToWriter
458510
);
459511
}
512+
f = message.getPong();
513+
if (f != null) {
514+
writer.writeMessage(
515+
18,
516+
f,
517+
node_pb.Pong.serializeBinaryToWriter
518+
);
519+
}
460520
};
461521

462522

@@ -610,6 +670,36 @@ proto.ServerMessage.prototype.hasSharedProcessActive = function() {
610670
};
611671

612672

673+
/**
674+
* optional Pong pong = 18;
675+
* @return {?proto.Pong}
676+
*/
677+
proto.ServerMessage.prototype.getPong = function() {
678+
return /** @type{?proto.Pong} */ (
679+
jspb.Message.getWrapperField(this, node_pb.Pong, 18));
680+
};
681+
682+
683+
/** @param {?proto.Pong|undefined} value */
684+
proto.ServerMessage.prototype.setPong = function(value) {
685+
jspb.Message.setOneofWrapperField(this, 18, proto.ServerMessage.oneofGroups_[0], value);
686+
};
687+
688+
689+
proto.ServerMessage.prototype.clearPong = function() {
690+
this.setPong(undefined);
691+
};
692+
693+
694+
/**
695+
* Returns whether this field is set.
696+
* @return {!boolean}
697+
*/
698+
proto.ServerMessage.prototype.hasPong = function() {
699+
return jspb.Message.getField(this, 18) != null;
700+
};
701+
702+
613703

614704
/**
615705
* Generated by JsPbCodeGenerator.

packages/protocol/src/proto/node.proto

+4
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,7 @@ message EvalDoneMessage {
2626
uint64 id = 1;
2727
string response = 2;
2828
}
29+
30+
message Ping {}
31+
32+
message Pong {}

packages/protocol/src/proto/node_pb.d.ts

+32
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,35 @@ export namespace EvalDoneMessage {
119119
}
120120
}
121121

122+
export class Ping extends jspb.Message {
123+
serializeBinary(): Uint8Array;
124+
toObject(includeInstance?: boolean): Ping.AsObject;
125+
static toObject(includeInstance: boolean, msg: Ping): Ping.AsObject;
126+
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
127+
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
128+
static serializeBinaryToWriter(message: Ping, writer: jspb.BinaryWriter): void;
129+
static deserializeBinary(bytes: Uint8Array): Ping;
130+
static deserializeBinaryFromReader(message: Ping, reader: jspb.BinaryReader): Ping;
131+
}
132+
133+
export namespace Ping {
134+
export type AsObject = {
135+
}
136+
}
137+
138+
export class Pong extends jspb.Message {
139+
serializeBinary(): Uint8Array;
140+
toObject(includeInstance?: boolean): Pong.AsObject;
141+
static toObject(includeInstance: boolean, msg: Pong): Pong.AsObject;
142+
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
143+
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
144+
static serializeBinaryToWriter(message: Pong, writer: jspb.BinaryWriter): void;
145+
static deserializeBinary(bytes: Uint8Array): Pong;
146+
static deserializeBinaryFromReader(message: Pong, reader: jspb.BinaryReader): Pong;
147+
}
148+
149+
export namespace Pong {
150+
export type AsObject = {
151+
}
152+
}
153+

0 commit comments

Comments
 (0)