Skip to content
This repository has been archived by the owner on Oct 4, 2023. It is now read-only.

Commit

Permalink
[C-2886] Improve cache performance (#3792)
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanjeffers authored Jul 25, 2023
1 parent 6fb78f1 commit 5af77ec
Show file tree
Hide file tree
Showing 23 changed files with 231 additions and 179 deletions.
1 change: 1 addition & 0 deletions packages/common/src/models/Cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export type Cache<T> = {
subscribers: { [id: number]: Set<UID> }
subscriptions: { [id: number]: Set<{ uid: UID; kind: Kind }> }
idsToPrune: Set<ID>
entryTTL: number
}
4 changes: 3 additions & 1 deletion packages/common/src/services/remote-config/defaults.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IntKeys, StringKeys, DoubleKeys, BooleanKeys } from './types'

const ETH_PROVIDER_URLS = process.env.REACT_APP_ETH_PROVIDER_URL || ''
const DEFAULT_ENTRY_TTL = 1 /* min */ * 60 /* seconds */ * 1000 /* ms */

export const remoteConfigIntDefaults: { [key in IntKeys]: number | null } = {
[IntKeys.IMAGE_QUICK_FETCH_TIMEOUT_MS]: 5000,
Expand Down Expand Up @@ -31,7 +32,8 @@ export const remoteConfigIntDefaults: { [key in IntKeys]: number | null } = {
[IntKeys.BUY_AUDIO_WALLET_POLL_MAX_RETRIES]: 120,
[IntKeys.BUY_AUDIO_SLIPPAGE]: 3,
[IntKeys.GATED_TRACK_POLL_INTERVAL_MS]: 1000,
[IntKeys.DISCOVERY_NOTIFICATIONS_GENESIS_UNIX_TIMESTAMP]: 0
[IntKeys.DISCOVERY_NOTIFICATIONS_GENESIS_UNIX_TIMESTAMP]: 0,
[IntKeys.CACHE_ENTRY_TTL]: DEFAULT_ENTRY_TTL
}

export const remoteConfigStringDefaults: {
Expand Down
2 changes: 2 additions & 0 deletions packages/common/src/services/remote-config/feature-flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export enum FeatureFlags {
CHAT_ENABLED = 'chat_enabled',
FAST_CACHE = 'fast_cache',
SAFE_FAST_CACHE = 'safe_fast_cache',
SIMPLE_CACHE = 'simple_cache',
PODCAST_CONTROL_UPDATES_ENABLED = 'podcast_control_updates_enabled',
PODCAST_CONTROL_UPDATES_ENABLED_FALLBACK = 'podcast_control_updates_enabled_fallback',
LAZY_USERBANK_CREATION_ENABLED = 'lazy_userbank_creation_enabled',
Expand Down Expand Up @@ -89,6 +90,7 @@ export const flagDefaults: FlagDefaults = {
[FeatureFlags.CHAT_ENABLED]: false,
[FeatureFlags.FAST_CACHE]: false,
[FeatureFlags.SAFE_FAST_CACHE]: false,
[FeatureFlags.SIMPLE_CACHE]: false,
[FeatureFlags.PODCAST_CONTROL_UPDATES_ENABLED]: false,
[FeatureFlags.PODCAST_CONTROL_UPDATES_ENABLED_FALLBACK]: false,
[FeatureFlags.LAZY_USERBANK_CREATION_ENABLED]: false,
Expand Down
6 changes: 5 additions & 1 deletion packages/common/src/services/remote-config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,11 @@ export enum IntKeys {
* The start time for discovery notifications indexing, used to determine
* when we should rollback to identity notifications
*/
DISCOVERY_NOTIFICATIONS_GENESIS_UNIX_TIMESTAMP = 'DISCOVERY_NOTIFICATIONS_GENESIS_UNIX_TIMESTAMP'
DISCOVERY_NOTIFICATIONS_GENESIS_UNIX_TIMESTAMP = 'DISCOVERY_NOTIFICATIONS_GENESIS_UNIX_TIMESTAMP',
/**
* Cache entry TTL to determine when a cache value should be overwritten with new instance
*/
CACHE_ENTRY_TTL = 'CACHE_ENTRY_TTL'
}

export enum BooleanKeys {
Expand Down
90 changes: 66 additions & 24 deletions packages/common/src/store/cache/actions.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// @ts-nocheck
import { pick } from 'lodash'

import { ID, UID } from 'models/Identifiers'
import { Kind } from 'models/Kind'
import { getConfirmCalls } from 'store/confirmer/selectors'
import { getIdFromKindId } from 'utils/uid'

import { getCache } from './selectors'
import { Metadata } from './types'

export const ADD = 'CACHE/ADD'
export const ADD_SUCCEEDED = 'CACHE/ADD_SUCCEEDED'
export const ADD_ENTRIES = 'CACHE/ADD_ENTRIES'
export const UPDATE = 'CACHE/UPDATE'
Expand All @@ -17,22 +20,64 @@ export const UNSUBSCRIBE_SUCCEEDED = 'CACHE/UNSUBSCRIBE_SUCCEEDED'
export const REMOVE = 'CACHE/REMOVE'
export const REMOVE_SUCCEEDED = 'CACHE/REMOVE_SUCCEEDED'
export const SET_EXPIRED = 'CACHE/SET_EXPIRED'
export const SET_CACHE_TYPE = 'CACHE/SET_CACHE_TYPE'
export const SET_CACHE_CONFIG = 'CACHE/SET_CONFIG'

type Entry<EntryT extends Metadata = Metadata> = {
id: ID
uid?: UID
metadata: EntryT
timestamp?: number
}

/**
* Signals to add an entry to the cache.
* @param {Kind} kind
* @param {array} entries { id, uid, metadata }
* @param {boolean} replace optionally replaces the entire entry instead of joining metadata
* @param {boolean} persist optionally persists the cache entry to indexdb
*/
export const add = (kind, entries, replace = false, persist = true) => ({
type: ADD,
kind,
entries,
replace,
persist
})
export const add = (
kind: Kind,
entries: Entry[],
// optionally replaces the entire entry instead of joining metadata
replace = false,
// optionally persists the cache entry to indexdb
persist = true
) => {
return async (dispatch, getState) => {
const state = await getState()
const confirmCalls = getConfirmCalls(state)
const cache = getCache(state, { kind })

const confirmCallsInCache = pick(
cache.entries,
Object.keys(confirmCalls).map((kindId) => getIdFromKindId(kindId))
)

const entriesToAdd = []
const entriesToSubscribe = []
entries.forEach((entry) => {
// If something is confirming and in the cache, we probably don't
// want to replace it (unless explicit) because we would lose client
// state, e.g. "has_current_user_reposted"
if (!replace && entry.id in confirmCallsInCache) {
entriesToSubscribe.push({ uid: entry.uid, id: entry.id })
} else {
entriesToAdd.push(entry)
}
})

if (entriesToAdd.length > 0) {
dispatch({
type: ADD_SUCCEEDED,
kind,
entries: entriesToAdd,
replace,
persist
})
}

if (entriesToSubscribe.length > 0) {
dispatch(cacheActions.subscribe(kind, entriesToSubscribe))
}
}
}

export type AddSuccededAction<EntryT extends Metadata = Metadata> = {
type: typeof ADD_SUCCEEDED
Expand All @@ -49,13 +94,6 @@ export type AddSuccededAction<EntryT extends Metadata = Metadata> = {
persist?: boolean
}

type Entry<EntryT extends Metadata = Metadata> = {
id: ID
uid: UID
metadata: EntryT
timestamp: number
}

type EntriesByKind<EntryT extends Metadata = Metadata> = {
[key: Kind]: Entry<EntryT>[]
}
Expand Down Expand Up @@ -215,9 +253,13 @@ export const setExpired = (kind, id) => ({

export type CacheType = 'normal' | 'fast' | 'safe-fast'

export type SetCacheTypeAction = { cacheType: CacheType }
export type SetCacheConfigAction = {
cacheType: CacheType
entryTTL: number
simple: boolean
}

export const setCacheType = (action: SetCacheTypeAction) => ({
type: SET_CACHE_TYPE,
...action
export const setCacheConfig = (config: SetCacheConfigAction) => ({
type: SET_CACHE_CONFIG,
...config
})
Loading

0 comments on commit 5af77ec

Please sign in to comment.