Skip to content

Commit bac7bbf

Browse files
committed
Async browser cache update, rather than resetting daily
This boosts startup performance (could get up to 1s on Linux when the cache was empty/reset), but still ensures we get fresh browser data shortly after every startup (typically the 2nd check - 10s).
1 parent 3726375 commit bac7bbf

File tree

1 file changed

+35
-29
lines changed

1 file changed

+35
-29
lines changed

src/browsers.ts

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,61 +3,67 @@ import * as path from 'path';
33
import { promisify } from 'util';
44

55
import * as getBrowserLauncherCb from '@httptoolkit/browser-launcher';
6-
import { LaunchOptions, Launch, BrowserInstance, Browser } from '@httptoolkit/browser-launcher';
6+
import {
7+
LaunchOptions,
8+
Launch,
9+
BrowserInstance,
10+
Browser,
11+
update as updateBrowserCacheCb
12+
} from '@httptoolkit/browser-launcher';
713

814
import { reportError } from './error-tracking';
9-
import { readFile, statFile, deleteFile } from './util';
15+
import { readFile, deleteFile, delay } from './util';
1016

1117
const getBrowserLauncher = promisify(getBrowserLauncherCb);
18+
const updateBrowserCache: (configPath: string) => Promise<unknown> = promisify(updateBrowserCacheCb);
1219

1320
const browserConfigPath = (configPath: string) => path.join(configPath, 'browsers.json');
1421

1522
export { BrowserInstance, Browser };
1623

1724
export async function checkBrowserConfig(configPath: string) {
1825
// It's not clear why, but sometimes the browser config can become corrupted, so it's not valid JSON
19-
// If that happens JBL doesn't catch it, so we crash. To avoid that, we check it here on startup.
26+
// If that happens browser-launcher can hit issues. To avoid that entirely, we check it here on startup.
2027

2128
const browserConfig = browserConfigPath(configPath);
22-
return Promise.all([
23-
// Check the file is readable and parseable
24-
readFile(browserConfig, 'utf8')
25-
.then((contents) => JSON.parse(contents)),
26-
27-
// Check the file is relatively recent
28-
statFile(browserConfig)
29-
.then((stats) => {
30-
if (Date.now() - stats.mtime.valueOf() > 1000 * 60 * 60 * 24) {
31-
return deleteFile(browserConfig).catch((err) => {
32-
console.error('Failed to clear outdated config file');
33-
reportError(err);
34-
});
35-
};
36-
})
37-
])
38-
.catch((error) => {
29+
30+
try {
31+
const rawConfig = await readFile(browserConfig, 'utf8');
32+
JSON.parse(rawConfig);
33+
} catch (error) {
3934
if (error.code === 'ENOENT') return;
35+
console.warn(`Failed to read browser config cache from ${browserConfig}, clearing.`, error);
4036

41-
console.warn('Failed to read browser config on startup', error);
4237
return deleteFile(browserConfig).catch((err) => {
43-
// We can have a race if the file was invalid AND old, which case we can get a parse error
44-
// and have deleted the file already. Regardless: it's now gone, so we're all good.
38+
// There may be possible races around here - as long as the file's gone, we're happy
4539
if (err.code === 'ENOENT') return;
46-
4740
console.error('Failed to clear broken config file:', err);
4841
reportError(err);
4942
});
50-
})
43+
}
5144
}
5245

5346
let launcher: Promise<Launch> | undefined;
5447

5548
function getLauncher(configPath: string) {
5649
if (!launcher) {
57-
const start = Date.now();
58-
console.log('Getting launcher...');
59-
launcher = getBrowserLauncher(browserConfigPath(configPath));
60-
launcher.then(() => console.log(`Got launcher, took ${Date.now() - start}ms`));
50+
const browserConfig = browserConfigPath(configPath);
51+
launcher = getBrowserLauncher(browserConfig);
52+
53+
launcher.then(async () => {
54+
// Async after first creating the launcher, we trigger a background cache update.
55+
// This can be *synchronously* expensive (spawns 10s of procs, 10+ms sync per
56+
// spawn on unix-based OSs) so defer briefly.
57+
await delay(2000);
58+
try {
59+
await updateBrowserCache(browserConfig);
60+
console.log('Browser cache updated');
61+
// Need to reload the launcher after updating the cache:
62+
launcher = getBrowserLauncher(browserConfig);
63+
} catch (e) {
64+
reportError(e)
65+
}
66+
});
6167

6268
// Reset & retry if this fails somehow:
6369
launcher.catch((e) => {

0 commit comments

Comments
 (0)