fix: add 8s timeout to NeoInstituteContext school node fetch
Races the SchoolNeoDBService.getSchoolNode() call against an 8-second timeout. If Neo4j is slow or unavailable the workspace now loads within seconds rather than waiting for the full axios 120s timeout. The context degrades gracefully — workspace opens without institute data, error is logged as a warning not an exception. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d3c2a9bdff
commit
ab1f8111f6
@ -5,6 +5,8 @@ import { SchoolNeoDBService } from '../services/graph/schoolNeoDBService';
|
|||||||
import { CCSchoolNodeProps } from '../utils/tldraw/cc-base/cc-graph/cc-graph-types';
|
import { CCSchoolNodeProps } from '../utils/tldraw/cc-base/cc-graph/cc-graph-types';
|
||||||
import { logger } from '../debugConfig';
|
import { logger } from '../debugConfig';
|
||||||
|
|
||||||
|
const NEO_INSTITUTE_TIMEOUT_MS = 8000;
|
||||||
|
|
||||||
export interface NeoInstituteContextType {
|
export interface NeoInstituteContextType {
|
||||||
schoolNode: CCSchoolNodeProps | null;
|
schoolNode: CCSchoolNodeProps | null;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
@ -22,7 +24,7 @@ const NeoInstituteContext = createContext<NeoInstituteContextType>({
|
|||||||
export const NeoInstituteProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
|
export const NeoInstituteProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const { profile, isInitialized: isUserInitialized } = useUser();
|
const { profile, isInitialized: isUserInitialized } = useUser();
|
||||||
|
|
||||||
const [schoolNode, setSchoolNode] = useState<CCSchoolNodeProps | null>(null);
|
const [schoolNode, setSchoolNode] = useState<CCSchoolNodeProps | null>(null);
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [isInitialized, setIsInitialized] = useState(false);
|
const [isInitialized, setIsInitialized] = useState(false);
|
||||||
@ -35,7 +37,7 @@ export const NeoInstituteProvider: React.FC<{ children: ReactNode }> = ({ childr
|
|||||||
hasUser: !!user,
|
hasUser: !!user,
|
||||||
isInitialized
|
isInitialized
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait for user profile to be ready
|
// Wait for user profile to be ready
|
||||||
if (!isUserInitialized) {
|
if (!isUserInitialized) {
|
||||||
logger.debug('neo-institute-context', '⏳ Waiting for user initialization...');
|
logger.debug('neo-institute-context', '⏳ Waiting for user initialization...');
|
||||||
@ -58,7 +60,17 @@ export const NeoInstituteProvider: React.FC<{ children: ReactNode }> = ({ childr
|
|||||||
userEmail: user?.email
|
userEmail: user?.email
|
||||||
});
|
});
|
||||||
|
|
||||||
const node = await SchoolNeoDBService.getSchoolNode(profile.school_db_name);
|
// Race the Neo4j call against a timeout so a slow/unavailable Neo4j
|
||||||
|
// never blocks the workspace from loading for more than 8 seconds.
|
||||||
|
const timeoutPromise = new Promise<null>((_, reject) =>
|
||||||
|
setTimeout(() => reject(new Error(`Neo4j timed out after ${NEO_INSTITUTE_TIMEOUT_MS}ms`)), NEO_INSTITUTE_TIMEOUT_MS)
|
||||||
|
);
|
||||||
|
|
||||||
|
const node = await Promise.race([
|
||||||
|
SchoolNeoDBService.getSchoolNode(profile.school_db_name),
|
||||||
|
timeoutPromise
|
||||||
|
]);
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
setSchoolNode(node);
|
setSchoolNode(node);
|
||||||
logger.debug('neo-institute-context', '✅ School node loaded', {
|
logger.debug('neo-institute-context', '✅ School node loaded', {
|
||||||
@ -71,7 +83,7 @@ export const NeoInstituteProvider: React.FC<{ children: ReactNode }> = ({ childr
|
|||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = error instanceof Error ? error.message : 'Failed to load school node';
|
const errorMessage = error instanceof Error ? error.message : 'Failed to load school node';
|
||||||
logger.error('neo-institute-context', '❌ Failed to load school node', {
|
logger.warn('neo-institute-context', '⚠️ School node unavailable — workspace will load without institute data', {
|
||||||
error: errorMessage,
|
error: errorMessage,
|
||||||
schoolDbName: profile.school_db_name
|
schoolDbName: profile.school_db_name
|
||||||
});
|
});
|
||||||
@ -79,7 +91,7 @@ export const NeoInstituteProvider: React.FC<{ children: ReactNode }> = ({ childr
|
|||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
setIsInitialized(true);
|
setIsInitialized(true);
|
||||||
logger.debug('neo-institute-context', '✅ Institute context initialization complete');
|
logger.debug('neo-institute-context', '✅ Institute context initialization complete');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user