@@ -14,49 +14,45 @@ import { getGitpodService } from "../service/service";
1414 * @returns void
1515 */
1616async function measureAndPickWorkspaceClusterRegion ( ) : Promise < void > {
17- const eps = await getGitpodService ( ) . server . listWorkspaceClusterRTTEndpoints ( ) ;
17+ const localStorageKey = "measureAndPickWorkspaceClusterRegion.lastMeasurement" ;
1818
19- if ( ! ! eps . lastMeasurement ) {
20- const lrm = Date . parse ( eps . lastMeasurement ) ;
21- if ( Date . now ( ) - lrm < 6 * 60 * 60 * 1000 ) {
22- // we checked within the last six hours. Nothing to do here .
19+ let lastCheck = localStorage . getItem ( localStorageKey ) ;
20+ try {
21+ if ( ! lastCheck || ( Date . now ( ) - Date . parse ( lastCheck ) ) < 6 * 60 * 60 * 1000 ) {
22+ // we've recently done the check .
2323 return ;
2424 }
25+ } catch ( err ) {
26+ // Date.parse can fail ... in which case we assume we haven't done the RTT measurement recently.
2527 }
2628
29+ const eps = await getGitpodService ( ) . server . listWorkspaceClusterRTTEndpoints ( ) ;
30+
2731 const region = await Promise . race ( eps . candidates . map ( ep => measureRTT ( ep . endpoint , ep . region ) ) ) ;
2832 if ( ! region ) {
2933 console . warn ( "did not find a prefered workspace cluster region" ) ;
3034 return ;
3135 }
3236
37+ localStorage . setItem ( localStorageKey , new Date ( ) . toISOString ( ) )
3338 await getGitpodService ( ) . server . setWorkspaceClusterPreferences ( { region } ) ;
3439}
3540
3641async function measureRTT ( endpoint : string , region : string ) : Promise < string | undefined > {
37- const laps = 5 ;
38- let count = 0 ;
39- for ( let i = 0 ; i < laps ; i ++ ) {
40- const controller = new AbortController ( ) ;
41- const abort = setTimeout ( ( ) => controller . abort ( ) , 1000 ) ;
42-
43- try {
44- await fetch ( endpoint , {
45- cache : "no-cache" ,
46- signal : controller . signal ,
47- } ) ;
48- count ++ ;
49- } catch ( err ) {
50- console . debug ( `failed to fetch RTT endpoint ${ endpoint } : ${ err } ` ) ;
51- } finally {
52- clearTimeout ( abort ) ;
53- }
54- }
55-
56- if ( count < 5 ) {
57- // we haven't completed all RTT measurements, hence take a penalty lap.
58- await new Promise ( resolve => setTimeout ( resolve , laps * 1000 ) ) ;
59- return ;
42+ const controller = new AbortController ( ) ;
43+ const abort = setTimeout ( ( ) => controller . abort ( ) , 1000 ) ;
44+
45+ try {
46+ await Promise . all ( Array ( 5 ) . map ( async ( ) => {
47+ try {
48+ await fetch ( endpoint , { cache : "no-cache" , signal : controller . signal , } ) ;
49+ } catch ( err ) {
50+ // we don't want a single error to abort the race. For example, it's ok
51+ // if the RTT endpoints return 404.
52+ }
53+ } ) )
54+ } finally {
55+ clearTimeout ( abort ) ;
6056 }
6157
6258 return region ;
0 commit comments