Skip to content

Commit cbd3a0c

Browse files
authored
fix(backend): deadlocks (#3320)
* feat: cache fees * feat: fix deadlocks - fixes deadlocks by ensuring we dont open new connections before resolving open transactions - forced knex connections to 1 to help find these cases * feat: add local payment test script * feat: use fee cache instead of withGraphFetched * chore: cleanup comments, test config * chore: format * chore: rm logs, commented out code * fix(backend): out payment service tests - payment returned from createOutgoingPayment previously had walletAddress of undefined (coming from withGraphFetched(quote)). When assigning manually it included wallet address. Updated get methods to include wallet address on quote as well. * test(backend): fix some quote tests * chore: cleanup comments, join on fees again, fix test * chore: rm comment, restore comment * fix: quote, outgoing payment tests * chore: rm comment * fix(performance): local test to use incoming payment, not receiver * fix: rm unused arg * chore: ignore k6 test text output * fix(backend): too many args passed into calculateExpiry * feat(backend): add saveAdditionalQuoteDetails * Revert "feat(backend): add saveAdditionalQuoteDetails" This reverts commit 8e00526. * feat(backend): rm comment
1 parent 14ddf4d commit cbd3a0c

8 files changed

Lines changed: 573 additions & 329 deletions

File tree

packages/backend/src/fee/service.ts

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { BaseService } from '../shared/baseService'
33
import { FeeError } from './errors'
44
import { Fee, FeeType } from './model'
55
import { Pagination, SortOrder } from '../shared/baseModel'
6+
import { CacheDataStore } from '../middleware/cache/data-stores'
67

78
export interface CreateOptions {
89
assetId: string
@@ -21,19 +22,24 @@ export interface FeeService {
2122
sortOrder?: SortOrder
2223
): Promise<Fee[]>
2324
getLatestFee(assetId: string, type: FeeType): Promise<Fee | undefined>
25+
get(id: string): Promise<Fee | undefined>
2426
}
2527

26-
type ServiceDependencies = BaseService
28+
interface ServiceDependencies extends BaseService {
29+
feeCache: CacheDataStore<Fee>
30+
}
2731

2832
export async function createFeeService({
2933
logger,
30-
knex
34+
knex,
35+
feeCache
3136
}: ServiceDependencies): Promise<FeeService> {
3237
const deps: ServiceDependencies = {
3338
logger: logger.child({
3439
service: 'FeeService'
3540
}),
36-
knex
41+
knex,
42+
feeCache
3743
}
3844
return {
3945
create: (options: CreateOptions) => createFee(deps, options),
@@ -43,7 +49,8 @@ export async function createFeeService({
4349
sortOrder = SortOrder.Desc
4450
) => getFeesPage(deps, assetId, pagination, sortOrder),
4551
getLatestFee: (assetId: string, type: FeeType) =>
46-
getLatestFee(deps, assetId, type)
52+
getLatestFee(deps, assetId, type),
53+
get: (id: string) => getById(deps, id)
4754
}
4855
}
4956

@@ -60,15 +67,42 @@ async function getFeesPage(
6067
return await query
6168
}
6269

70+
async function getById(
71+
deps: ServiceDependencies,
72+
id: string
73+
): Promise<Fee | undefined> {
74+
const cachedFee = await deps.feeCache.get(id)
75+
76+
if (cachedFee) {
77+
return cachedFee
78+
}
79+
80+
const fee = await Fee.query(deps.knex).findById(id)
81+
82+
if (fee) await deps.feeCache.set(id, fee)
83+
84+
return fee
85+
}
86+
6387
async function getLatestFee(
6488
deps: ServiceDependencies,
6589
assetId: string,
6690
type: FeeType
6791
): Promise<Fee | undefined> {
68-
return await Fee.query(deps.knex)
92+
const cachedFee = await deps.feeCache.get(`${assetId}${type}`)
93+
94+
if (cachedFee) {
95+
return cachedFee
96+
}
97+
98+
const latestFee = await Fee.query(deps.knex)
6999
.where({ assetId, type })
70100
.orderBy('createdAt', 'desc')
71101
.first()
102+
103+
if (latestFee) await deps.feeCache.set(`${assetId}${type}`, latestFee)
104+
105+
return latestFee
72106
}
73107

74108
async function createFee(
@@ -86,12 +120,15 @@ async function createFee(
86120
}
87121

88122
try {
89-
return await Fee.query(deps.knex).insertAndFetch({
123+
const fee = await Fee.query(deps.knex).insertAndFetch({
90124
assetId: assetId,
91125
type: type,
92126
basisPointFee: basisPoints,
93127
fixedFee: fixed
94128
})
129+
130+
await deps.feeCache.set(`${assetId}${type}`, fee)
131+
return fee
95132
} catch (error) {
96133
if (error instanceof ForeignKeyViolationError) {
97134
return FeeError.UnknownAsset

packages/backend/src/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,8 @@ export function initIocContainer(
419419
const knex = await deps.use('knex')
420420
return await createFeeService({
421421
logger: logger,
422-
knex: knex
422+
knex: knex,
423+
feeCache: createInMemoryDataStore(config.localCacheDuration)
423424
})
424425
})
425426

@@ -513,7 +514,8 @@ export function initIocContainer(
513514
walletAddressService: await deps.use('walletAddressService'),
514515
quoteService: await deps.use('quoteService'),
515516
assetService: await deps.use('assetService'),
516-
telemetry: await deps.use('telemetry')
517+
telemetry: await deps.use('telemetry'),
518+
feeService: await deps.use('feeService')
517519
})
518520
})
519521

0 commit comments

Comments
 (0)