@@ -52,6 +52,17 @@ function isAccountBusyForProbe(account) {
5252 return accountInflight ( account ) > 0 || accountMaintenance ( account ) > 0 || accountLsMaintenance ( account ) > 0 ;
5353}
5454
55+ function maintenanceBusyReason ( account ) {
56+ if ( accountInflight ( account ) > 0 ) return 'account_inflight' ;
57+ if ( accountMaintenance ( account ) > 0 ) return 'account_maintenance' ;
58+ if ( accountLsMaintenance ( account ) > 0 ) return 'ls_maintenance' ;
59+ return '' ;
60+ }
61+
62+ function shouldSkipBusyBackgroundMaintenance ( ) {
63+ return process . env . WINDSURFAPI_BACKGROUND_MAINTENANCE_SKIP_BUSY !== '0' ;
64+ }
65+
5566function isAccountInMaintenance ( account ) {
5667 return accountMaintenance ( account ) > 0 || accountLsMaintenance ( account ) > 0 ;
5768}
@@ -1400,10 +1411,17 @@ export async function refreshCredits(id) {
14001411 }
14011412}
14021413
1403- export async function refreshAllCredits ( ) {
1414+ export async function refreshAllCredits ( { skipBusy = false } = { } ) {
14041415 const results = [ ] ;
14051416 for ( const a of accounts ) {
14061417 if ( a . status !== 'active' ) continue ;
1418+ if ( skipBusy ) {
1419+ const busyReason = maintenanceBusyReason ( a ) ;
1420+ if ( busyReason ) {
1421+ results . push ( { id : a . id , email : a . email , ok : false , skipped : true , reason : busyReason } ) ;
1422+ continue ;
1423+ }
1424+ }
14071425 const r = await refreshCredits ( a . id ) ;
14081426 results . push ( { id : a . id , email : a . email , ok : r . ok , error : r . error } ) ;
14091427 }
@@ -1931,10 +1949,17 @@ export function emitNoAuthWarnings(bindHost = '0.0.0.0') {
19311949 * Refresh Firebase tokens for all accounts that have a stored refreshToken.
19321950 * Re-registers with Codeium to get a fresh API key and updates the account.
19331951 */
1934- async function refreshAllFirebaseTokens ( ) {
1952+ async function refreshAllFirebaseTokens ( { skipBusy = false } = { } ) {
19351953 const { refreshFirebaseToken, reRegisterWithCodeium } = await import ( './dashboard/windsurf-login.js' ) ;
19361954 for ( const a of accounts ) {
19371955 if ( a . status !== 'active' || ! a . refreshToken ) continue ;
1956+ if ( skipBusy ) {
1957+ const busyReason = maintenanceBusyReason ( a ) ;
1958+ if ( busyReason ) {
1959+ log . debug ( `Firebase refresh ${ a . id } skipped: ${ busyReason } ` ) ;
1960+ continue ;
1961+ }
1962+ }
19381963 try {
19391964 const proxy = getEffectiveProxy ( a . id ) || null ;
19401965 const { idToken, refreshToken : newRefresh } = await refreshFirebaseToken ( a . refreshToken , proxy ) ;
@@ -2002,9 +2027,10 @@ export async function initAuth() {
20022027 // Periodic credit refresh (every 15 min). First run is fire-and-forget so
20032028 // startup isn't blocked by cloud round-trips.
20042029 const CREDIT_INTERVAL = 15 * 60 * 1000 ;
2005- refreshAllCredits ( ) . catch ( e => log . warn ( `Initial credit refresh: ${ e . message } ` ) ) ;
2030+ const skipBusyMaintenance = shouldSkipBusyBackgroundMaintenance ( ) ;
2031+ refreshAllCredits ( { skipBusy : skipBusyMaintenance } ) . catch ( e => log . warn ( `Initial credit refresh: ${ e . message } ` ) ) ;
20062032 setInterval ( ( ) => {
2007- refreshAllCredits ( ) . catch ( e => log . warn ( `Scheduled credit refresh: ${ e . message } ` ) ) ;
2033+ refreshAllCredits ( { skipBusy : skipBusyMaintenance } ) . catch ( e => log . warn ( `Scheduled credit refresh: ${ e . message } ` ) ) ;
20082034 } , CREDIT_INTERVAL ) . unref ?. ( ) ;
20092035
20102036 // Fetch live model catalog from cloud and merge into hardcoded catalog.
@@ -2014,9 +2040,9 @@ export async function initAuth() {
20142040 // Periodic Firebase token refresh (every 50 min). Firebase ID tokens expire
20152041 // after 60 min; refreshing at 50 keeps a comfortable margin.
20162042 const TOKEN_REFRESH_INTERVAL = 50 * 60 * 1000 ;
2017- refreshAllFirebaseTokens ( ) . catch ( e => log . warn ( `Initial token refresh: ${ e . message } ` ) ) ;
2043+ refreshAllFirebaseTokens ( { skipBusy : skipBusyMaintenance } ) . catch ( e => log . warn ( `Initial token refresh: ${ e . message } ` ) ) ;
20182044 setInterval ( ( ) => {
2019- refreshAllFirebaseTokens ( ) . catch ( e => log . warn ( `Scheduled token refresh: ${ e . message } ` ) ) ;
2045+ refreshAllFirebaseTokens ( { skipBusy : skipBusyMaintenance } ) . catch ( e => log . warn ( `Scheduled token refresh: ${ e . message } ` ) ) ;
20202046 } , TOKEN_REFRESH_INTERVAL ) . unref ?. ( ) ;
20212047
20222048 // Warm up the default LS so first chat avoids spawn cost. Proxy-specific
0 commit comments