Skip to content

Commit ffa00cc

Browse files
committed
refactor: Implement concurrent universe data loading strategies and remove Git federation timeout warning.refactor: Implement concurrent universe data loading strategies and remove Git federation timeout warning.
1 parent ee8e8f8 commit ffa00cc

2 files changed

Lines changed: 104 additions & 82 deletions

File tree

src/GitNativeFederation.jsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,8 @@ const GitNativeFederation = ({ variant = 'panel', onRequestClose }) => {
324324

325325
if (didTimeout) {
326326
gfWarn('[GF-DEBUG] Federation state refresh timed out, continuing without blocking UI');
327-
setSyncStatus({
328-
type: 'warning',
329-
message: 'Taking longer than expected to refresh Git federation. UI remains usable; latest data will catch up shortly.'
330-
});
327+
// Warning removed per user request - silent degradation
328+
// setSyncStatus({ ... });
331329
setError(null);
332330

333331
statePromise

src/services/universeBackend.js

Lines changed: 102 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2895,102 +2895,126 @@ class UniverseBackend {
28952895
}
28962896
}
28972897

2898-
// Try primary source first
2899-
if (sourceOfTruth === SOURCE_OF_TRUTH.GIT && universe.gitRepo.enabled) {
2900-
try {
2901-
const gitData = await this.loadFromGit(universe);
2902-
if (gitData) return this.syncAndReturn(universe, gitData, {
2903-
force: sourceOfTruth === SOURCE_OF_TRUTH.GIT,
2904-
source: SOURCE_OF_TRUTH.GIT,
2905-
allowPermissionPrompt
2906-
});
2907-
} catch (error) {
2908-
gfWarn('[UniverseBackend] Git load failed, trying fallback:', error);
2909-
// Direct-read fallback when engine isn't configured yet
2910-
try {
2911-
const directGitData = await this.loadFromGitDirect(universe);
2912-
if (directGitData) return this.syncAndReturn(universe, directGitData, {
2913-
force: sourceOfTruth === SOURCE_OF_TRUTH.GIT,
2914-
source: SOURCE_OF_TRUTH.GIT,
2915-
allowPermissionPrompt
2916-
});
2917-
} catch (fallbackError) {
2918-
gfWarn('[UniverseBackend] Direct Git fallback failed:', fallbackError);
2919-
}
2920-
}
2921-
}
2922-
2923-
if (sourceOfTruth === SOURCE_OF_TRUTH.LOCAL && universe.localFile.enabled) {
2924-
try {
2925-
const localData = await this.loadFromLocalFile(universe, { allowPermissionPrompt });
2926-
if (localData) return this.syncAndReturn(universe, localData, {
2927-
force: sourceOfTruth === SOURCE_OF_TRUTH.LOCAL,
2898+
// Race loading strategies for maximum speed
2899+
// Strategy:
2900+
// 1. If Local is enabled and has handle, try it immediately (fastest path)
2901+
// 2. Concurrently try Git if enabled
2902+
// 3. Concurrently try Browser Storage as backup
2903+
// 4. Return the first successful 'authoritative' result if possible, or best available
2904+
2905+
const loadPromies = [];
2906+
2907+
// 1. Local Load (High Priority)
2908+
if (universe.localFile?.enabled) {
2909+
loadPromies.push(
2910+
this.loadFromLocalFile(universe, { allowPermissionPrompt })
2911+
.then(data => ({ source: SOURCE_OF_TRUTH.LOCAL, data, error: null }))
2912+
.catch(error => ({ source: SOURCE_OF_TRUTH.LOCAL, data: null, error }))
2913+
);
2914+
}
2915+
2916+
// 2. Git Load (Medium Priority - Network bound)
2917+
// Only fetch if Git is explicitly enabled AND has a linked repository
2918+
const hasLinkedGitRepo = universe.gitRepo?.enabled && universe.gitRepo?.linkedRepo && universe.gitRepo?.repo;
2919+
2920+
if (hasLinkedGitRepo) {
2921+
const gitPromise = this.loadFromGit(universe)
2922+
.catch(() => this.loadFromGitDirect(universe)) // Try direct fallback
2923+
.then(data => ({ source: SOURCE_OF_TRUTH.GIT, data, error: null }))
2924+
.catch(error => ({ source: SOURCE_OF_TRUTH.GIT, data: null, error }));
2925+
loadPromies.push(gitPromise);
2926+
}
2927+
2928+
// 3. Browser Storage (Low Priority / Backup)
2929+
if (universe.browserStorage?.enabled) {
2930+
loadPromies.push(
2931+
this.loadFromBrowserStorage(universe)
2932+
.then(data => ({ source: SOURCE_OF_TRUTH.BROWSER, data, error: null }))
2933+
.catch(error => ({ source: SOURCE_OF_TRUTH.BROWSER, data: null, error }))
2934+
);
2935+
}
2936+
2937+
if (loadPromies.length === 0) {
2938+
gfWarn('[UniverseBackend] No storage methods enabled, creating empty state');
2939+
return this.createEmptyState();
2940+
}
2941+
2942+
// Wait for all attempts to settle, but we can be smart about which one we pick
2943+
// (In a future iteration we could use Promise.race for even faster UI, but we need to respect Source of Truth)
2944+
const results = await Promise.all(loadPromies);
2945+
const resultsMap = new Map(results.map(r => [r.source, r]));
2946+
2947+
// Decision Logic:
2948+
2949+
// A. If Source of Truth is LOCAL and it succeeded, use it directly.
2950+
if (sourceOfTruth === SOURCE_OF_TRUTH.LOCAL) {
2951+
const localRes = resultsMap.get(SOURCE_OF_TRUTH.LOCAL);
2952+
if (localRes?.data) {
2953+
return this.syncAndReturn(universe, localRes.data, {
2954+
force: true,
29282955
source: SOURCE_OF_TRUTH.LOCAL,
29292956
allowPermissionPrompt
29302957
});
2931-
} catch (error) {
2958+
} else if (localRes?.error) {
2959+
// If local failed with specific permission/missing error, rethrow to trigger UI prompt
29322960
if (
2933-
error?.code === LOCAL_FILE_ERROR.PERMISSION ||
2934-
error?.code === LOCAL_FILE_ERROR.MISSING ||
2935-
error?.code === LOCAL_FILE_ERROR.NOT_FOUND
2961+
localRes.error?.code === LOCAL_FILE_ERROR.PERMISSION ||
2962+
localRes.error?.code === LOCAL_FILE_ERROR.MISSING ||
2963+
localRes.error?.code === LOCAL_FILE_ERROR.NOT_FOUND
29362964
) {
2937-
gfWarn('[UniverseBackend] Local file load blocked by access issue:', error.message);
2938-
throw error;
2965+
gfWarn('[UniverseBackend] Primary Local load blocked:', localRes.error.message);
2966+
throw localRes.error;
29392967
}
2940-
gfWarn('[UniverseBackend] Local file load failed, trying fallback:', error);
29412968
}
29422969
}
29432970

2944-
// Try fallback sources
2945-
if (sourceOfTruth !== SOURCE_OF_TRUTH.LOCAL && universe.localFile.enabled) {
2946-
try {
2947-
const localData = await this.loadFromLocalFile(universe, { allowPermissionPrompt });
2948-
if (localData) return this.syncAndReturn(universe, localData, {
2949-
force: sourceOfTruth === SOURCE_OF_TRUTH.LOCAL,
2950-
source: SOURCE_OF_TRUTH.LOCAL,
2971+
// B. If Source of Truth is GIT and it succeeded, use it.
2972+
if (sourceOfTruth === SOURCE_OF_TRUTH.GIT) {
2973+
const gitRes = resultsMap.get(SOURCE_OF_TRUTH.GIT);
2974+
if (gitRes?.data) {
2975+
return this.syncAndReturn(universe, gitRes.data, {
2976+
force: true,
2977+
source: SOURCE_OF_TRUTH.GIT,
29512978
allowPermissionPrompt
29522979
});
2953-
} catch (error) {
2954-
if (
2955-
error?.code === LOCAL_FILE_ERROR.PERMISSION ||
2956-
error?.code === LOCAL_FILE_ERROR.NOT_FOUND
2957-
) {
2958-
gfWarn('[UniverseBackend] Local fallback skipped due to permission requirement:', error.message);
2959-
} else {
2960-
gfWarn('[UniverseBackend] Local fallback failed:', error);
2961-
}
29622980
}
29632981
}
29642982

2965-
if (sourceOfTruth !== SOURCE_OF_TRUTH.GIT && universe.gitRepo.enabled) {
2966-
try {
2967-
const gitData = await this.loadFromGit(universe);
2968-
if (gitData) return this.syncAndReturn(universe, gitData, {
2969-
source: SOURCE_OF_TRUTH.GIT,
2970-
throttleMs: 0,
2971-
allowPermissionPrompt
2972-
});
2973-
} catch (error) {
2974-
gfWarn('[UniverseBackend] Git fallback failed:', error);
2975-
}
2983+
// C. Fallbacks (Cross-Loading):
2984+
// If Source of Truth failed, try the backups in order of speed/reliability: Local > Git > Browser
2985+
2986+
// Try Local fallback
2987+
const localRes = resultsMap.get(SOURCE_OF_TRUTH.LOCAL);
2988+
if (localRes?.data) {
2989+
gfLog('[UniverseBackend] Using Local fallback (Primary unavailable)');
2990+
return this.syncAndReturn(universe, localRes.data, {
2991+
source: SOURCE_OF_TRUTH.LOCAL,
2992+
allowPermissionPrompt
2993+
});
29762994
}
29772995

2978-
// Browser storage fallback for mobile
2979-
if (universe.browserStorage.enabled) {
2980-
try {
2981-
const browserData = await this.loadFromBrowserStorage(universe);
2982-
if (browserData) return this.syncAndReturn(universe, browserData, {
2983-
source: SOURCE_OF_TRUTH.BROWSER,
2984-
throttleMs: 0,
2985-
allowPermissionPrompt
2986-
});
2987-
} catch (error) {
2988-
gfWarn('[UniverseBackend] Browser storage fallback failed:', error);
2989-
}
2996+
// Try Git fallback
2997+
const gitRes = resultsMap.get(SOURCE_OF_TRUTH.GIT);
2998+
if (gitRes?.data) {
2999+
gfLog('[UniverseBackend] Using Git fallback (Primary unavailable)');
3000+
return this.syncAndReturn(universe, gitRes.data, {
3001+
source: SOURCE_OF_TRUTH.GIT,
3002+
allowPermissionPrompt
3003+
});
3004+
}
3005+
3006+
// Try Browser fallback
3007+
const browserRes = resultsMap.get(SOURCE_OF_TRUTH.BROWSER);
3008+
if (browserRes?.data) {
3009+
gfLog('[UniverseBackend] Using Browser Storage fallback');
3010+
return this.syncAndReturn(universe, browserRes.data, {
3011+
source: SOURCE_OF_TRUTH.BROWSER,
3012+
allowPermissionPrompt
3013+
});
29903014
}
29913015

2992-
// Return empty state if nothing works
2993-
gfWarn('[UniverseBackend] All load methods failed, creating empty state');
3016+
// Return empty state if absolutely everything failed
3017+
gfWarn('[UniverseBackend] All parallel load methods failed, creating empty state');
29943018
return this.createEmptyState();
29953019
}
29963020

0 commit comments

Comments
 (0)