Skip to content

Commit

Permalink
Refactor: Replaced map upload queue with arrary (#747)
Browse files Browse the repository at this point in the history
* Refactor: Replaced map upload queue with arrary

* Refactor: Using slice(0) to clone array instead of spread operator

* Refactor: using Array.some instead of Array.find

As I do not need to the stored element
  • Loading branch information
alfetopito authored Jun 29, 2022
1 parent 596abcf commit 42ecff3
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 60 deletions.
62 changes: 24 additions & 38 deletions src/custom/state/appData/atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import {
AddAppDataToUploadQueueParams,
AppDataPendingToUpload,
AppDataInfo,
FlattenedAppDataFromUploadQueue,
RemoveAppDataFromUploadQueueParams,
UpdateAppDataOnUploadQueueParams,
} from 'state/appData/types'
import { buildAppDataRecordKey, parseAppDataRecordKey } from 'state/appData/utils'
import { buildDocFilterFn, buildInverseDocFilterFn } from 'state/appData/utils'

/**
* Base atom that store the current appDataInfo
Expand All @@ -21,7 +20,7 @@ export const appDataInfoAtom = atom<AppDataInfo | null>(null)
*/
export const appDataUploadQueueAtom = atomWithStorage<AppDataPendingToUpload>(
'appDataUploadQueue', // local storage key
{}
[]
)

/**
Expand All @@ -32,12 +31,13 @@ export const addAppDataToUploadQueueAtom = atom(
(get, set, { chainId, orderId, appData }: AddAppDataToUploadQueueParams) => {
set(appDataUploadQueueAtom, () => {
const docs = get(appDataUploadQueueAtom)
const key = buildAppDataRecordKey({ chainId, orderId })

return {
...docs,
[key]: { ...appData, uploading: false, failedAttempts: 0 },
if (docs.some(buildDocFilterFn(chainId, orderId))) {
// Entry already in the queue, ignore
return docs
}

return [...docs, { chainId, orderId, ...appData, uploading: false, failedAttempts: 0 }]
})
}
)
Expand All @@ -50,23 +50,28 @@ export const updateAppDataOnUploadQueueAtom = atom(
(get, set, { chainId, orderId, uploading, lastAttempt, failedAttempts }: UpdateAppDataOnUploadQueueParams) => {
set(appDataUploadQueueAtom, () => {
const docs = get(appDataUploadQueueAtom)
const key = buildAppDataRecordKey({ chainId, orderId })
const existingDocIndex = docs.findIndex(buildDocFilterFn(chainId, orderId))

if (!docs[key]) {
if (existingDocIndex === -1) {
// Entry doesn't exist in the queue, ignore
return docs
}

const current = docs[key]
// Create a copy of original docs
const updateDocs = docs.slice(0)

// Using the index, get the value
const existingDoc = docs[existingDocIndex]

return {
...docs,
[key]: {
...current,
uploading: uploading ?? current.uploading,
lastAttempt: lastAttempt ?? current.lastAttempt,
failedAttempts: failedAttempts ?? current.failedAttempts,
},
// Replace existing doc at index with the updated version
updateDocs[existingDocIndex] = {
...existingDoc,
uploading: uploading ?? existingDoc.uploading,
lastAttempt: lastAttempt ?? existingDoc.lastAttempt,
failedAttempts: failedAttempts ?? existingDoc.failedAttempts,
}

return updateDocs
})
}
)
Expand All @@ -77,25 +82,6 @@ export const updateAppDataOnUploadQueueAtom = atom(
export const removeAppDataFromUploadQueueAtom = atom(
null,
(get, set, { chainId, orderId }: RemoveAppDataFromUploadQueueParams) => {
set(appDataUploadQueueAtom, () => {
const docs = { ...get(appDataUploadQueueAtom) }
const key = buildAppDataRecordKey({ chainId, orderId })

delete docs[key]

return docs
})
set(appDataUploadQueueAtom, () => get(appDataUploadQueueAtom).filter(buildInverseDocFilterFn(chainId, orderId)))
}
)

/**
* Read only atom to flatten pending list of appData into a list
*/
export const flattenedAppDataFromUploadQueueAtom = atom((get) => {
const docs = get(appDataUploadQueueAtom)

return Object.keys(docs).map<FlattenedAppDataFromUploadQueue>((key) => ({
...docs[key],
...parseAppDataRecordKey(key),
}))
})
10 changes: 4 additions & 6 deletions src/custom/state/appData/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,17 @@ type AppDataUploadStatus = {
uploading: boolean
}

export type AppDataRecord = AppDataInfo & AppDataUploadStatus

export type AppDataPendingToUpload = Record<string, AppDataRecord>

export type AppDataKeyParams = {
chainId: SupportedChainId
orderId: string
}

export type AppDataRecord = AppDataInfo & AppDataUploadStatus & AppDataKeyParams

export type AppDataPendingToUpload = Array<AppDataRecord>

export type AddAppDataToUploadQueueParams = AppDataKeyParams & {
appData: AppDataInfo
}
export type UpdateAppDataOnUploadQueueParams = AppDataKeyParams & Partial<AppDataUploadStatus>
export type RemoveAppDataFromUploadQueueParams = AppDataKeyParams

export type FlattenedAppDataFromUploadQueue = AppDataKeyParams & AppDataRecord
14 changes: 5 additions & 9 deletions src/custom/state/appData/updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,19 @@ import { AppDataDoc } from '@cowprotocol/cow-sdk'
import { COW_SDK } from 'constants/index'

import {
flattenedAppDataFromUploadQueueAtom,
appDataUploadQueueAtom,
removeAppDataFromUploadQueueAtom,
updateAppDataOnUploadQueueAtom,
} from 'state/appData/atoms'
import {
AppDataKeyParams,
FlattenedAppDataFromUploadQueue,
UpdateAppDataOnUploadQueueParams,
} from 'state/appData/types'
import { AppDataKeyParams, AppDataRecord, UpdateAppDataOnUploadQueueParams } from 'state/appData/types'

const UPLOAD_CHECK_INTERVAL = ms`10s`
const BASE_FOR_EXPONENTIAL_BACKOFF = 2 // in seconds, converted to milliseconds later
const ONE_SECOND = ms`1s`
const MAX_TIME_TO_WAIT = ms`5 minutes`

export function UploadToIpfsUpdater(): null {
const toUpload = useAtomValue(flattenedAppDataFromUploadQueueAtom)
const toUpload = useAtomValue(appDataUploadQueueAtom)
const removePending = useSetAtom(removeAppDataFromUploadQueueAtom)
const updatePending = useSetAtom(updateAppDataOnUploadQueueAtom)

Expand All @@ -47,7 +43,7 @@ export function UploadToIpfsUpdater(): null {
}

async function _uploadToIpfs(
appDataRecord: FlattenedAppDataFromUploadQueue,
appDataRecord: AppDataRecord,
updatePending: (params: UpdateAppDataOnUploadQueueParams) => void,
removePending: (params: AppDataKeyParams) => void
) {
Expand Down Expand Up @@ -82,7 +78,7 @@ function _canUpload(uploading: boolean, attempts: number, lastAttempt?: number):
}

async function _actuallyUploadToIpfs(
appDataRecord: FlattenedAppDataFromUploadQueue,
appDataRecord: AppDataRecord,
updatePending: (params: UpdateAppDataOnUploadQueueParams) => void,
removePending: (params: AppDataKeyParams) => void
) {
Expand Down
14 changes: 7 additions & 7 deletions src/custom/state/appData/utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { AppDataKeyParams } from 'state/appData/types'
import { SupportedChainId } from '@cowprotocol/cow-sdk'

export function buildAppDataRecordKey({ chainId, orderId }: AppDataKeyParams): string {
return `${chainId}-${orderId}`
}
import { AppDataRecord } from 'state/appData/types'

export function parseAppDataRecordKey(key: string): AppDataKeyParams {
const [chainId, orderId] = key.split('-')
export function buildDocFilterFn(chainId: SupportedChainId, orderId: string) {
return (doc: AppDataRecord) => doc.chainId === chainId && doc.orderId === orderId
}

return { chainId, orderId } as unknown as AppDataKeyParams
export function buildInverseDocFilterFn(chainId: SupportedChainId, orderId: string) {
return (doc: AppDataRecord) => doc.chainId !== chainId && doc.orderId !== orderId
}

0 comments on commit 42ecff3

Please sign in to comment.