diff --git a/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/baselineProfiles/0/app-arm64-release.dm b/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/baselineProfiles/0/app-arm64-release.dm deleted file mode 100644 index 31d9873c..00000000 Binary files a/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/baselineProfiles/0/app-arm64-release.dm and /dev/null differ diff --git a/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/baselineProfiles/1/app-arm64-release.dm b/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/baselineProfiles/1/app-arm64-release.dm deleted file mode 100644 index a437c2ee..00000000 Binary files a/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/baselineProfiles/1/app-arm64-release.dm and /dev/null differ diff --git a/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/eid-w3ds-v0.2.1.0.apk b/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/eid-w3ds-v0.2.1.0.apk deleted file mode 100644 index 2e334d32..00000000 Binary files a/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/eid-w3ds-v0.2.1.0.apk and /dev/null differ diff --git a/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/eid-w3ds-v0.2.1.1.apk b/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/eid-w3ds-v0.2.1.1.apk deleted file mode 100644 index a1e76b13..00000000 Binary files a/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/eid-w3ds-v0.2.1.1.apk and /dev/null differ diff --git a/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/output-metadata.json b/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/output-metadata.json deleted file mode 100644 index 625869fa..00000000 --- a/infrastructure/eid-wallet/src-tauri/gen/android/app/arm64/release/output-metadata.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "version": 3, - "artifactType": { - "type": "APK", - "kind": "Directory" - }, - "applicationId": "foundation.metastate.eid_wallet", - "variantName": "arm64Release", - "elements": [ - { - "type": "SINGLE", - "filters": [], - "attributes": [], - "versionCode": 2, - "versionName": "0.1.8", - "outputFile": "app-arm64-release.apk" - } - ], - "elementType": "File", - "baselineProfiles": [ - { - "minApi": 28, - "maxApi": 30, - "baselineProfiles": [ - "baselineProfiles/1/app-arm64-release.dm" - ] - }, - { - "minApi": 31, - "maxApi": 2147483647, - "baselineProfiles": [ - "baselineProfiles/0/app-arm64-release.dm" - ] - } - ], - "minSdkVersionForDexing": 24 -} \ No newline at end of file diff --git a/infrastructure/eid-wallet/src/routes/(app)/settings/+page.svelte b/infrastructure/eid-wallet/src/routes/(app)/settings/+page.svelte index 8dac85cc..eb5043b6 100644 --- a/infrastructure/eid-wallet/src/routes/(app)/settings/+page.svelte +++ b/infrastructure/eid-wallet/src/routes/(app)/settings/+page.svelte @@ -126,7 +126,7 @@ on:click={handleVersionTap} disabled={isRetrying} > - Version v0.2.1.1 + Version v0.2.1.2 {#if retryMessage} diff --git a/platforms/pictique-api/src/web3adapter/watchers/subscriber.ts b/platforms/pictique-api/src/web3adapter/watchers/subscriber.ts index 3e3d00b8..7da2c6b7 100644 --- a/platforms/pictique-api/src/web3adapter/watchers/subscriber.ts +++ b/platforms/pictique-api/src/web3adapter/watchers/subscriber.ts @@ -33,9 +33,30 @@ const JUNCTION_TABLE_MAP = { @EventSubscriber() export class PostgresSubscriber implements EntitySubscriberInterface { private adapter: Web3Adapter; + private pendingChanges: Map = new Map(); constructor() { this.adapter = adapter; + + // Clean up old pending changes every 5 minutes to prevent memory leaks + setInterval(() => { + this.cleanupOldPendingChanges(); + }, 5 * 60 * 1000); + } + + /** + * Clean up old pending changes to prevent memory leaks + */ + private cleanupOldPendingChanges(): void { + const now = Date.now(); + const maxAge = 10 * 60 * 1000; // 10 minutes + + for (const [key, timestamp] of this.pendingChanges.entries()) { + if (now - timestamp > maxAge) { + this.pendingChanges.delete(key); + console.log(`Cleaned up old pending change: ${key}`); + } + } } /** @@ -164,28 +185,49 @@ export class PostgresSubscriber implements EntitySubscriberInterface { const data = this.entityToPlain(entity); if (!data.id) return; + // Create a unique key for this entity change to prevent duplicates + const changeKey = `${tableName}:${entity.id}`; + + // Check if we already have a pending change for this entity + if (this.pendingChanges.has(changeKey)) { + console.log(`Change already pending for ${changeKey}, skipping duplicate`); + return; + } + + // Mark this change as pending with timestamp + this.pendingChanges.set(changeKey, Date.now()); + try { setTimeout(async () => { - let globalId = await this.adapter.mappingDb.getGlobalId( - entity.id - ); - globalId = globalId ?? ""; - - if (this.adapter.lockedIds.includes(globalId)) - return console.log("locked skipping ", globalId); - - console.log( - "sending packet for global Id", - globalId, - entity.id - ); - const envelope = await this.adapter.handleChange({ - data, - tableName: tableName.toLowerCase(), - }); + try { + let globalId = await this.adapter.mappingDb.getGlobalId( + entity.id + ); + globalId = globalId ?? ""; + + if (this.adapter.lockedIds.includes(globalId)) { + console.log("locked skipping ", globalId); + return; + } + + console.log( + "sending packet for global Id", + globalId, + entity.id + ); + const envelope = await this.adapter.handleChange({ + data, + tableName: tableName.toLowerCase(), + }); + } finally { + // Always remove the pending change flag + this.pendingChanges.delete(changeKey); + } }, 3_000); } catch (error) { console.error(`Error processing change for ${tableName}:`, error); + // Remove the pending change flag on error + this.pendingChanges.delete(changeKey); } } @@ -217,34 +259,52 @@ export class PostgresSubscriber implements EntitySubscriberInterface { return; } - let globalId = await this.adapter.mappingDb.getGlobalId(entity.id); - globalId = globalId ?? ""; + // Create a unique key for this junction table change to prevent duplicates + const changeKey = `junction:${junctionInfo.entity}:${parentId}`; + + // Check if we already have a pending change for this parent entity + if (this.pendingChanges.has(changeKey)) { + console.log(`Junction change already pending for ${changeKey}, skipping duplicate`); + return; + } + + // Mark this change as pending with timestamp + this.pendingChanges.set(changeKey, Date.now()); - // Use immediate locking instead of setTimeout to prevent race conditions + // Use setTimeout to prevent race conditions try { setTimeout(async () => { - let globalId = await this.adapter.mappingDb.getGlobalId( - entity.id - ); - globalId = globalId ?? ""; - - if (this.adapter.lockedIds.includes(globalId)) - return console.log("locked skipping ", globalId); - - console.log( - "sending packet for global Id", - globalId, - entity.id - ); - - const tableName = `${junctionInfo.entity.toLowerCase()}s`; - await this.adapter.handleChange({ - data: this.entityToPlain(parentEntity), - tableName, - }); + try { + let globalId = await this.adapter.mappingDb.getGlobalId( + entity.id + ); + globalId = globalId ?? ""; + + if (this.adapter.lockedIds.includes(globalId)) { + console.log("locked skipping ", globalId); + return; + } + + console.log( + "sending packet for global Id", + globalId, + entity.id + ); + + const tableName = `${junctionInfo.entity.toLowerCase()}s`; + await this.adapter.handleChange({ + data: this.entityToPlain(parentEntity), + tableName, + }); + } finally { + // Always remove the pending change flag + this.pendingChanges.delete(changeKey); + } }, 3_000); } catch (error) { console.error(error); + // Remove the pending change flag on error + this.pendingChanges.delete(changeKey); } } catch (error) { console.error("Error handling junction table change:", error);