remove replaceableEvents table

This commit is contained in:
hzrd149
2024-01-13 14:09:17 +00:00
parent 3fae9ad263
commit 5de4838bc9
3 changed files with 43 additions and 59 deletions

View File

@@ -1,15 +1,15 @@
import { openDB, deleteDB, IDBPDatabase, IDBPTransaction } from "idb"; import { openDB, deleteDB, IDBPDatabase, IDBPTransaction } from "idb";
import { clearDB } from "nostr-idb"; import { clearDB } from "nostr-idb";
import { SchemaV1, SchemaV2, SchemaV3, SchemaV4, SchemaV5, SchemaV6, SchemaV7 } from "./schema"; import { SchemaV1, SchemaV2, SchemaV3, SchemaV4, SchemaV5, SchemaV6, SchemaV7, SchemaV8 } from "./schema";
import { logger } from "../../helpers/debug"; import { logger } from "../../helpers/debug";
import { localCacheDatabase } from "../local-cache-relay"; import { localCacheDatabase } from "../local-cache-relay";
const log = logger.extend("Database"); const log = logger.extend("Database");
const dbName = "storage"; const dbName = "storage";
const version = 7; const version = 8;
const db = await openDB<SchemaV6>(dbName, version, { const db = await openDB<SchemaV8>(dbName, version, {
upgrade(db, oldVersion, newVersion, transaction, event) { upgrade(db, oldVersion, newVersion, transaction, event) {
if (oldVersion < 1) { if (oldVersion < 1) {
const v0 = db as unknown as IDBPDatabase<SchemaV1>; const v0 = db as unknown as IDBPDatabase<SchemaV1>;
@@ -72,10 +72,10 @@ const db = await openDB<SchemaV6>(dbName, version, {
v2.deleteObjectStore("settings"); v2.deleteObjectStore("settings");
// create new replaceable event object store // create new replaceable event object store
const settings = v3.createObjectStore("replaceableEvents", { const replaceableEvents = v3.createObjectStore("replaceableEvents", {
keyPath: "addr", keyPath: "addr",
}); });
settings.createIndex("created", "created"); replaceableEvents.createIndex("created", "created");
} }
if (oldVersion < 4) { if (oldVersion < 4) {
@@ -166,6 +166,11 @@ const db = await openDB<SchemaV6>(dbName, version, {
} }
}); });
} }
if (oldVersion < 8) {
const v7 = db as unknown as IDBPDatabase<SchemaV7>;
v7.deleteObjectStore("replaceableEvents");
}
}, },
}); });
@@ -175,9 +180,6 @@ export async function clearCacheData() {
log("Clearing nostr-idb"); log("Clearing nostr-idb");
await clearDB(localCacheDatabase); await clearDB(localCacheDatabase);
log("Clearing replaceableEvents");
await db.clear("replaceableEvents");
log("Clearing channelMetadata"); log("Clearing channelMetadata");
await db.clear("channelMetadata"); await db.clear("channelMetadata");

View File

@@ -126,3 +126,5 @@ export interface SchemaV7 extends Omit<SchemaV6, "account"> {
value: Account; value: Account;
}; };
} }
export interface SchemaV8 extends Omit<SchemaV7, "replaceableEvents"> {}

View File

@@ -10,9 +10,10 @@ import { NostrQuery } from "../types/nostr-query";
import { logger } from "../helpers/debug"; import { logger } from "../helpers/debug";
import db from "./db"; import db from "./db";
import { nameOrPubkey } from "./user-metadata"; import { nameOrPubkey } from "./user-metadata";
import { getEventCoordinate } from "../helpers/nostr/events"; import { getEventCoordinate, parseCoordinate } from "../helpers/nostr/events";
import createDefer, { Deferred } from "../classes/deferred"; import createDefer, { Deferred } from "../classes/deferred";
import { LOCAL_CACHE_RELAY, LOCAL_CACHE_RELAY_ENABLED, localCacheRelay } from "./local-cache-relay"; import { LOCAL_CACHE_RELAY, LOCAL_CACHE_RELAY_ENABLED, localCacheRelay } from "./local-cache-relay";
import { relayRequest } from "../helpers/relay";
type Pubkey = string; type Pubkey = string;
type Relay = string; type Relay = string;
@@ -182,25 +183,36 @@ class ReplaceableEventLoaderService {
private async readFromCache() { private async readFromCache() {
if (this.readFromCachePromises.size === 0) return; if (this.readFromCachePromises.size === 0) return;
let read = 0; const kindFilters: Record<number, NostrQuery> = {};
const transaction = db.transaction("replaceableEvents", "readonly"); for (const [cord] of this.readFromCachePromises) {
for (const [cord, promise] of this.readFromCachePromises) { const [kindStr, pubkey, d] = cord.split(":") as [string, string] | [string, string, string];
transaction const kind = parseInt(kindStr);
.objectStore("replaceableEvents") kindFilters[kind] = kindFilters[kind] || { kinds: [kind] };
.get(cord)
.then((cached) => { const arr = (kindFilters[kind].authors = kindFilters[kind].authors || []);
if (cached?.event) { arr.push(pubkey);
this.handleEvent(cached.event, false);
promise.resolve(true); if (d) {
read++; const arr = (kindFilters[kind]["#d"] = kindFilters[kind]["#d"] || []);
} arr.push(d);
promise.resolve(false); }
});
} }
const filters = Array.from(Object.values(kindFilters));
const events = await relayRequest(localCacheRelay, filters);
for (const event of events) {
this.handleEvent(event, false);
const cord = getEventCoordinate(event);
const promise = this.readFromCachePromises.get(cord);
if (promise) promise.resolve(true);
this.readFromCachePromises.delete(cord);
}
// resolve remaining promises
for (const [_, promise] of this.readFromCachePromises) promise.resolve();
this.readFromCachePromises.clear(); this.readFromCachePromises.clear();
transaction.commit();
await transaction.done; if (events.length > 0) this.dbLog(`Read ${events.length} events from database`);
if (read) this.dbLog(`Read ${read} events from database`);
} }
private loadCacheDedupe = new Map<string, Promise<boolean>>(); private loadCacheDedupe = new Map<string, Promise<boolean>>();
loadFromCache(cord: string) { loadFromCache(cord: string) {
@@ -223,38 +235,14 @@ class ReplaceableEventLoaderService {
if (this.writeCacheQueue.size === 0) return; if (this.writeCacheQueue.size === 0) return;
this.dbLog(`Writing ${this.writeCacheQueue.size} events to database`); this.dbLog(`Writing ${this.writeCacheQueue.size} events to database`);
const transaction = db.transaction("replaceableEvents", "readwrite"); for (const [_, event] of this.writeCacheQueue) localCacheRelay.publish(event);
for (const [cord, event] of this.writeCacheQueue) {
localCacheRelay.publish(event);
// TODO: remove this
transaction.objectStore("replaceableEvents").put({ addr: cord, event, created: dayjs().unix() });
}
this.writeCacheQueue.clear(); this.writeCacheQueue.clear();
transaction.commit();
await transaction.done;
} }
private async saveToCache(cord: string, event: NostrEvent) { private async saveToCache(cord: string, event: NostrEvent) {
this.writeCacheQueue.set(cord, event); this.writeCacheQueue.set(cord, event);
this.writeToCacheThrottle(); this.writeToCacheThrottle();
} }
/** @deprecated */
async pruneDatabaseCache() {
const keys = await db.getAllKeysFromIndex(
"replaceableEvents",
"created",
IDBKeyRange.upperBound(dayjs().subtract(1, "week").unix()),
);
if (keys.length === 0) return;
this.dbLog(`Pruning ${keys.length} expired events from database`);
const transaction = db.transaction("replaceableEvents", "readwrite");
for (const key of keys) {
transaction.store.delete(key);
}
await transaction.commit();
}
private requestEventFromRelays(relays: string[], kind: number, pubkey: string, d?: string) { private requestEventFromRelays(relays: string[], kind: number, pubkey: string, d?: string) {
const cord = createCoordinate(kind, pubkey, d); const cord = createCoordinate(kind, pubkey, d);
const sub = this.events.get(cord); const sub = this.events.get(cord);
@@ -297,14 +285,6 @@ class ReplaceableEventLoaderService {
const replaceableEventLoaderService = new ReplaceableEventLoaderService(); const replaceableEventLoaderService = new ReplaceableEventLoaderService();
replaceableEventLoaderService.pruneDatabaseCache();
setInterval(
() => {
replaceableEventLoaderService.pruneDatabaseCache();
},
1000 * 60 * 60,
);
if (import.meta.env.DEV) { if (import.meta.env.DEV) {
//@ts-ignore //@ts-ignore
window.replaceableEventLoaderService = replaceableEventLoaderService; window.replaceableEventLoaderService = replaceableEventLoaderService;