Skip to content

Commit f678836

Browse files
committed
Add deletion patch.
1 parent 8ff9647 commit f678836

File tree

5 files changed

+353
-215
lines changed

5 files changed

+353
-215
lines changed

patches/cleanup-socket.diff

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
Delete session from session registry on extension host termination.
2+
3+
Index: code-server/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
4+
===================================================================
5+
--- code-server.orig/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
6+
+++ code-server/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
7+
@@ -3,6 +3,9 @@
8+
* Licensed under the MIT License. See License.txt in the project root for license information.
9+
*--------------------------------------------------------------------------------------------*/
10+
11+
+import * as os from 'os';
12+
+import * as _http from 'http';
13+
+import * as path from 'vs/base/common/path';
14+
import * as nativeWatchdog from 'native-watchdog';
15+
import * as net from 'net';
16+
import * as minimist from 'minimist';
17+
@@ -400,7 +403,29 @@ async function startExtensionHostProcess
18+
);
19+
20+
// rewrite onTerminate-function to be a proper shutdown
21+
- onTerminate = (reason: string) => extensionHostMain.terminate(reason);
22+
+ onTerminate = (reason: string) => {
23+
+ extensionHostMain.terminate(reason);
24+
+ (() => {
25+
+ const socketPath = process.env['VSCODE_IPC_HOOK_CLI'];
26+
+ if (!socketPath) {
27+
+ return;
28+
+ }
29+
+ const message = JSON.stringify({socketPath});
30+
+ const codeServerSocketPath = path.join(os.tmpdir(), 'code-server-ipc.sock');
31+
+ const opts: _http.RequestOptions = {
32+
+ path: '/delete-session',
33+
+ socketPath: codeServerSocketPath,
34+
+ method: 'POST',
35+
+ headers: {
36+
+ 'content-type': 'application/json',
37+
+ 'accept': 'application/json'
38+
+ }
39+
+ };
40+
+ const req = _http.request(opts);
41+
+ req.write(message);
42+
+ req.end();
43+
+ })();
44+
+ };
45+
}
46+
47+
startExtensionHostProcess().catch((err) => console.log(err));

patches/series

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ insecure-notification.diff
88
update-check.diff
99
logout.diff
1010
store-socket.diff
11+
cleanup-socket.diff
1112
proxy-uri.diff
1213
github-auth.diff
1314
unique-db.diff

patches/store-socket.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Index: code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.
5353
+ const codeServerSocketPath = path.join(os.tmpdir(), 'code-server-ipc.sock');
5454
+ await new Promise<void>((resolve, reject) => {
5555
+ const opts: _http.RequestOptions = {
56-
+ path: '/session',
56+
+ path: '/add-session',
5757
+ socketPath: codeServerSocketPath,
5858
+ method: 'POST',
5959
+ headers: {

src/node/vscodeSocket.ts

+68-58
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ export interface EditorSessionEntry {
2424
socketPath: string
2525
}
2626

27-
// interface DeleteSessionRequest {
28-
// socketPath: string
29-
// }
27+
interface DeleteSessionRequest {
28+
socketPath: string
29+
}
3030

31-
interface RegisterSessionRequest {
31+
interface AddSessionRequest {
3232
entry: EditorSessionEntry
3333
}
3434

@@ -37,52 +37,15 @@ interface GetSessionResponse {
3737
socketPath?: string
3838
}
3939

40-
export class EditorSessionManagerClient {
41-
constructor(private codeServerSocketPath: string) {}
42-
43-
async canConnect() {
44-
return canConnect(this.codeServerSocketPath)
45-
}
46-
47-
async getConnectedSocketPath(filePath: string): Promise<string | undefined> {
48-
const response = await new Promise<GetSessionResponse>((resolve, reject) => {
49-
const opts = {
50-
path: "/session?filePath=" + encodeURIComponent(filePath),
51-
socketPath: this.codeServerSocketPath,
52-
}
53-
const req = http.get(opts, (res) => {
54-
let rawData = ""
55-
res.setEncoding("utf8")
56-
res.on("data", (chunk) => {
57-
rawData += chunk
58-
})
59-
res.on("end", () => {
60-
try {
61-
const obj = JSON.parse(rawData)
62-
if (res.statusCode === 200) {
63-
resolve(obj)
64-
} else {
65-
reject(new Error("Unexpected status code: " + res.statusCode))
66-
}
67-
} catch (e: unknown) {
68-
reject(e)
69-
}
70-
})
71-
})
72-
req.on("error", reject)
73-
req.end()
74-
})
75-
return response.socketPath
76-
}
77-
}
78-
7940
export async function makeEditorSessionManagerServer(
8041
codeServerSocketPath: string,
8142
editorSessionManager: EditorSessionManager,
8243
): Promise<http.Server> {
8344
const router = express()
45+
8446
// eslint-disable-next-line import/no-named-as-default-member
8547
router.use(express.json())
48+
8649
router.get("/session", async (req, res) => {
8750
const filePath = req.query.filePath as string
8851
if (!filePath) {
@@ -97,17 +60,25 @@ export async function makeEditorSessionManagerServer(
9760
res.status(500).send(error)
9861
}
9962
})
100-
router.post("/session", async (req, res) => {
101-
const request = req.body as RegisterSessionRequest
63+
64+
router.post("/add-session", async (req, res) => {
65+
const request = req.body as AddSessionRequest
10266
if (!request.entry) {
10367
res.status(400).send("entry is required")
10468
}
105-
editorSessionManager.registerSession(request.entry)
69+
editorSessionManager.addSession(request.entry)
10670
res.status(200).send()
10771
})
108-
router.delete("/session", async (req, res) => {
109-
throw new Error("Not implemented")
72+
73+
router.post("/delete-session", async (req, res) => {
74+
const request = req.body as DeleteSessionRequest
75+
if (!request.socketPath) {
76+
res.status(400).send("socketPath is required")
77+
}
78+
editorSessionManager.deleteSession(request.socketPath)
79+
res.status(200).send()
11080
})
81+
11182
const server = http.createServer(router)
11283
try {
11384
await fs.unlink(codeServerSocketPath)
@@ -133,18 +104,19 @@ export class EditorSessionManager {
133104
// Map from socket path to EditorSessionEntry.
134105
private entries = new Map<string, EditorSessionEntry>()
135106

136-
registerSession(entry: EditorSessionEntry): void {
107+
addSession(entry: EditorSessionEntry): void {
108+
logger.debug(`Adding session to session registry: ${entry.socketPath}`)
137109
this.entries.set(entry.socketPath, entry)
138110
}
139111

140-
getCandidatesForFile(path: string): EditorSessionEntry[] {
112+
getCandidatesForFile(filePath: string): EditorSessionEntry[] {
141113
const matchCheckResults = new Map<string, boolean>()
142114

143115
const checkMatch = (entry: EditorSessionEntry): boolean => {
144116
if (matchCheckResults.has(entry.socketPath)) {
145117
return matchCheckResults.get(entry.socketPath)!
146118
}
147-
const result = this.containsPath(entry, path)
119+
const result = entry.workspace.folders.some((folder) => filePath.startsWith(folder.uri.path + path.sep))
148120
matchCheckResults.set(entry.socketPath, result)
149121
return result
150122
}
@@ -165,17 +137,17 @@ export class EditorSessionManager {
165137
})
166138
}
167139

168-
private containsPath(entry: EditorSessionEntry, path: string): boolean {
169-
return entry.workspace.folders.some((folder) => path.startsWith(folder.uri.path))
140+
async deleteSession(socketPath: string): Promise<void> {
141+
logger.debug(`Deleting session from session registry: ${socketPath}`)
142+
this.entries.delete(socketPath)
170143
}
171144

172145
/**
173146
* Returns the best socket path that we can connect to.
174-
* See getSocketPaths for the order of preference.
175147
* We also delete any sockets that we can't connect to.
176148
*/
177-
async getConnectedSocketPath(path: string): Promise<string | undefined> {
178-
const candidates = this.getCandidatesForFile(path)
149+
async getConnectedSocketPath(filePath: string): Promise<string | undefined> {
150+
const candidates = this.getCandidatesForFile(filePath)
179151
let match: EditorSessionEntry | undefined = undefined
180152

181153
const toDelete = new Set<EditorSessionEntry>()
@@ -189,11 +161,49 @@ export class EditorSessionManager {
189161

190162
if (toDelete.size > 0) {
191163
for (const candidate of toDelete) {
192-
logger.debug(`Deleting stale socket from socket registry: ${candidate.socketPath}`)
193-
this.entries.delete(candidate.socketPath)
164+
this.deleteSession(candidate.socketPath)
194165
}
195166
}
196167

197168
return match?.socketPath
198169
}
199170
}
171+
172+
export class EditorSessionManagerClient {
173+
constructor(private codeServerSocketPath: string) {}
174+
175+
async canConnect() {
176+
return canConnect(this.codeServerSocketPath)
177+
}
178+
179+
async getConnectedSocketPath(filePath: string): Promise<string | undefined> {
180+
const response = await new Promise<GetSessionResponse>((resolve, reject) => {
181+
const opts = {
182+
path: "/session?filePath=" + encodeURIComponent(filePath),
183+
socketPath: this.codeServerSocketPath,
184+
}
185+
const req = http.get(opts, (res) => {
186+
let rawData = ""
187+
res.setEncoding("utf8")
188+
res.on("data", (chunk) => {
189+
rawData += chunk
190+
})
191+
res.on("end", () => {
192+
try {
193+
const obj = JSON.parse(rawData)
194+
if (res.statusCode === 200) {
195+
resolve(obj)
196+
} else {
197+
reject(new Error("Unexpected status code: " + res.statusCode))
198+
}
199+
} catch (e: unknown) {
200+
reject(e)
201+
}
202+
})
203+
})
204+
req.on("error", reject)
205+
req.end()
206+
})
207+
return response.socketPath
208+
}
209+
}

0 commit comments

Comments
 (0)