Skip to content

Commit c09ac2c

Browse files
committed
Schedule cached wallets' engine startup behind a limited-concurrency queue
Wallets that emit from walletCache.json no longer race every other wallet through repo sync, key derivation, and engine creation in the seconds after login. Their heavy startup work now waits in a per-context queue (8 at a time), while wallets without a cache bypass the queue because they cannot emit at all until that work runs, keeping first login identical to before. Asking for a wallet moves it to the front of the line: the account's waitForCurrencyWallet, the internal engine/storage waiters, and changePaused(false) all bump the wallet's queued startup.
1 parent ed985f4 commit c09ac2c

5 files changed

Lines changed: 370 additions & 139 deletions

File tree

src/core/account/account-api.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
} from '../../types/types'
3232
import { makeEdgeResult } from '../../util/edgeResult'
3333
import { base58 } from '../../util/encoding'
34+
import { bumpEngineQueue } from '../currency/currency-selectors'
3435
import { saveWalletSettings } from '../currency/wallet/currency-wallet-files'
3536
import { getPublicWalletInfo } from '../currency/wallet/currency-wallet-pixie'
3637
import {
@@ -724,6 +725,10 @@ export function makeAccountApi(ai: ApiInput, accountId: string): EdgeAccount {
724725
},
725726

726727
async waitForCurrencyWallet(walletId: string): Promise<EdgeCurrencyWallet> {
728+
// Asking for a wallet is the "the user wants this one" signal,
729+
// so move its engine startup to the front of the queue:
730+
bumpEngineQueue(ai, walletId)
731+
727732
return await new Promise((resolve, reject) => {
728733
const check = (): void => {
729734
const wallet = this.currencyWallets[walletId]

src/core/currency/currency-selectors.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
EdgeTokenMap
55
} from '../../types/types'
66
import { ApiInput, RootProps } from '../root-pixie'
7+
import { getEngineScheduler } from './wallet/engine-scheduler'
78

89
export function getCurrencyMultiplier(
910
currencyInfo: EdgeCurrencyInfo,
@@ -47,6 +48,10 @@ export function waitForCurrencyWallet(
4748
ai: ApiInput,
4849
walletId: string
4950
): Promise<EdgeCurrencyWallet> {
51+
// Asking for a wallet is the "the user wants this one" signal,
52+
// so move its engine startup to the front of the queue:
53+
bumpEngineQueue(ai, walletId)
54+
5055
const out: Promise<EdgeCurrencyWallet> = ai.waitFor(
5156
(props: RootProps): EdgeCurrencyWallet | undefined => {
5257
checkCurrencyWallet(props, walletId)
@@ -59,3 +64,13 @@ export function waitForCurrencyWallet(
5964
)
6065
return out
6166
}
67+
68+
/**
69+
* Prioritizes a wallet's engine startup when its startup work is still
70+
* waiting in the limited-concurrency queue. Harmless otherwise.
71+
*/
72+
export function bumpEngineQueue(ai: ApiInput, walletId: string): void {
73+
if (getEngineScheduler(ai.props.io).bump(walletId)) {
74+
ai.props.log(`${walletId} engine startup bumped to front of queue`)
75+
}
76+
}

src/core/currency/wallet/currency-wallet-api.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import { RootProps, toApiInput } from '../../root-pixie'
5252
import { makeLocalDisklet, makeRepoPaths } from '../../storage/repo'
5353
import { makeStorageWalletApi } from '../../storage/storage-api'
5454
import {
55+
bumpEngineQueue,
5556
checkCurrencyWallet,
5657
getCurrencyMultiplier
5758
} from '../currency-selectors'
@@ -116,6 +117,9 @@ export function makeCurrencyWalletApi(
116117
* method call instead of a hang.
117118
*/
118119
function getEngine(): Promise<EdgeCurrencyEngine> {
120+
// The caller needs this engine now, so skip the startup queue:
121+
bumpEngineQueue(ai, walletId)
122+
119123
return ai.waitFor((props: RootProps): EdgeCurrencyEngine | undefined => {
120124
checkCurrencyWallet(props, walletId)
121125
return props.output.currency.wallets[walletId]?.engine
@@ -136,6 +140,10 @@ export function makeCurrencyWalletApi(
136140
* `addStorageWallet`, so the repo is never coming).
137141
*/
138142
function getStorage(): Promise<true> {
143+
// The repo loads inside the queued startup work, so a caller
144+
// waiting on storage wants this wallet at the front too:
145+
bumpEngineQueue(ai, walletId)
146+
139147
return ai.waitFor((props: RootProps): true | undefined => {
140148
if (props.state.storageWallets[walletId] != null) return true
141149
checkCurrencyWallet(props, walletId)
@@ -314,6 +322,10 @@ export function makeCurrencyWalletApi(
314322

315323
// Running state:
316324
async changePaused(paused: boolean): Promise<void> {
325+
// Un-pausing means the app wants this wallet running,
326+
// so align the startup queue with the caller's boot order:
327+
if (!paused) bumpEngineQueue(ai, walletId)
328+
317329
input.props.dispatch({
318330
type: 'CURRENCY_WALLET_CHANGED_PAUSED',
319331
payload: { walletId: input.props.walletId, paused }

0 commit comments

Comments
 (0)