Skip to content

Commit

Permalink
fix(typescript-plugin): add packet loss handling
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsoncodehk committed Dec 23, 2024
1 parent b7a001f commit bc59d9a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 33 deletions.
2 changes: 1 addition & 1 deletion packages/typescript-plugin/lib/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,5 @@ async function sendRequest<T>(requestType: RequestData[1], fileName: string, ...
if (!server) {
return;
}
return server.request<T>(requestType, fileName, ...rest);
return server.sendRequest<T>(requestType, fileName, ...rest);
}
63 changes: 35 additions & 28 deletions packages/typescript-plugin/lib/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export async function startNamedPipeServer(
const dataChunks: Buffer[] = [];
const componentNamesAndProps = new Map<string, string>();
const allConnections = new Set<net.Socket>();
const pendingRequests = new Set<number>();
const server = net.createServer(connection => {
allConnections.add(connection);

Expand Down Expand Up @@ -183,58 +184,64 @@ export async function startNamedPipeServer(
}

function onRequest(connection: net.Socket, [seq, requestType, ...args]: RequestData) {
if (pendingRequests.has(seq)) {
return;
}
setTimeout(() => pendingRequests.delete(seq), 500);
pendingRequests.add(seq);

let data: any;
try {
data = handleRequest(requestType, ...args);
} catch {
data = null;
}

if (requestType === 'getComponentEvents' && Math.random() < 0.9) {
return;
}
connection.write(JSON.stringify([seq, data ?? null]) + '\n\n');
}

function handleRequest(requestType: RequestType, ...args: any[]) {
if (requestType === 'projectInfo') {
sendResponse({
return {
name: info.project.getProjectName(),
kind: info.project.projectKind,
currentDirectory: info.project.getCurrentDirectory(),
} satisfies ProjectInfo);
} satisfies ProjectInfo;
}
else if (requestType === 'containsFile') {
sendResponse(
info.project.containsFile(ts.server.toNormalizedPath(args[0]))
);
return info.project.containsFile(ts.server.toNormalizedPath(args[0]));
}
else if (requestType === 'collectExtractProps') {
const result = collectExtractProps.apply(requestContext, args as any);
sendResponse(result);
return collectExtractProps.apply(requestContext, args as any);
}
else if (requestType === 'getImportPathForFile') {
const result = getImportPathForFile.apply(requestContext, args as any);
sendResponse(result);
return getImportPathForFile.apply(requestContext, args as any);
}
else if (requestType === 'getPropertiesAtLocation') {
const result = getPropertiesAtLocation.apply(requestContext, args as any);
sendResponse(result);
return getPropertiesAtLocation.apply(requestContext, args as any);
}
else if (requestType === 'getQuickInfoAtPosition') {
const result = getQuickInfoAtPosition.apply(requestContext, args as any);
sendResponse(result);
return getQuickInfoAtPosition.apply(requestContext, args as any);
}
else if (requestType === 'getComponentProps') {
const result = getComponentProps.apply(requestContext, args as any);
sendResponse(result);
return getComponentProps.apply(requestContext, args as any);
}
else if (requestType === 'getComponentEvents') {
const result = getComponentEvents.apply(requestContext, args as any);
sendResponse(result);
return getComponentEvents.apply(requestContext, args as any);
}
else if (requestType === 'getTemplateContextProps') {
const result = getTemplateContextProps.apply(requestContext, args as any);
sendResponse(result);
return getTemplateContextProps.apply(requestContext, args as any);
}
else if (requestType === 'getElementAttrs') {
const result = getElementAttrs.apply(requestContext, args as any);
sendResponse(result);
}
else {
console.warn('[Vue Named Pipe Server] Unknown request:', requestType);
debugger;
return getElementAttrs.apply(requestContext, args as any);
}

function sendResponse(data: any | undefined) {
connection.write(JSON.stringify([seq, data ?? null]) + '\n\n');
}
console.warn('[Vue Named Pipe Server] Unknown request:', requestType);
debugger;
return undefined;
}
}

Expand Down
14 changes: 10 additions & 4 deletions packages/typescript-plugin/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class NamedPipeServer {
if (this.projectInfo) {
if (!this.containsFileCache.has(fileName)) {
this.containsFileCache.set(fileName, (async () => {
const res = await this.request<boolean>('containsFile', fileName);
const res = await this.sendRequest<boolean>('containsFile', fileName);
if (typeof res !== 'boolean') {
// If the request fails, delete the cache
this.containsFileCache.delete(fileName);
Expand All @@ -66,7 +66,7 @@ class NamedPipeServer {
this.socket = net.connect(this.path);
this.socket.on('data', this.onData.bind(this));
this.socket.on('connect', async () => {
const projectInfo = await this.request<ProjectInfo>('projectInfo', '');
const projectInfo = await this.sendRequest<ProjectInfo>('projectInfo', '');
if (projectInfo) {
console.log('TSServer project ready:', projectInfo.name);
this.projectInfo = projectInfo;
Expand Down Expand Up @@ -136,16 +136,22 @@ class NamedPipeServer {
}
}

request<T>(requestType: RequestData[1], fileName: string, ...args: any[]) {
sendRequest<T>(requestType: RequestData[1], fileName: string, ...args: any[]) {
return new Promise<T | undefined | null>(resolve => {
const seq = this.seq++;
// console.time(`[${seq}] ${requestType} ${fileName}`);
this.requestHandlers.set(seq, data => {
// console.timeEnd(`[${seq}] ${requestType} ${fileName}`);
this.requestHandlers.delete(seq);
resolve(data);
clearInterval(retryTimer);
});
this.socket!.write(JSON.stringify([seq, requestType, fileName, ...args] satisfies RequestData) + '\n\n');
const retry = () => {
const data: RequestData = [seq, requestType, fileName, ...args];
this.socket!.write(JSON.stringify(data) + '\n\n');
};
retry();
const retryTimer = setInterval(retry, 1000);
});
}
}
Expand Down

0 comments on commit bc59d9a

Please sign in to comment.