Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 39 additions & 3 deletions core/blockstore/attachable-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,19 @@ function isLoadable(unknown: AttachedStores | Loadable): unknown is Loadable {
return !!(unknown as Loadable).sthis && !!(unknown as Loadable).attachedStores;
}

/**
* Create and attach store handles using either a single URI or explicit gateway URL parameters.
*
* Prepares a GatewayUrlsParam from `urlOrGup` (if a `CoerceURI` is provided it is used for all gateways),
* resolves the target AttachedStores from `arOrLoadable` (accepting either an AttachedStores or a Loadable),
* and calls `attach` to produce an Attached instance.
*
* @param urlOrGup - A single URI to use for all gateways or a `GatewayUrlsParam` that specifies per-gateway URLs.
* @param arOrLoadable - An AttachedStores instance or a Loadable whose `attachedStores` will be used.
* @param name - Optional attachment name; defaults to `"local"`.
* @returns The created Attached instance representing the attached stores configured with the provided gateway URLs.
* @throws Error if `urlOrGup` is not provided.
*/
export async function createAttachedStores(
urlOrGup: CoerceURI | GatewayUrlsParam,
arOrLoadable: AttachedStores | Loadable,
Expand Down Expand Up @@ -289,7 +302,7 @@ export async function createAttachedStores(
}

export class AttachedRemotesImpl implements AttachedStores {
private readonly _remotes = new KeyedResolvOnce<Attached>();
private _remotes = new KeyedResolvOnce<Attached>();

readonly loadable: Loadable;
// readonly attactedFileStore: DataStore;
Expand Down Expand Up @@ -330,6 +343,17 @@ export class AttachedRemotesImpl implements AttachedStores {
return new ActiveStoreImpl(this._local.stores as LocalDataAndMetaAndWalStore, this);
}

/**
* Returns the local store if set, or undefined if already reset.
* Use this for safe access during teardown.
*/
localOrUndefined(): LocalActiveStore | undefined {
if (!this._local) {
return undefined;
}
return new ActiveStoreImpl(this._local.stores as LocalDataAndMetaAndWalStore, this);
}

activate(store: DataAndMetaStore | CoerceURI): ActiveStore {
// console.log(
// "activate",
Expand Down Expand Up @@ -374,7 +398,7 @@ export class AttachedRemotesImpl implements AttachedStores {
}

// needed for React Statemanagement
readonly _keyedAttachable = new KeyedResolvOnce<Attached>();
private _keyedAttachable = new KeyedResolvOnce<Attached>();
async attach(attachable: Attachable, onAttach: (at: Attached) => Promise<Attached>): Promise<Attached> {
const keyed = attachable.configHash(this.loadable.blockstoreParent?.crdtParent?.ledgerParent);
// console.log("attach-enter", keyed, this.loadable.blockstoreParent?.crdtParent?.ledgerParent?.name);
Expand Down Expand Up @@ -465,4 +489,16 @@ export class AttachedRemotesImpl implements AttachedStores {
});
return ret;
}
}

/**
* Reset remote attachments for teardown.
* Note: _local is intentionally NOT cleared here because async operations
* (meta stream handler, write queue) may still reference it during shutdown.
* The local store is properly cleaned up via detach().
*/
reset(): void {
this._remotes = new KeyedResolvOnce<Attached>();
this._keyedAttachable = new KeyedResolvOnce<Attached>();
// Don't clear _local - async operations may still need it during shutdown
}
}