Skip to content
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 37 additions & 11 deletions packages/sessions/src/trackers/multiple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,44 @@ export function raceUntil<T>(promises: Promise<T>[], fallback: T, evalRes: (val:
})
}

export function serialResolve<T>(promises: Promise<T>[], fallback: T, evalRes: (val: T) => boolean): Promise<T | undefined> {
return new Promise(resolve => {
for (const p of promises) {
p.then(val => {
if (evalRes(val)) resolve(val)
})
}
resolve(fallback)
})
}

Comment thread
andrewlee348 marked this conversation as resolved.
Outdated
export async function allSafe<T>(promises: Promise<T>[], fallback: T): Promise<T[]> {
return Promise.all(promises.map(promise => promise.catch(() => fallback)))
}

export class MultipleTracker implements migrator.PresignedMigrationTracker, ConfigTracker {
constructor(private trackers: (migrator.PresignedMigrationTracker & ConfigTracker)[]) {}
constructor(
private trackers: (migrator.PresignedMigrationTracker & ConfigTracker)[],
private isSerial: boolean = false
) {}

async configOfImageHash(args: { imageHash: string }): Promise<commons.config.Config | undefined> {
const requests = this.trackers.map(async (t, i) => ({ res: await t.configOfImageHash(args), i }))

// We try to find a complete configuration, we race so that we don't wait for all trackers to respond
const result1 = await raceUntil(requests, undefined, val => {
if (val?.res === undefined) return false
return universal.genericCoderFor(val.res.version).config.isComplete(val.res)
})
let result1: { res: commons.config.Config | undefined; i: number } | undefined

if (this.isSerial) {
result1 = await serialResolve(requests, undefined, val => {
if (val?.res === undefined) return false
return universal.genericCoderFor(val.res.version).config.isComplete(val.res)
})
} else {
// We try to find a complete configuration, we race so that we don't wait for all trackers to respond
result1 = await raceUntil(requests, undefined, val => {
if (val?.res === undefined) return false
return universal.genericCoderFor(val.res.version).config.isComplete(val.res)
})
}

if (result1?.res) {
// Skip saving the config to the tracker that returned the result
Expand Down Expand Up @@ -82,11 +105,14 @@ export class MultipleTracker implements migrator.PresignedMigrationTracker, Conf
async imageHashOfCounterfactualWallet(args: {
wallet: string
}): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> {
const imageHash = await raceUntil(
this.trackers.map(t => t.imageHashOfCounterfactualWallet(args)),
undefined,
result => Boolean(result)
)
let imageHash: { imageHash: string; context: commons.context.WalletContext } | undefined
const requests = this.trackers.map(t => t.imageHashOfCounterfactualWallet(args))

if (this.isSerial) {
imageHash = await serialResolve(requests, undefined, result => Boolean(result))
} else {
imageHash = await raceUntil(requests, undefined, result => Boolean(result))
}

if (imageHash) {
this.configOfImageHash({ imageHash: imageHash.imageHash }).then(config => {
Expand Down