Cache refresh actor promise
This commit is contained in:
parent
a6a12dae10
commit
4ead40e776
6 changed files with 49 additions and 15 deletions
|
@ -138,10 +138,10 @@ export class CustomMarkupService {
|
|||
const component = this.dynamicElementService.createElement(ButtonMarkupComponent)
|
||||
|
||||
const model = {
|
||||
theme: data.theme,
|
||||
theme: data.theme ?? 'primary',
|
||||
href: data.href,
|
||||
label: data.label,
|
||||
blankTarget: this.buildBoolean(data.blankTarget)
|
||||
blankTarget: this.buildBoolean(data.blankTarget) ?? false
|
||||
}
|
||||
this.dynamicElementService.setModel(component, model)
|
||||
|
||||
|
|
21
server/helpers/promise-cache.ts
Normal file
21
server/helpers/promise-cache.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
export class PromiseCache <A, R> {
|
||||
private readonly running = new Map<string, Promise<R>>()
|
||||
|
||||
constructor (
|
||||
private readonly fn: (arg: A) => Promise<R>,
|
||||
private readonly keyBuilder: (arg: A) => string
|
||||
) {
|
||||
}
|
||||
|
||||
run (arg: A) {
|
||||
const key = this.keyBuilder(arg)
|
||||
|
||||
if (this.running.has(key)) return this.running.get(key)
|
||||
|
||||
const p = this.fn(arg)
|
||||
|
||||
this.running.set(key, p)
|
||||
|
||||
return p.finally(() => this.running.delete(key))
|
||||
}
|
||||
}
|
|
@ -56,7 +56,7 @@ async function getOrCreateAPActor (
|
|||
if (actor.Account) (actor as MActorAccountChannelIdActor).Account.Actor = actor
|
||||
if (actor.VideoChannel) (actor as MActorAccountChannelIdActor).VideoChannel.Actor = actor
|
||||
|
||||
const { actor: actorRefreshed, refreshed } = await refreshActorIfNeeded(actor, fetchType)
|
||||
const { actor: actorRefreshed, refreshed } = await refreshActorIfNeeded({ actor, fetchedType: fetchType })
|
||||
if (!actorRefreshed) throw new Error('Actor ' + actor.url + ' does not exist anymore.')
|
||||
|
||||
await scheduleOutboxFetchIfNeeded(actor, created, refreshed, updateCollections)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { logger, loggerTagsFactory } from '@server/helpers/logger'
|
||||
import { PromiseCache } from '@server/helpers/promise-cache'
|
||||
import { PeerTubeRequestError } from '@server/helpers/requests'
|
||||
import { ActorLoadByUrlType } from '@server/lib/model-loaders'
|
||||
import { ActorModel } from '@server/models/actor/actor'
|
||||
|
@ -8,11 +9,30 @@ import { fetchRemoteActor } from './shared'
|
|||
import { APActorUpdater } from './updater'
|
||||
import { getUrlFromWebfinger } from './webfinger'
|
||||
|
||||
async function refreshActorIfNeeded <T extends MActorFull | MActorAccountChannelId> (
|
||||
actorArg: T,
|
||||
type RefreshResult <T> = Promise<{ actor: T | MActorFull, refreshed: boolean }>
|
||||
|
||||
type RefreshOptions <T> = {
|
||||
actor: T
|
||||
fetchedType: ActorLoadByUrlType
|
||||
): Promise<{ actor: T | MActorFull, refreshed: boolean }> {
|
||||
if (!actorArg.isOutdated()) return { actor: actorArg, refreshed: false }
|
||||
}
|
||||
|
||||
const promiseCache = new PromiseCache(doRefresh, (options: RefreshOptions<MActorFull | MActorAccountChannelId>) => options.actor.url)
|
||||
|
||||
function refreshActorIfNeeded <T extends MActorFull | MActorAccountChannelId> (options: RefreshOptions<T>): RefreshResult <T> {
|
||||
const actorArg = options.actor
|
||||
if (!actorArg.isOutdated()) return Promise.resolve({ actor: actorArg, refreshed: false })
|
||||
|
||||
return promiseCache.run(options)
|
||||
}
|
||||
|
||||
export {
|
||||
refreshActorIfNeeded
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
async function doRefresh <T extends MActorFull | MActorAccountChannelId> (options: RefreshOptions<T>): RefreshResult <MActorFull> {
|
||||
const { actor: actorArg, fetchedType } = options
|
||||
|
||||
// We need more attributes
|
||||
const actor = fetchedType === 'all'
|
||||
|
@ -52,12 +72,6 @@ async function refreshActorIfNeeded <T extends MActorFull | MActorAccountChannel
|
|||
}
|
||||
}
|
||||
|
||||
export {
|
||||
refreshActorIfNeeded
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function getActorUrl (actor: MActorFull) {
|
||||
return getUrlFromWebfinger(actor.preferredUsername + '@' + actor.getHost())
|
||||
.catch(err => {
|
||||
|
|
|
@ -47,7 +47,7 @@ async function refreshActor (actorUrl: string) {
|
|||
const actor = await ActorModel.loadByUrlAndPopulateAccountAndChannel(actorUrl)
|
||||
|
||||
if (actor) {
|
||||
await refreshActorIfNeeded(actor, fetchType)
|
||||
await refreshActorIfNeeded({ actor, fetchedType: fetchType })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@ export type VideosListMarkupData = {
|
|||
languageOneOf?: string // coma separated values
|
||||
|
||||
onlyLocal?: string // boolean
|
||||
|
||||
}
|
||||
|
||||
export type ButtonMarkupData = {
|
||||
|
|
Loading…
Reference in a new issue