Approach request optimization differently

This commit is contained in:
Jon Staab
2024-09-03 17:30:11 -07:00
parent 6ee79eb219
commit 06d3462f99
6 changed files with 100 additions and 85 deletions
+13 -19
View File
@@ -1,7 +1,7 @@
import {isNil} from "@welshman/lib"
import {Repository, Relay, LOCAL_RELAY_URL, getFilterResultCardinality} from "@welshman/util"
import type {TrustedEvent, Filter} from "@welshman/util"
import {Tracker, subscribe as baseSubscribe, mergeSubscriptions} from "@welshman/net"
import {Tracker, subscribe as baseSubscribe} from "@welshman/net"
import type {SubscribeRequest} from "@welshman/net"
import {createEventStore} from "@welshman/store"
import type {Router} from './router'
@@ -52,29 +52,23 @@ export const subscribe = (request: PartialSubscribeRequest) => {
}
}
// Make sure to query our local relay too
const delay = AppContext.requestDelay
const timeout = AppContext.requestTimeout
const sub = baseSubscribe({delay, authTimeout: timeout, relays: [], ...request})
return mergeSubscriptions(
AppContext.splitRequest!(request).map(req => {
// Make sure to query our local relay too
const relays = [...req.relays, LOCAL_RELAY_URL]
const sub = baseSubscribe({delay, authTimeout: timeout, ...req, relays})
sub.emitter.on("event", (url: string, e: TrustedEvent) => {
repository.publish(e)
})
sub.emitter.on("event", (url: string, e: TrustedEvent) => {
repository.publish(e)
})
// Keep cached results async so the caller can set up handlers
setTimeout(() => {
for (const event of events) {
sub.emitter.emit("event", LOCAL_RELAY_URL, event)
}
})
// Keep cached results async so the caller can set up handlers
setTimeout(() => {
for (const event of events) {
sub.emitter.emit("event", LOCAL_RELAY_URL, event)
}
})
return sub
})
)
return sub
}
export const load = (request: PartialSubscribeRequest) =>
+14 -4
View File
@@ -16,19 +16,29 @@ export * from './topics'
export * from './util'
export * from './zappers'
import {NetworkContext} from "@welshman/net"
import {type TrustedEvent} from "@welshman/util"
import {partition} from "@welshman/lib"
import {type Subscription, NetworkContext, defaultOptimizeSubscriptions} from "@welshman/net"
import {type TrustedEvent, unionFilters} from "@welshman/util"
import {tracker, repository, AppContext} from './core'
import {splitRequest, makeRouter} from './router'
import {makeRouter, getFilterSelections} from './router'
import {onAuth} from './session'
export function* optimizeSubscriptions(subs: Subscription[]) {
const [withRelays, withoutRelays] = partition(sub => sub.request.relays.length > 0, subs)
yield* defaultOptimizeSubscriptions(withRelays)
yield* getFilterSelections(
unionFilters(withoutRelays.flatMap(sub => sub.request.filters))
)
}
Object.assign(NetworkContext, {
onAuth,
onEvent: (url: string, event: TrustedEvent) => tracker.track(event.id, url),
isDeleted: (url: string, event: TrustedEvent) => repository.isDeleted(event),
optimizeSubscriptions,
})
Object.assign(AppContext, {
splitRequest,
router: makeRouter(),
})
+2 -11
View File
@@ -3,7 +3,6 @@ import {Tags, getFilterId, unionFilters, isShareableRelayUrl, isCommunityAddress
import type {TrustedEvent, Filter} from '@welshman/util'
import {NetworkContext, ConnectionStatus} from '@welshman/net'
import {AppContext} from './core'
import type {PartialSubscribeRequest} from './core'
import {pubkey} from './session'
import {relaySelectionsByPubkey, getReadRelayUrls, getWriteRelayUrls, getRelayUrls} from './relaySelections'
import {relays, relaysByUrl} from './relays'
@@ -443,7 +442,7 @@ export const makeRouter = (options: Partial<RouterOptions> = {}) =>
// Infer relay selections from filters
export type RelayFilters = {
relay: string
relays: string[]
filters: Filter[]
}
@@ -561,7 +560,7 @@ export const getFilterSelections = (filters: Filter[]): RelayFilters[] => {
.getSelections()
.map(({values, relay}) => ({
filters: values.map(id => filtersById.get(id)!),
relay,
relays: [relay],
}))
// Pubkey-based selections can get really big. Use the most popular relays for the long tail
@@ -575,11 +574,3 @@ export const getFilterSelections = (filters: Filter[]): RelayFilters[] => {
return keep
}
export const splitRequest = (req: PartialSubscribeRequest) => {
if ((req.relays || []).length > 0) return [req]
return getFilterSelections(req.filters)
.map(({relay, filters}) => ({...req, filters, relays: [relay]}))
}