Skip to content

Commit 332d361

Browse files
committed
Block startup until sync docs have loaded
1 parent 8bf3d52 commit 332d361

File tree

7 files changed

+95
-5
lines changed

7 files changed

+95
-5
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"lint": "eslint --ext .js,.ts .",
2424
"deploy": "npm run deploy:stop && npm run deploy:start",
2525
"deploy:start": "pm2 start pm2.json",
26+
"deploy:start:logs": "pm2 start pm2.json && pm2 logs --lines 200",
2627
"deploy:stop": "pm2 delete all || true",
2728
"deploy:restart": "npm run deploy",
2829
"deploy:status": "pm2 status",

src/v3/index.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,31 @@ import {
1111
sendCoinrankListV2,
1212
sendCoinranksV2
1313
} from './legacyRouter'
14-
import { heartbeatV3, ratesV3 } from './router'
14+
import { initializeCoingeckoSyncDocs } from './providers/coingecko/coingecko'
15+
import { initializeCoinmarketcapSyncDocs } from './providers/coinmarketcap/coinmarketcap'
16+
import { initializeConstantRateSyncDocs } from './providers/constantRates'
17+
import { heartbeatV3, initializeRouterSyncDocs, ratesV3 } from './router'
1518

1619
async function main(): Promise<void> {
20+
// Try to preload synced docs before serving traffic. If some fail, keep
21+
// running in a degraded state and rely on the background sync retries.
22+
console.log('Starting initial sync doc load')
23+
const syncResults = await Promise.allSettled([
24+
initializeRouterSyncDocs(),
25+
initializeCoingeckoSyncDocs(),
26+
initializeCoinmarketcapSyncDocs(),
27+
initializeConstantRateSyncDocs()
28+
])
29+
const failedSyncs = syncResults.filter(
30+
result => result.status === 'rejected'
31+
).length
32+
if (failedSyncs > 0) {
33+
console.warn(
34+
`Initial sync doc load completed with ${failedSyncs} failure(s); starting in degraded mode`
35+
)
36+
} else {
37+
console.log('Initial sync doc load complete')
38+
}
1739
server()
1840
}
1941

@@ -43,7 +65,7 @@ function server(): void {
4365
console.log(`HTTP v3 server listening on port ${httpPort}`)
4466
}
4567

46-
main().catch(error => {
68+
main().catch((error: unknown) => {
4769
console.error(error)
4870
process.exit(1)
4971
})

src/v3/providers/coingecko/coingecko.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,25 @@ automatedTokenMappingsSyncDoc.onChange(automatedMappings => {
131131
}
132132
})
133133

134+
export const initializeCoingeckoSyncDocs = async (): Promise<void> => {
135+
console.log('Initializing coingecko sync docs')
136+
await Promise.all([
137+
manualTokenMappingsSyncDoc.sync(dbSettings).catch((error: unknown) => {
138+
console.error('Initial sync failed for coingecko', error)
139+
throw error
140+
}),
141+
automatedTokenMappingsSyncDoc.sync(dbSettings).catch((error: unknown) => {
142+
console.error('Initial sync failed for coingecko:automated', error)
143+
throw error
144+
}),
145+
platformIdMappingSyncDoc.sync(dbSettings).catch((error: unknown) => {
146+
console.error('Initial sync failed for coingecko:platforms', error)
147+
throw error
148+
})
149+
])
150+
console.log('Initialized coingecko sync docs')
151+
}
152+
134153
const tokenMapping: RateEngine = async () => {
135154
const uidMapping: TokenMap = {}
136155
const crossChainMapping: CrossChainMapping = {}
@@ -282,7 +301,7 @@ const getHistoricalRates = async (
282301
out[id] = data.market_data.current_price.usd
283302
}
284303
})
285-
.catch(e => {
304+
.catch((e: unknown) => {
286305
console.error('coingecko historical query error:', e)
287306
})
288307
)

src/v3/providers/coinmarketcap/coinmarketcap.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,25 @@ automatedTokenMappingsSyncDoc.onChange(autoMappings => {
161161
}
162162
})
163163

164+
export const initializeCoinmarketcapSyncDocs = async (): Promise<void> => {
165+
console.log('Initializing coinmarketcap sync docs')
166+
await Promise.all([
167+
userTokenMappingsSyncDoc.sync(dbSettings).catch((error: unknown) => {
168+
console.error('Initial sync failed for coinmarketcap', error)
169+
throw error
170+
}),
171+
automatedTokenMappingsSyncDoc.sync(dbSettings).catch((error: unknown) => {
172+
console.error('Initial sync failed for coinmarketcap:automated', error)
173+
throw error
174+
}),
175+
platformIdMappingSyncDoc.sync(dbSettings).catch((error: unknown) => {
176+
console.error('Initial sync failed for coinmarketcap:platforms', error)
177+
throw error
178+
})
179+
])
180+
console.log('Initialized coinmarketcap sync docs')
181+
}
182+
164183
const tokenMapping: RateEngine = async () => {
165184
const mapping: TokenMap = {}
166185

src/v3/providers/constantRates.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ import { dbSettings } from './couch'
1212
const constantRateSyncDoc = syncedDocument('constantrates', asObject(asNumber))
1313
create30MinuteSyncInterval(constantRateSyncDoc, dbSettings)
1414

15+
export const initializeConstantRateSyncDocs = async (): Promise<void> => {
16+
console.log('Initializing constant rate sync docs')
17+
await constantRateSyncDoc.sync(dbSettings).catch((error: unknown) => {
18+
console.error('Initial sync failed for constantrates', error)
19+
throw error
20+
})
21+
console.log('Initialized constant rate sync docs')
22+
}
23+
1524
export const constantRates: RateProvider = {
1625
providerId: 'constantRates',
1726
type: 'api',

src/v3/router.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,26 @@ const automatedCrossChainSyncDoc = syncedDocument(
106106
'crosschain:automated',
107107
asCrossChainMapping
108108
)
109+
110+
export const initializeRouterSyncDocs = async (): Promise<void> => {
111+
console.log('Initializing router sync docs')
112+
await Promise.all([
113+
defaultCrossChainSyncDoc.sync(dbSettings).catch((error: unknown) => {
114+
console.error('Initial sync failed for crosschain', error)
115+
throw error
116+
}),
117+
automatedCrossChainSyncDoc.sync(dbSettings).catch((error: unknown) => {
118+
console.error('Initial sync failed for crosschain:automated', error)
119+
throw error
120+
}),
121+
v2CurrencyCodeMapSyncDoc.sync(dbSettings).catch((error: unknown) => {
122+
console.error('Initial sync failed for v2CurrencyCodeMap', error)
123+
throw error
124+
})
125+
])
126+
console.log('Initialized router sync docs')
127+
}
128+
109129
create30MinuteSyncInterval(defaultCrossChainSyncDoc, dbSettings)
110130
create30MinuteSyncInterval(automatedCrossChainSyncDoc, dbSettings)
111131
create30MinuteSyncInterval(v2CurrencyCodeMapSyncDoc, dbSettings)

src/v3/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,12 +375,12 @@ export const create30MinuteSyncInterval = (
375375
.sync(db)
376376
.then(() => {
377377
setInterval(() => {
378-
syncedDocument.sync(db).catch(e => {
378+
syncedDocument.sync(db).catch((e: unknown) => {
379379
console.error('interval sync error', syncedDocument.id, e)
380380
})
381381
}, 30 * ONE_MINUTE)
382382
})
383-
.catch(e => {
383+
.catch((e: unknown) => {
384384
console.error('create30MinuteSyncInterval error', syncedDocument.id, e)
385385
})
386386
}

0 commit comments

Comments
 (0)