|
1 | 1 | import { logger } from "@coder/logger" |
2 | 2 | import { spawn } from "child_process" |
3 | | -import delay from "delay" |
4 | | -import fs from "fs" |
5 | 3 | import path from "path" |
6 | 4 | import split2 from "split2" |
7 | | -import { promisify } from "util" |
8 | | -import xdgBasedir from "xdg-basedir" |
9 | 5 |
|
10 | 6 | const coderCloudAgent = path.resolve(__dirname, "../../lib/coder-cloud-agent") |
11 | 7 |
|
@@ -39,17 +35,7 @@ export function coderCloudProxy(addr: string) { |
39 | 35 | // So we trim the protocol. |
40 | 36 | addr = addr.replace(/^https?:\/\//, "") |
41 | 37 |
|
42 | | - if (!xdgBasedir.config) { |
43 | | - return |
44 | | - } |
45 | | - |
46 | | - const sessionTokenPath = path.join(xdgBasedir.config, "coder-cloud", "session") |
47 | | - |
48 | 38 | const _proxy = async () => { |
49 | | - await waitForPath(sessionTokenPath) |
50 | | - |
51 | | - logger.info("exposing coder-server with coder-cloud") |
52 | | - |
53 | 39 | const agent = spawn(coderCloudAgent, ["proxy", "--code-server-addr", addr], { |
54 | 40 | stdio: ["inherit", "inherit", "pipe"], |
55 | 41 | }) |
@@ -84,74 +70,3 @@ export function coderCloudProxy(addr: string) { |
84 | 70 | } |
85 | 71 | proxy() |
86 | 72 | } |
87 | | - |
88 | | -/** |
89 | | - * waitForPath efficiently implements waiting for the existence of a path. |
90 | | - * |
91 | | - * We intentionally do not use fs.watchFile as it is very slow from testing. |
92 | | - * I believe it polls instead of watching. |
93 | | - * |
94 | | - * The way this works is for each level of the path it will check if it exists |
95 | | - * and if not, it will wait for it. e.g. if the path is /home/nhooyr/.config/coder-cloud/session |
96 | | - * then first it will check if /home exists, then /home/nhooyr and so on. |
97 | | - * |
98 | | - * The wait works by first creating a watch promise for the p segment. |
99 | | - * We call fs.watch on the dirname of the p segment. When the dirname has a change, |
100 | | - * we check if the p segment exists and if it does, we resolve the watch promise. |
101 | | - * On any error or the watcher being closed, we reject the watch promise. |
102 | | - * |
103 | | - * Once that promise is setup, we check if the p segment exists with fs.exists |
104 | | - * and if it does, we close the watcher and return. |
105 | | - * |
106 | | - * Now we race the watch promise and a 2000ms delay promise. Once the race |
107 | | - * is complete, we close the watcher. |
108 | | - * |
109 | | - * If the watch promise was the one to resolve, we return. |
110 | | - * Otherwise we setup the watch promise again and retry. |
111 | | - * |
112 | | - * This combination of polling and watching is very reliable and efficient. |
113 | | - */ |
114 | | -async function waitForPath(p: string): Promise<void> { |
115 | | - const segs = p.split(path.sep) |
116 | | - for (let i = 0; i < segs.length; i++) { |
117 | | - const s = path.join("/", ...segs.slice(0, i + 1)) |
118 | | - // We need to wait for each segment to exist. |
119 | | - await _waitForPath(s) |
120 | | - } |
121 | | -} |
122 | | - |
123 | | -async function _waitForPath(p: string): Promise<void> { |
124 | | - const watchDir = path.dirname(p) |
125 | | - |
126 | | - logger.debug(`waiting for ${p}`) |
127 | | - |
128 | | - for (;;) { |
129 | | - const w = fs.watch(watchDir) |
130 | | - const watchPromise = new Promise<void>((res, rej) => { |
131 | | - w.on("change", async () => { |
132 | | - if (await promisify(fs.exists)(p)) { |
133 | | - res() |
134 | | - } |
135 | | - }) |
136 | | - w.on("close", () => rej(new Error("watcher closed"))) |
137 | | - w.on("error", rej) |
138 | | - }) |
139 | | - |
140 | | - // We want to ignore any errors from this promise being rejected if the file |
141 | | - // already exists below. |
142 | | - watchPromise.catch(() => {}) |
143 | | - |
144 | | - if (await promisify(fs.exists)(p)) { |
145 | | - // The path exists! |
146 | | - w.close() |
147 | | - return |
148 | | - } |
149 | | - |
150 | | - // Now we wait for either the watch promise to resolve/reject or 2000ms. |
151 | | - const s = await Promise.race([watchPromise.then(() => "exists"), delay(2000)]) |
152 | | - w.close() |
153 | | - if (s === "exists") { |
154 | | - return |
155 | | - } |
156 | | - } |
157 | | -} |
0 commit comments