fix(8.0): gate native graph analytics on the provider readiness flag
The optional native graph-acceleration provider exposes `isInitialized`, which is false during its cold-start / rebuild window (engine + cursor not yet loaded). The accessor cached the resolved provider INSTANCE but never re-checked readiness, so `brain.graph.*` could dispatch to a not-ready provider and throw instead of answering. Resolve and cache the instance once, but check `isInitialized` LIVE on every call: route to the pure-TS analytics path while the provider is not ready, and re-engage the native path automatically the moment it flips true. This gates every native route at once — subgraph, export, rank, communities, path, and the query→expand fusion. Adds a test asserting the provider is never called (and the TS fallback returns real answers) while not ready. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
bf0afe8563
commit
d321cf5f33
2 changed files with 65 additions and 19 deletions
|
|
@ -3299,25 +3299,30 @@ export class Brainy<T = any> implements BrainyInterface<T> {
|
|||
|
||||
/** Resolve the optional native graph-acceleration provider (feature-detected). */
|
||||
private graphAccelerationProvider(): GraphAccelerationProvider | undefined {
|
||||
if (this._graphAccelProvider !== undefined) {
|
||||
return this._graphAccelProvider ?? undefined
|
||||
}
|
||||
// Resolve the optional 'graphAcceleration' provider once and cache it. Accept
|
||||
// EITHER a ready instance OR a `(storage) => provider` factory (the convention
|
||||
// the graphIndex/metadataIndex/vector providers use) — a registered factory
|
||||
// would otherwise fail the isGraphAccelerationProvider duck-test and the native
|
||||
// path would silently never engage.
|
||||
const raw = this.pluginRegistry.getProvider<unknown>('graphAcceleration')
|
||||
let resolved: unknown = raw
|
||||
if (typeof raw === 'function' && !isGraphAccelerationProvider(raw)) {
|
||||
try {
|
||||
resolved = (raw as (storage: StorageAdapter) => unknown)(this.storage)
|
||||
} catch {
|
||||
resolved = undefined
|
||||
// Resolve + cache the provider INSTANCE once. Accept EITHER a ready instance OR
|
||||
// a `(storage) => provider` factory (the convention the graphIndex/metadataIndex/
|
||||
// vector providers use) — a registered factory would otherwise fail the
|
||||
// isGraphAccelerationProvider duck-test and the native path would silently never engage.
|
||||
if (this._graphAccelProvider === undefined) {
|
||||
const raw = this.pluginRegistry.getProvider<unknown>('graphAcceleration')
|
||||
let resolved: unknown = raw
|
||||
if (typeof raw === 'function' && !isGraphAccelerationProvider(raw)) {
|
||||
try {
|
||||
resolved = (raw as (storage: StorageAdapter) => unknown)(this.storage)
|
||||
} catch {
|
||||
resolved = undefined
|
||||
}
|
||||
}
|
||||
this._graphAccelProvider = isGraphAccelerationProvider(resolved) ? resolved : null
|
||||
}
|
||||
this._graphAccelProvider = isGraphAccelerationProvider(resolved) ? resolved : null
|
||||
return this._graphAccelProvider ?? undefined
|
||||
const provider = this._graphAccelProvider ?? undefined
|
||||
// Readiness gate — checked LIVE each call, never cached: the native engine sets
|
||||
// `isInitialized` false until its engine + cursor have loaded (the cold-start /
|
||||
// rebuild window). Until then, route to the pure-TS path rather than calling a
|
||||
// not-ready provider (which throws) — and re-engage the native path automatically
|
||||
// the moment `isInitialized` flips true. Gates EVERY `brain.graph.*` route
|
||||
// (subgraph/export/rank/communities/path + the query→expand fusion) at once.
|
||||
return provider && provider.isInitialized ? provider : undefined
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue