refactor: store w transaction

This commit is contained in:
Andres Aya
2023-04-20 08:14:11 -05:00
parent 28be45a9b4
commit 2b27416af0
2 changed files with 23 additions and 28 deletions

View File

@@ -82,7 +82,7 @@ export type SignalKeyStore = {
export type SignalKeyStoreWithTransaction = SignalKeyStore & {
isInTransaction: () => boolean
transaction(exec: () => Promise<void>): Promise<void>
transaction<T>(exec: () => Promise<T>): Promise<T>
}
export type TransactionCapabilityOptions = {
@@ -92,7 +92,7 @@ export type TransactionCapabilityOptions = {
export type SignalAuthState = {
creds: SignalCreds
keys: SignalKeyStore
keys: SignalKeyStore | SignalKeyStoreWithTransaction
}
export type AuthenticationState = {

View File

@@ -93,32 +93,25 @@ export const addTransactionCapability = (
let transactionCache: SignalDataSet = { }
let mutations: SignalDataSet = { }
/**
* prefetches some data and stores in memory,
* useful if these data points will be used together often
* */
const prefetch = async<T extends keyof SignalDataTypeMap>(type: T, ids: string[]) => {
const dict = transactionCache[type]
const idsRequiringFetch = dict
? ids.filter(item => typeof dict[item] !== 'undefined')
: ids
// only fetch if there are any items to fetch
if(idsRequiringFetch.length) {
dbQueriesInTransaction += 1
const result = await state.get(type, idsRequiringFetch)
transactionCache[type] ||= {}
transactionCache[type] = Object.assign(
transactionCache[type]!,
result
)
}
}
return {
get: async(type, ids) => {
if(inTransaction) {
await prefetch(type, ids)
const dict = transactionCache[type]
const idsRequiringFetch = dict
? ids.filter(item => typeof dict[item] !== 'undefined')
: ids
// only fetch if there are any items to fetch
if(idsRequiringFetch.length) {
dbQueriesInTransaction += 1
const result = await state.get(type, idsRequiringFetch)
transactionCache[type] ||= {}
Object.assign(
transactionCache[type]!,
result
)
}
return ids.reduce(
(dict, id) => {
const value = transactionCache[type]?.[id]
@@ -148,16 +141,17 @@ export const addTransactionCapability = (
}
},
isInTransaction: () => inTransaction,
transaction: async(work) => {
async transaction(work) {
let result: Awaited<ReturnType<typeof work>>
// if we're already in a transaction,
// just execute what needs to be executed -- no commit required
if(inTransaction) {
await work()
result = await work()
} else {
logger.trace('entering transaction')
inTransaction = true
try {
await work()
result = await work()
if(Object.keys(mutations).length) {
logger.trace('committing transaction')
// retry mechanism to ensure we've some recovery
@@ -184,6 +178,7 @@ export const addTransactionCapability = (
dbQueriesInTransaction = 0
}
}
return result
}
}
}