Skip to content

Commit

Permalink
Merge pull request #66 from unyt-org/fix-local-pointers-in-storage
Browse files Browse the repository at this point in the history
Fix local pointers in storage
  • Loading branch information
benStre authored Jan 25, 2024
2 parents 3dadca0 + f479fd5 commit 884409e
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 5 deletions.
2 changes: 2 additions & 0 deletions init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ export async function init() {
// has only local endpoint id (%0000) or global id?
if (endpoint != LOCAL_ENDPOINT) {
Pointer.is_local = false;
// update storage entries that contain pointers with unresolved @@local origin
Storage.updateEntriesWithUnresolvedLocalDependencies();
// init subscriber cache as soon as endpoint is available
initSubscriberCache();
}
Expand Down
5 changes: 3 additions & 2 deletions runtime/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1830,8 +1830,9 @@ export class Runtime {
}
// other message, assume sender endpoint is online now
else {
// HELLO message received, regard as new login to network, reset previous subscriptions
if (header.type == ProtocolDataType.HELLO && !header.sender.ignoreHello) Pointer.clearEndpointSubscriptions(header.sender)
// TODO: HELLO message received, regard as new login to network, reset previous subscriptions?
// does not work correctly because valid subscriptions are reset after HELLO message is received after some time
// if (header.type == ProtocolDataType.HELLO && !header.sender.ignoreHello) Pointer.clearEndpointSubscriptions(header.sender)
header.sender.setOnline(true)
}
}
Expand Down
48 changes: 46 additions & 2 deletions runtime/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { LOCAL_ENDPOINT } from "../types/addressing.ts";
import { ESCAPE_SEQUENCES } from "../utils/logger.ts";
import { StorageMap } from "../types/storage_map.ts";
import { StorageSet } from "../types/storage_set.ts";
import { IterableWeakSet } from "../utils/iterable-weak-set.ts";


// displayInit();
Expand Down Expand Up @@ -377,6 +378,9 @@ export class Storage {
return this.trusted_location;
}

static #unresolvedLocalItems = new Map<string, unknown>()
static #unresolvedLocalPointers = new IterableWeakSet<Pointer>()


static setItem(key:string, value:any, listen_for_pointer_changes = true, location:StorageLocation|null|undefined = this.#primary_location):Promise<boolean>|boolean {
Storage.cache.set(key, value); // save in cache
Expand All @@ -391,23 +395,61 @@ export class Storage {
else return false;
}

static async setItemAsync(location:AsyncStorageLocation, key: string,value: unknown,listen_for_pointer_changes: boolean) {
static async setItemAsync(location:AsyncStorageLocation, key: string, value: unknown,listen_for_pointer_changes: boolean) {
this.setDirty(location, true)
// store value (might be pointer reference)
const dependencies = await location.setItem(key, value);
if (Pointer.is_local) this.checkUnresolvedLocalDependenciesForItem(key, value, dependencies);
this.updateItemDependencies(key, [...dependencies].map(p=>p.id));
await this.saveDependencyPointersAsync(dependencies, listen_for_pointer_changes, location);
this.setDirty(location, false)
return true;
}

static setItemSync(location:SyncStorageLocation, key: string,value: unknown,listen_for_pointer_changes: boolean) {
static setItemSync(location:SyncStorageLocation, key: string, value: unknown,listen_for_pointer_changes: boolean) {
const dependencies = location.setItem(key, value);
if (Pointer.is_local) this.checkUnresolvedLocalDependenciesForItem(key, value, dependencies);
this.updateItemDependencies(key, [...dependencies].map(p=>p.id));
this.saveDependencyPointersSync(dependencies, listen_for_pointer_changes, location);
return true;
}

/**
* Collects all pointer dependencies of an itemr entry with a @@local origin.
* Once the endpoint is initialized, the entry is updated with the correct pointer ids.
*/
private static checkUnresolvedLocalDependenciesForItem(key: string, value:unknown, dependencies: Set<Pointer>) {
const hasUnresolvedLocalDependency = [...dependencies].some(p=>p.origin == LOCAL_ENDPOINT);
if (hasUnresolvedLocalDependency) this.#unresolvedLocalItems.set(key, value);
}

/**
* Collects all pointer dependencies of a pointer entry with a @@local origin.
* Once the endpoint is initialized, the entry is updated with the correct pointer ids.
*/
private static checkUnresolvedLocalDependenciesForPointer(pointer: Pointer, dependencies: Set<Pointer>) {
const hasUnresolvedLocalDependency = [...dependencies].some(p=>p.origin == LOCAL_ENDPOINT);
if (hasUnresolvedLocalDependency) this.#unresolvedLocalPointers.add(pointer);
}

/**
* Updates all item/pointer entries in storage that still are stored with unresolved @@local pointers
*/
static updateEntriesWithUnresolvedLocalDependencies() {
for (const [key, value] of this.#unresolvedLocalItems) {
logger.debug("update item containing pointers with @@local origin: " + key)
this.setItem(key, value)
}
this.#unresolvedLocalItems.clear()

for (const ptr of this.#unresolvedLocalPointers) {
logger.debug("update pointer containing pointers with @@local origin: " + ptr.idString())
this.setPointer(ptr as Pointer)
}
this.#unresolvedLocalPointers.clear()
}


public static setPointer(pointer:Pointer, listen_for_changes = true, location:StorageLocation|undefined = this.#primary_location, partialUpdateKey: unknown = NOT_EXISTING): Promise<boolean>|boolean {
if (!pointer.value_initialized) {
// logger.warn("pointer value " + pointer.idString() + " not available, cannot save in storage");
Expand All @@ -428,6 +470,7 @@ export class Storage {

const dependencies = this.updatePointerSync(location, pointer, partialUpdateKey);
dependencies.delete(pointer);
if (Pointer.is_local) this.checkUnresolvedLocalDependenciesForPointer(pointer, dependencies);
this.updatePointerDependencies(pointer.id, [...dependencies].map(p=>p.id));
this.saveDependencyPointersSync(dependencies, listen_for_changes, location);

Expand All @@ -448,6 +491,7 @@ export class Storage {

const dependencies = await this.updatePointerAsync(location, pointer, partialUpdateKey);
dependencies.delete(pointer);
if (Pointer.is_local) this.checkUnresolvedLocalDependenciesForPointer(pointer, dependencies);
this.updatePointerDependencies(pointer.id, [...dependencies].map(p=>p.id));
await this.saveDependencyPointersAsync(dependencies, listen_for_changes, location);

Expand Down
5 changes: 4 additions & 1 deletion types/addressing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,10 @@ export class Endpoint extends Target {
return this.#entrypoint = Runtime.Blockchain.getEndpointDefault(this);
}

public async getAlias(){
public async getAlias(useCache = true){
// use cached alias
if (this.#alias && useCache) return this.#alias;

// resolve alias from Blockchain
try {
this.#alias = <string | undefined> await Runtime.Blockchain.resolveAlias(this);
Expand Down

0 comments on commit 884409e

Please sign in to comment.