From ff09d28c114bf7e0e61144560ebd8c83628ec823 Mon Sep 17 00:00:00 2001 From: benStre Date: Thu, 25 Jan 2024 00:47:11 +0100 Subject: [PATCH 1/5] disable subscription reset on HELLO message --- runtime/runtime.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/runtime/runtime.ts b/runtime/runtime.ts index 6b96faf5..f8f8379a 100644 --- a/runtime/runtime.ts +++ b/runtime/runtime.ts @@ -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) } } From 7868b457ce0f84ca2ae6ce1614d8f9763136c018 Mon Sep 17 00:00:00 2001 From: benStre Date: Thu, 25 Jan 2024 00:47:30 +0100 Subject: [PATCH 2/5] enable alias cache per default --- types/addressing.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/types/addressing.ts b/types/addressing.ts index 0bc6b922..627b780e 100644 --- a/types/addressing.ts +++ b/types/addressing.ts @@ -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 = await Runtime.Blockchain.resolveAlias(this); From e8b85a89d3f799d0d33f6d1e5b9c591924b73a8c Mon Sep 17 00:00:00 2001 From: benStre Date: Thu, 25 Jan 2024 01:52:42 +0100 Subject: [PATCH 3/5] handle unresolved local pointers in storage items --- init.ts | 2 ++ runtime/storage.ts | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/init.ts b/init.ts index 5dd25a28..c72d9293 100644 --- a/init.ts +++ b/init.ts @@ -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 items that contain pointers with unresolved local origin in storage + Storage.updateItemsWithUnresolvedLocalDependencies(); // init subscriber cache as soon as endpoint is available initSubscriberCache(); } diff --git a/runtime/storage.ts b/runtime/storage.ts index 6e3a297e..05791973 100644 --- a/runtime/storage.ts +++ b/runtime/storage.ts @@ -377,6 +377,8 @@ export class Storage { return this.trusted_location; } + static #unresolvedLocalItems = new Map() + static setItem(key:string, value:any, listen_for_pointer_changes = true, location:StorageLocation|null|undefined = this.#primary_location):Promise|boolean { Storage.cache.set(key, value); // save in cache @@ -391,23 +393,51 @@ 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.checkUnresolvedLocalDependencies(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.checkUnresolvedLocalDependencies(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 item with a @@local origin. + * Once the endpoint is initialized, the item is updated with the correct pointer ids. + * @param itemKey + * @param value + * @param dependencies + */ + private static checkUnresolvedLocalDependencies(itemKey: string, value:unknown, dependencies: Set) { + const hasUnresolvedLocalDependency = [...dependencies].some(p=>p.origin == LOCAL_ENDPOINT); + if (hasUnresolvedLocalDependency) { + this.#unresolvedLocalItems.set(itemKey, value) + } + } + + /** + * Updates all items in storage that still are stored with unresolved @@local pointers + */ + static updateItemsWithUnresolvedLocalDependencies() { + for (const [key, value] of this.#unresolvedLocalItems) { + logger.debug("update item containing pointers with @@local origin: " + key) + this.setItem(key, value) + } + this.#unresolvedLocalItems.clear() + } + + public static setPointer(pointer:Pointer, listen_for_changes = true, location:StorageLocation|undefined = this.#primary_location, partialUpdateKey: unknown = NOT_EXISTING): Promise|boolean { if (!pointer.value_initialized) { // logger.warn("pointer value " + pointer.idString() + " not available, cannot save in storage"); From 897b285326891f493e5306ef374edb3aaac6fe13 Mon Sep 17 00:00:00 2001 From: benStre Date: Thu, 25 Jan 2024 02:04:07 +0100 Subject: [PATCH 4/5] refactoring, add support for pointer entries --- init.ts | 4 ++-- runtime/storage.ts | 42 ++++++++++++++++++++++++++++-------------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/init.ts b/init.ts index c72d9293..8d03e72c 100644 --- a/init.ts +++ b/init.ts @@ -80,8 +80,8 @@ export async function init() { // has only local endpoint id (%0000) or global id? if (endpoint != LOCAL_ENDPOINT) { Pointer.is_local = false; - // update items that contain pointers with unresolved local origin in storage - Storage.updateItemsWithUnresolvedLocalDependencies(); + // update storage entries that contain pointers with unresolved @@local origin + Storage.updateEntriesWithUnresolvedLocalDependencies(); // init subscriber cache as soon as endpoint is available initSubscriberCache(); } diff --git a/runtime/storage.ts b/runtime/storage.ts index 05791973..e9c67c07 100644 --- a/runtime/storage.ts +++ b/runtime/storage.ts @@ -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(); @@ -378,6 +379,7 @@ export class Storage { } static #unresolvedLocalItems = new Map() + static #unresolvedLocalPointers = new IterableWeakSet() static setItem(key:string, value:any, listen_for_pointer_changes = true, location:StorageLocation|null|undefined = this.#primary_location):Promise|boolean { @@ -397,7 +399,7 @@ export class Storage { this.setDirty(location, true) // store value (might be pointer reference) const dependencies = await location.setItem(key, value); - if (Pointer.is_local) this.checkUnresolvedLocalDependencies(key, value, dependencies); + 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) @@ -406,35 +408,45 @@ export class Storage { static setItemSync(location:SyncStorageLocation, key: string, value: unknown,listen_for_pointer_changes: boolean) { const dependencies = location.setItem(key, value); - if (Pointer.is_local) this.checkUnresolvedLocalDependencies(key, value, dependencies); + 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 item with a @@local origin. - * Once the endpoint is initialized, the item is updated with the correct pointer ids. - * @param itemKey - * @param value - * @param dependencies + * 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 checkUnresolvedLocalDependencies(itemKey: string, value:unknown, dependencies: Set) { + private static checkUnresolvedLocalDependenciesForItem(key: string, value:unknown, dependencies: Set) { const hasUnresolvedLocalDependency = [...dependencies].some(p=>p.origin == LOCAL_ENDPOINT); - if (hasUnresolvedLocalDependency) { - this.#unresolvedLocalItems.set(itemKey, value) - } + 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) { + const hasUnresolvedLocalDependency = [...dependencies].some(p=>p.origin == LOCAL_ENDPOINT); + if (hasUnresolvedLocalDependency) this.#unresolvedLocalPointers.add(pointer); } /** - * Updates all items in storage that still are stored with unresolved @@local pointers + * Updates all item/pointer entries in storage that still are stored with unresolved @@local pointers */ - static updateItemsWithUnresolvedLocalDependencies() { + static updateEntriesWithUnresolvedLocalDependencies() { for (const [key, value] of this.#unresolvedLocalItems) { - logger.debug("update item containing pointers with @@local origin: " + key) + 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() } @@ -458,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); @@ -478,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); From f479fd55d0c8303c1adfc40f6f25b1d898b8d958 Mon Sep 17 00:00:00 2001 From: benStre Date: Thu, 25 Jan 2024 02:05:49 +0100 Subject: [PATCH 5/5] refactoring --- runtime/storage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/storage.ts b/runtime/storage.ts index e9c67c07..7c82fd2c 100644 --- a/runtime/storage.ts +++ b/runtime/storage.ts @@ -437,7 +437,7 @@ export class Storage { */ static updateEntriesWithUnresolvedLocalDependencies() { for (const [key, value] of this.#unresolvedLocalItems) { - logger.debug("update item containing pointers with @@local origin!: " + key) + logger.debug("update item containing pointers with @@local origin: " + key) this.setItem(key, value) } this.#unresolvedLocalItems.clear()