Skip to content

Commit 2d91b14

Browse files
committed
Cleanup old servers on startup
1 parent 74ac38a commit 2d91b14

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

src/commands/start.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
type ErrorTrackingModule = typeof import('../error-tracking');
33
type IndexTypeModule = typeof import('../index');
44

5+
import * as path from 'path';
6+
import { promises as fs } from 'fs'
7+
import * as semver from 'semver';
8+
import * as rimraf from 'rimraf';
9+
510
import { IS_PROD_BUILD } from '../constants';
611

712
function maybeBundleImport<T>(moduleName: string): T {
@@ -40,6 +45,8 @@ class HttpToolkitServer extends Command {
4045
async run() {
4146
const { flags } = this.parse(HttpToolkitServer);
4247

48+
this.cleanupOldServers(); // Async cleanup old server versions
49+
4350
await runHTK({
4451
configPath: flags.config,
4552
authToken: flags.token
@@ -48,6 +55,66 @@ class HttpToolkitServer extends Command {
4855
throw error;
4956
});
5057
}
58+
59+
// On startup, we want to kill any downloaded servers that are not longer necessary
60+
async cleanupOldServers() {
61+
const { dataDir, version: currentVersion } = this.config;
62+
63+
const serverUpdatesPath = process.env.OCLIF_CLIENT_HOME ||
64+
path.join(dataDir, 'client');
65+
66+
// Be careful - if the server path isn't clearly ours somehow, ignore it.
67+
if (!serverUpdatesPath.split(path.sep).includes('httptoolkit-server')) {
68+
reportError(`Unexpected server path (${serverUpdatesPath}), ignoring`);
69+
return;
70+
}
71+
72+
const serverPaths= await fs.readdir(serverUpdatesPath)
73+
.catch((e) => {
74+
if (e.code === 'ENOENT') return null;
75+
else throw e;
76+
});
77+
if (!serverPaths) return; // No server update path means we're all good
78+
79+
// Similarly, if the folder contains anything unexpected, be careful and do nothing.
80+
if (serverPaths.some((filename) =>
81+
!semver.valid(filename.replace(/\.partial\.\d+$/, '')) &&
82+
filename !== 'bin' &&
83+
filename !== 'current'
84+
)) {
85+
console.log(serverPaths);
86+
reportError(
87+
`Server path (${serverUpdatesPath}) contains unexpected content, ignoring`
88+
);
89+
return;
90+
}
91+
92+
if (serverPaths.every((filename) => {
93+
const version = semver.valid(filename.replace(/\.partial\.\d+$/, ''));
94+
return !version || semver.lt(version, currentVersion);
95+
})) {
96+
// If everything is outdated, just drop the whole folder. Useful if you start
97+
// a new server standalone (not just from an update), because otherwise the
98+
// update dir can end up in a broken state. Better to clear it completely.
99+
console.log("Downloaded server directory is entirely outdated, deleting it");
100+
rimraf(serverUpdatesPath, (error) => {
101+
if (error) reportError(error);
102+
});
103+
} else {
104+
// Some of the servers are outdated, but not all (maybe it includes us).
105+
// Async delete all server versions older than this currently running version.
106+
serverPaths.forEach((filename) => {
107+
const version = semver.valid(filename.replace(/\.partial\.\d+$/, ''));
108+
109+
if (version && semver.lt(version, currentVersion)) {
110+
console.log(`Deleting old server ${filename}`);
111+
rimraf(path.join(serverUpdatesPath, filename), (error) => {
112+
if (error) reportError(error);
113+
});
114+
}
115+
});
116+
}
117+
}
51118
}
52119

53120
export = HttpToolkitServer;

0 commit comments

Comments
 (0)