@@ -3,61 +3,67 @@ import * as path from 'path';
3
3
import { promisify } from 'util' ;
4
4
5
5
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' ;
7
13
8
14
import { reportError } from './error-tracking' ;
9
- import { readFile , statFile , deleteFile } from './util' ;
15
+ import { readFile , deleteFile , delay } from './util' ;
10
16
11
17
const getBrowserLauncher = promisify ( getBrowserLauncherCb ) ;
18
+ const updateBrowserCache : ( configPath : string ) => Promise < unknown > = promisify ( updateBrowserCacheCb ) ;
12
19
13
20
const browserConfigPath = ( configPath : string ) => path . join ( configPath , 'browsers.json' ) ;
14
21
15
22
export { BrowserInstance , Browser } ;
16
23
17
24
export async function checkBrowserConfig ( configPath : string ) {
18
25
// 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.
20
27
21
28
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 ) {
39
34
if ( error . code === 'ENOENT' ) return ;
35
+ console . warn ( `Failed to read browser config cache from ${ browserConfig } , clearing.` , error ) ;
40
36
41
- console . warn ( 'Failed to read browser config on startup' , error ) ;
42
37
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
45
39
if ( err . code === 'ENOENT' ) return ;
46
-
47
40
console . error ( 'Failed to clear broken config file:' , err ) ;
48
41
reportError ( err ) ;
49
42
} ) ;
50
- } )
43
+ }
51
44
}
52
45
53
46
let launcher : Promise < Launch > | undefined ;
54
47
55
48
function getLauncher ( configPath : string ) {
56
49
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
+ } ) ;
61
67
62
68
// Reset & retry if this fails somehow:
63
69
launcher . catch ( ( e ) => {
0 commit comments