feat: profile cache worker relay

This commit is contained in:
Kieran 2024-01-18 22:04:11 +00:00
parent 084558b3e7
commit 6eef8c7fef
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
4 changed files with 111 additions and 5 deletions

View File

@ -0,0 +1,104 @@
import { CachedTable, CacheEvents, removeUndefined } from "@snort/shared";
import { CachedMetadata, mapEventToProfile, NostrEvent } from "@snort/system";
import { WorkerRelayInterface } from "@snort/worker-relay";
import EventEmitter from "eventemitter3";
export class ProfileCacheRelayWorker extends EventEmitter<CacheEvents> implements CachedTable<CachedMetadata> {
#relay: WorkerRelayInterface;
#keys = new Set<string>();
#cache = new Map<string, CachedMetadata>();
constructor(relay: WorkerRelayInterface) {
super();
this.#relay = relay;
}
async preload() {
const ids = await this.#relay.sql("select distinct(pubkey) from events where kind = ?", [0]);
this.#keys = new Set<string>(ids.map(a => a[0] as string));
}
keysOnTable(): string[] {
return [...this.#keys];
}
getFromCache(key?: string | undefined) {
if (key) {
return this.#cache.get(key);
}
}
discover(ev: NostrEvent) {
if (ev.kind === 0) {
this.#keys.add(ev.pubkey);
}
}
async get(key?: string | undefined) {
if (key) {
const cached = this.getFromCache(key);
if (cached) {
return cached;
}
const res = await this.bulkGet([key]);
if (res.length > 0) {
return res[0];
}
}
}
async bulkGet(keys: string[]) {
if (keys.length === 0) return [];
const results = await this.#relay.req({
id: "ProfileCacheRelayWorker.bulkGet",
filters: [
{
authors: keys,
kinds: [0],
},
],
});
const mapped = removeUndefined(results.result.map(a => mapEventToProfile(a)));
for (const pf of mapped) {
this.#cache.set(this.key(pf), pf);
}
this.emit(
"change",
mapped.map(a => this.key(a)),
);
console.debug("ProfileCacheRelayWorker", keys, results);
return mapped;
}
async set(obj: CachedMetadata) {
this.#keys.add(this.key(obj));
}
async bulkSet(obj: CachedMetadata[] | readonly CachedMetadata[]) {
const mapped = obj.map(a => this.key(a));
mapped.forEach(a => this.#keys.add(a));
this.emit("change", mapped);
}
async update<TWithCreated extends CachedMetadata & { created: number; loaded: number }>(
m: TWithCreated,
): Promise<"new" | "refresh" | "updated" | "no_change"> {
// do nothing
return "refresh";
}
async buffer(keys: string[]) {
const missing = keys.filter(a => !this.#cache.has(a));
const res = await this.bulkGet(missing);
return missing.filter(a => !res.some(b => this.key(b) === a));
}
key(of: CachedMetadata) {
return of.pubkey;
}
snapshot() {
return [...this.#cache.values()];
}
}

View File

@ -1,4 +1,4 @@
import { RelayMetricCache, UserProfileCache, UserRelaysCache } from "@snort/system";
import { RelayMetricCache, UserRelaysCache } from "@snort/system";
import { SnortSystemDb } from "@snort/system-web";
import { WorkerRelayInterface } from "@snort/worker-relay";
import WorkerRelayPath from "@snort/worker-relay/dist/worker?worker&url";
@ -6,6 +6,7 @@ import WorkerRelayPath from "@snort/worker-relay/dist/worker?worker&url";
import { ChatCache } from "./ChatCache";
import { EventCacheWorker } from "./EventCacheWorker";
import { GiftWrapCache } from "./GiftWrapCache";
import { ProfileCacheRelayWorker } from "./ProfileWorkeCache";
export const Relay = new WorkerRelayInterface(WorkerRelayPath);
export async function initRelayWorker() {
@ -21,9 +22,10 @@ export async function initRelayWorker() {
}
export const SystemDb = new SnortSystemDb();
export const UserCache = new UserProfileCache(SystemDb.users);
export const UserRelays = new UserRelaysCache(SystemDb.userRelays);
export const RelayMetrics = new RelayMetricCache(SystemDb.relayMetrics);
export const UserCache = new ProfileCacheRelayWorker(Relay);
export const EventsCache = new EventCacheWorker(Relay);
export const Chats = new ChatCache();
@ -31,7 +33,7 @@ export const GiftsCache = new GiftWrapCache();
export async function preload(follows?: Array<string>) {
const preloads = [
UserCache.preload(follows),
UserCache.preload(),
Chats.preload(),
RelayMetrics.preload(),
GiftsCache.preload(),

View File

@ -2,7 +2,7 @@ import { FeedCache } from "@snort/shared";
import { ReactNode, useEffect, useState, useSyncExternalStore } from "react";
import { FormattedMessage, FormattedNumber } from "react-intl";
import { Chats, GiftsCache, Relay, RelayMetrics, UserCache } from "@/Cache";
import { Chats, GiftsCache, Relay, RelayMetrics } from "@/Cache";
import AsyncButton from "@/Components/Button/AsyncButton";
export function CacheSettings() {
@ -12,7 +12,6 @@ export function CacheSettings() {
<FormattedMessage defaultMessage="Cache" id="DBiVK1" />
</h3>
<RelayCacheStats />
<CacheDetails cache={UserCache} name={<FormattedMessage defaultMessage="Profiles" id="2zJXeA" />} />
<CacheDetails cache={Chats} name={<FormattedMessage defaultMessage="Chats" id="ABAQyo" />} />
<CacheDetails cache={RelayMetrics} name={<FormattedMessage defaultMessage="Relay Metrics" id="tjpYlr" />} />
<CacheDetails cache={GiftsCache} name={<FormattedMessage defaultMessage="Gift Wraps" id="fjAcWo" />} />

View File

@ -28,6 +28,7 @@ System.on("auth", async (c, r, cb) => {
System.on("event", (_, ev) => {
Relay.event(ev);
EventsCache.discover(ev);
UserCache.discover(ev);
});
/**