Skip to content

Commit bc59d9a

Browse files
committed
fix(typescript-plugin): add packet loss handling
1 parent b7a001f commit bc59d9a

File tree

3 files changed

+46
-33
lines changed

3 files changed

+46
-33
lines changed

packages/typescript-plugin/lib/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,5 @@ async function sendRequest<T>(requestType: RequestData[1], fileName: string, ...
9595
if (!server) {
9696
return;
9797
}
98-
return server.request<T>(requestType, fileName, ...rest);
98+
return server.sendRequest<T>(requestType, fileName, ...rest);
9999
}

packages/typescript-plugin/lib/server.ts

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export async function startNamedPipeServer(
6565
const dataChunks: Buffer[] = [];
6666
const componentNamesAndProps = new Map<string, string>();
6767
const allConnections = new Set<net.Socket>();
68+
const pendingRequests = new Set<number>();
6869
const server = net.createServer(connection => {
6970
allConnections.add(connection);
7071

@@ -183,58 +184,64 @@ export async function startNamedPipeServer(
183184
}
184185

185186
function onRequest(connection: net.Socket, [seq, requestType, ...args]: RequestData) {
187+
if (pendingRequests.has(seq)) {
188+
return;
189+
}
190+
setTimeout(() => pendingRequests.delete(seq), 500);
191+
pendingRequests.add(seq);
192+
193+
let data: any;
194+
try {
195+
data = handleRequest(requestType, ...args);
196+
} catch {
197+
data = null;
198+
}
199+
200+
if (requestType === 'getComponentEvents' && Math.random() < 0.9) {
201+
return;
202+
}
203+
connection.write(JSON.stringify([seq, data ?? null]) + '\n\n');
204+
}
205+
206+
function handleRequest(requestType: RequestType, ...args: any[]) {
186207
if (requestType === 'projectInfo') {
187-
sendResponse({
208+
return {
188209
name: info.project.getProjectName(),
189210
kind: info.project.projectKind,
190211
currentDirectory: info.project.getCurrentDirectory(),
191-
} satisfies ProjectInfo);
212+
} satisfies ProjectInfo;
192213
}
193214
else if (requestType === 'containsFile') {
194-
sendResponse(
195-
info.project.containsFile(ts.server.toNormalizedPath(args[0]))
196-
);
215+
return info.project.containsFile(ts.server.toNormalizedPath(args[0]));
197216
}
198217
else if (requestType === 'collectExtractProps') {
199-
const result = collectExtractProps.apply(requestContext, args as any);
200-
sendResponse(result);
218+
return collectExtractProps.apply(requestContext, args as any);
201219
}
202220
else if (requestType === 'getImportPathForFile') {
203-
const result = getImportPathForFile.apply(requestContext, args as any);
204-
sendResponse(result);
221+
return getImportPathForFile.apply(requestContext, args as any);
205222
}
206223
else if (requestType === 'getPropertiesAtLocation') {
207-
const result = getPropertiesAtLocation.apply(requestContext, args as any);
208-
sendResponse(result);
224+
return getPropertiesAtLocation.apply(requestContext, args as any);
209225
}
210226
else if (requestType === 'getQuickInfoAtPosition') {
211-
const result = getQuickInfoAtPosition.apply(requestContext, args as any);
212-
sendResponse(result);
227+
return getQuickInfoAtPosition.apply(requestContext, args as any);
213228
}
214229
else if (requestType === 'getComponentProps') {
215-
const result = getComponentProps.apply(requestContext, args as any);
216-
sendResponse(result);
230+
return getComponentProps.apply(requestContext, args as any);
217231
}
218232
else if (requestType === 'getComponentEvents') {
219-
const result = getComponentEvents.apply(requestContext, args as any);
220-
sendResponse(result);
233+
return getComponentEvents.apply(requestContext, args as any);
221234
}
222235
else if (requestType === 'getTemplateContextProps') {
223-
const result = getTemplateContextProps.apply(requestContext, args as any);
224-
sendResponse(result);
236+
return getTemplateContextProps.apply(requestContext, args as any);
225237
}
226238
else if (requestType === 'getElementAttrs') {
227-
const result = getElementAttrs.apply(requestContext, args as any);
228-
sendResponse(result);
229-
}
230-
else {
231-
console.warn('[Vue Named Pipe Server] Unknown request:', requestType);
232-
debugger;
239+
return getElementAttrs.apply(requestContext, args as any);
233240
}
234241

235-
function sendResponse(data: any | undefined) {
236-
connection.write(JSON.stringify([seq, data ?? null]) + '\n\n');
237-
}
242+
console.warn('[Vue Named Pipe Server] Unknown request:', requestType);
243+
debugger;
244+
return undefined;
238245
}
239246
}
240247

packages/typescript-plugin/lib/utils.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class NamedPipeServer {
4343
if (this.projectInfo) {
4444
if (!this.containsFileCache.has(fileName)) {
4545
this.containsFileCache.set(fileName, (async () => {
46-
const res = await this.request<boolean>('containsFile', fileName);
46+
const res = await this.sendRequest<boolean>('containsFile', fileName);
4747
if (typeof res !== 'boolean') {
4848
// If the request fails, delete the cache
4949
this.containsFileCache.delete(fileName);
@@ -66,7 +66,7 @@ class NamedPipeServer {
6666
this.socket = net.connect(this.path);
6767
this.socket.on('data', this.onData.bind(this));
6868
this.socket.on('connect', async () => {
69-
const projectInfo = await this.request<ProjectInfo>('projectInfo', '');
69+
const projectInfo = await this.sendRequest<ProjectInfo>('projectInfo', '');
7070
if (projectInfo) {
7171
console.log('TSServer project ready:', projectInfo.name);
7272
this.projectInfo = projectInfo;
@@ -136,16 +136,22 @@ class NamedPipeServer {
136136
}
137137
}
138138

139-
request<T>(requestType: RequestData[1], fileName: string, ...args: any[]) {
139+
sendRequest<T>(requestType: RequestData[1], fileName: string, ...args: any[]) {
140140
return new Promise<T | undefined | null>(resolve => {
141141
const seq = this.seq++;
142142
// console.time(`[${seq}] ${requestType} ${fileName}`);
143143
this.requestHandlers.set(seq, data => {
144144
// console.timeEnd(`[${seq}] ${requestType} ${fileName}`);
145145
this.requestHandlers.delete(seq);
146146
resolve(data);
147+
clearInterval(retryTimer);
147148
});
148-
this.socket!.write(JSON.stringify([seq, requestType, fileName, ...args] satisfies RequestData) + '\n\n');
149+
const retry = () => {
150+
const data: RequestData = [seq, requestType, fileName, ...args];
151+
this.socket!.write(JSON.stringify(data) + '\n\n');
152+
};
153+
retry();
154+
const retryTimer = setInterval(retry, 1000);
149155
});
150156
}
151157
}

0 commit comments

Comments
 (0)