Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(entities-*): persist fetcher cache key within session #1820

Merged
merged 4 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<template>
<div class="kong-ui-entities-ca-certificates-list">
<EntityBaseTable
:cache-identifier="cacheIdentifier"
:cache-identifier="cacheId"
:disable-sorting="disableSorting"
:empty-state-options="emptyStateOptions"
enable-entity-actions
:error-message="errorMessage"
:fetcher="fetcher"
:fetcher-cache-key="fetcherCacheKey"
pagination-type="offset"
preferences-storage-key="kong-ui-entities-ca-certificates-list"
:preferences-storage-key="preferencesStorageKey"
:query="filterQuery"
:table-headers="tableHeaders"
@clear-search-input="clearFilter"
Expand Down Expand Up @@ -225,7 +225,6 @@ const { i18n: { t, formatUnixTimeStamp }, i18nT } = composables.useI18n()
const router = useRouter()

const { axiosInstance } = useAxios(props.config?.axiosRequestConfig)
const fetcherCacheKey = ref<number>(1)

/**
* Table Headers
Expand Down Expand Up @@ -273,7 +272,14 @@ const filterConfig = computed<InstanceType<typeof EntityFilter>['$props']['confi
} as FuzzyMatchFilterConfig
})

const { fetcher, fetcherState } = useFetcher(props.config, fetcherBaseUrl.value)
const preferencesStorageKey = 'kong-ui-entities-ca-certificates-list'
const cacheId = computed(() => props.cacheIdentifier || preferencesStorageKey)
Copy link
Member

@adamdehaven adamdehaven Nov 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: I'm not sure the fallback here makes sense. I understand it will work; however, there's no documentation or expectation that the table's cache identifier will fallback to the table preferences storage key.

If anyone upstream was utilizing one or the other to save data in localStorage or the session, etc., this would be unexpected and could cause conflicting values to override each other in the upstream implementation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the cacheId isn't used for local storage, it's used for as SWRV cache key so there shouldn't be any clashes unless the preferences storage key was used as a swrv cache key somewhere.

Either way, we can mitigate this risk by adding some static string like:

const cacheId = computed(() => `${props.cacheIdentifier || preferencesStorageKey}-cache-identifier`)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the cacheId isn't used for local storage

It's not currently that we know of, but it could be

Copy link
Contributor Author

@Justineo Justineo Dec 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this because in <EntityBaseTable>, we have the following logic:

const cacheId = computed((): string => {
// Utilize the cacheIdentifier if provided; otherwise, fallback to the preferencesStorageKey that should always be defined
return props.cacheIdentifier || props.preferencesStorageKey
})

I thought we should apply similar logic to ensure a consistent fetcher cache key. However, if this isn't necessary, I believe we can simply remove the fallback.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To add further context: In <EntityBaseTable>, the props.cacheIdentifier || props.preferencesStorageKey is already used as both the cacheIdentifier for <KTableData> and the key for table preferences in localStorage. Even if users do not provide a cacheIdentifier for the entity lists, the fetcher results are stored using fallback keys derived from preferencesStorageKey. Therefore, the intention here is to generate keys for persistent fetcherCacheKey containers here using the same logic.

Before this change: Even when cacheIdentifier is not provided, caching still occurs, and its behavior is essentially consistent with when it is provided.
After: If cacheIdentifier is not passed, the fetcherCacheKey cannot be persisted, leading to inconsistent behavior compared to when it is provided. That said, this inconsistency only reflects the behavior prior to optimization, so the impact may not be significant. And indeed, I also think the current approach reveals a bit of abstraction leakage for <EntityBaseTable>. So I think I'd just remove the fallback.

@adamdehaven @kaiarrowood


const {
fetcher,
fetcherState,
fetcherCacheKey,
} = useFetcher({ ...props.config, cacheIdentifier: cacheId.value }, fetcherBaseUrl.value)

const clearFilter = (): void => {
filterQuery.value = ''
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<template>
<div class="kong-ui-entities-certificates-list">
<EntityBaseTable
:cache-identifier="cacheIdentifier"
:cache-identifier="cacheId"
:disable-sorting="disableSorting"
:empty-state-options="emptyStateOptions"
enable-entity-actions
:error-message="errorMessage"
:fetcher="fetcher"
:fetcher-cache-key="fetcherCacheKey"
pagination-type="offset"
preferences-storage-key="kong-ui-entities-certificates-list"
:preferences-storage-key="preferencesStorageKey"
:query="filterQuery"
:table-headers="tableHeaders"
@clear-search-input="clearFilter"
Expand Down Expand Up @@ -255,7 +255,6 @@ const { i18n: { t, formatUnixTimeStamp }, i18nT } = composables.useI18n()
const router = useRouter()

const { axiosInstance } = useAxios(props.config?.axiosRequestConfig)
const fetcherCacheKey = ref<number>(1)

/**
* Table Headers
Expand Down Expand Up @@ -305,7 +304,14 @@ const filterConfig = computed<InstanceType<typeof EntityFilter>['$props']['confi
} as FuzzyMatchFilterConfig
})

const { fetcher, fetcherState } = useFetcher(props.config, fetcherBaseUrl.value)
const preferencesStorageKey = 'kong-ui-entities-certificates-list'
const cacheId = computed(() => props.cacheIdentifier || preferencesStorageKey)

const {
fetcher,
fetcherState,
fetcherCacheKey,
} = useFetcher({ ...props.config, cacheIdentifier: cacheId.value }, fetcherBaseUrl.value)

const clearFilter = (): void => {
filterQuery.value = ''
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="kong-ui-entities-consumer-credentials-list">
<EntityBaseTable
:cache-identifier="cacheIdentifier"
:cache-identifier="cacheId"
disable-row-click
disable-sorting
:empty-state-options="emptyStateOptions"
Expand All @@ -10,7 +10,7 @@
:fetcher="fetcher"
:fetcher-cache-key="fetcherCacheKey"
pagination-type="offset"
preferences-storage-key="kong-ui-entities-consumer-credentials-list"
:preferences-storage-key="preferencesStorageKey"
:table-headers="tableHeaders"
@sort="resetPagination"
>
Expand Down Expand Up @@ -259,7 +259,6 @@ const props = defineProps({
const { i18n: { t, formatUnixTimeStamp } } = composables.useI18n()

const { axiosInstance } = useAxios(props.config?.axiosRequestConfig)
const fetcherCacheKey = ref<number>(1)

/**
* Table Headers
Expand Down Expand Up @@ -328,7 +327,14 @@ const fetcherBaseUrl = computed((): string => {
return url
})

const { fetcher, fetcherState } = useFetcher(props.config, fetcherBaseUrl)
const preferencesStorageKey = 'kong-ui-entities-consumer-credentials-list'
const cacheId = computed(() => props.cacheIdentifier || preferencesStorageKey)

const {
fetcher,
fetcherState,
fetcherCacheKey,
} = useFetcher({ ...props.config, cacheIdentifier: cacheId.value }, fetcherBaseUrl.value)

const resetPagination = (): void => {
// Increment the cache key on sort
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="kong-ui-entities-consumer-groups-list">
<EntityBaseTable
:cache-identifier="cacheIdentifier"
:cache-identifier="cacheId"
:disable-pagination="isConsumerPage && !config.paginatedEndpoint"
:disable-sorting="disableSorting"
:empty-state-options="emptyStateOptions"
Expand Down Expand Up @@ -262,11 +262,6 @@ const { i18nT, i18n: { t } } = composables.useI18n()
const router = useRouter()

const { axiosInstance } = useAxios(props.config?.axiosRequestConfig)
const fetcherCacheKey = ref<number>(1)
const isConsumerPage = computed<boolean>(() => !!props.config.consumerId)
const preferencesStorageKey = computed<string>(
() => isConsumerPage.value ? 'kong-ui-entities-consumer-groups-list-in-consumer-page' : 'kong-ui-entities-consumer-groups-list',
)

/**
* Table Headers
Expand Down Expand Up @@ -331,14 +326,23 @@ const filterConfig = computed<InstanceType<typeof EntityFilter>['$props']['confi
} as FuzzyMatchFilterConfig
})

const isConsumerPage = computed<boolean>(() => !!props.config.consumerId)
const preferencesStorageKey = computed<string>(
() => isConsumerPage.value ? 'kong-ui-entities-consumer-groups-list-in-consumer-page' : 'kong-ui-entities-consumer-groups-list',
)
const cacheId = computed(() => props.cacheIdentifier || preferencesStorageKey.value)
const dataKeyName = computed((): string | undefined => {
if (props.config.app === 'konnect' && filterQuery.value) {
return 'consumer_group'
}
return isConsumerPage.value && !props.config.paginatedEndpoint ? 'consumer_groups' : undefined
})

const { fetcher, fetcherState } = useFetcher(props.config, fetcherBaseUrl.value, dataKeyName)
const {
fetcher,
fetcherState,
fetcherCacheKey,
} = useFetcher({ ...props.config, cacheIdentifier: cacheId.value }, fetcherBaseUrl.value, dataKeyName)

const clearFilter = (): void => {
filterQuery.value = ''
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="kong-ui-entities-consumers-list">
<EntityBaseTable
:cache-identifier="cacheIdentifier"
:cache-identifier="cacheId"
:disable-sorting="disableSorting"
:empty-state-options="emptyStateOptions"
enable-entity-actions
Expand Down Expand Up @@ -262,11 +262,6 @@ const { i18nT, i18n: { t } } = composables.useI18n()
const router = useRouter()

const { axiosInstance } = useAxios(props.config?.axiosRequestConfig)
const fetcherCacheKey = ref<number>(1)
const isConsumerGroupPage = computed<boolean>(() => !!props.config.consumerGroupId)
const preferencesStorageKey = computed<string>(
() => isConsumerGroupPage.value ? 'kong-ui-entities-consumers-list-in-group-page' : 'kong-ui-entities-consumers-list',
)

/**
* Table Headers
Expand Down Expand Up @@ -323,8 +318,18 @@ const filterConfig = computed<InstanceType<typeof EntityFilter>['$props']['confi
schema: props.config.filterSchema,
} as FuzzyMatchFilterConfig
})

const isConsumerGroupPage = computed<boolean>(() => !!props.config.consumerGroupId)
const preferencesStorageKey = computed<string>(
() => isConsumerGroupPage.value ? 'kong-ui-entities-consumers-list-in-group-page' : 'kong-ui-entities-consumers-list',
)
const cacheId = computed(() => props.cacheIdentifier || preferencesStorageKey.value)
const dataKeyName = computed((): string | undefined => isConsumerGroupPage.value && !props.config.paginatedEndpoint ? 'consumers' : undefined)
const { fetcher, fetcherState } = useFetcher(props.config, fetcherBaseUrl.value, dataKeyName.value)
const {
fetcher,
fetcherState,
fetcherCacheKey,
} = useFetcher({ ...props.config, cacheIdentifier: cacheId.value }, fetcherBaseUrl.value, dataKeyName.value)

const clearFilter = (): void => {
filterQuery.value = ''
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<template>
<div class="kong-ui-entities-gateway-services-list">
<EntityBaseTable
:cache-identifier="cacheIdentifier"
:cache-identifier="cacheId"
:default-table-preferences="defaultTablePreferences"
:disable-sorting="disableSorting"
:empty-state-options="emptyStateOptions"
enable-entity-actions
:error-message="errorMessage"
:fetcher="fetcher"
:fetcher-cache-key="fetchCacheKey"
:fetcher-cache-key="fetcherCacheKey"
pagination-type="offset"
preferences-storage-key="kong-ui-entities-gateway-services-list"
:preferences-storage-key="preferencesStorageKey"
:query="filterQuery"
:table-headers="tableHeaders"
@clear-search-input="clearFilter"
Expand Down Expand Up @@ -259,7 +259,6 @@ const { i18n: { t, formatUnixTimeStamp } } = composables.useI18n()
const router = useRouter()

const { axiosInstance } = useAxios(props.config?.axiosRequestConfig)
const fetchCacheKey = ref<number>(1)

/**
* Table Headers
Expand Down Expand Up @@ -329,15 +328,22 @@ const filterConfig = computed<InstanceType<typeof EntityFilter>['$props']['confi
} as FuzzyMatchFilterConfig
})

const { fetcher, fetcherState } = useFetcher(props.config, fetcherBaseUrl.value)
const preferencesStorageKey = 'kong-ui-entities-gateway-services-list'
const cacheId = computed(() => props.cacheIdentifier || preferencesStorageKey)

const {
fetcher,
fetcherState,
fetcherCacheKey,
} = useFetcher({ ...props.config, cacheIdentifier: cacheId.value }, fetcherBaseUrl.value)

const clearFilter = (): void => {
filterQuery.value = ''
}

const resetPagination = (): void => {
// Increment the cache key on sort
fetchCacheKey.value++
fetcherCacheKey.value++
}

/**
Expand Down Expand Up @@ -536,7 +542,7 @@ const deleteRow = async (): Promise<void> => {
emit('delete:success', gatewayServiceToBeDeleted.value)

hideDeleteModal()
fetchCacheKey.value++
fetcherCacheKey.value++
} catch (error: any) {
deleteModalError.value = error.response?.data?.message ||
error.message ||
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<template>
<div class="kong-ui-entities-key-sets-list">
<EntityBaseTable
:cache-identifier="cacheIdentifier"
:cache-identifier="cacheId"
:disable-sorting="disableSorting"
:empty-state-options="emptyStateOptions"
enable-entity-actions
:error-message="errorMessage"
:fetcher="fetcher"
:fetcher-cache-key="fetcherCacheKey"
pagination-type="offset"
preferences-storage-key="kong-ui-entities-key-sets-list"
:preferences-storage-key="preferencesStorageKey"
:query="filterQuery"
:table-headers="tableHeaders"
@clear-search-input="clearFilter"
Expand Down Expand Up @@ -212,7 +212,6 @@ const { i18n: { t } } = composables.useI18n()
const router = useRouter()

const { axiosInstance } = useAxios(props.config?.axiosRequestConfig)
const fetcherCacheKey = ref<number>(1)

/**
* Table Headers
Expand Down Expand Up @@ -263,7 +262,14 @@ const filterConfig = computed<InstanceType<typeof EntityFilter>['$props']['confi
} as FuzzyMatchFilterConfig
})

const { fetcher, fetcherState } = useFetcher(props.config, fetcherBaseUrl.value)
const preferencesStorageKey = 'kong-ui-entities-key-sets-list'
const cacheId = computed(() => props.cacheIdentifier || preferencesStorageKey)

const {
fetcher,
fetcherState,
fetcherCacheKey,
} = useFetcher({ ...props.config, cacheIdentifier: cacheId.value }, fetcherBaseUrl.value)

const clearFilter = (): void => {
filterQuery.value = ''
Expand Down
14 changes: 10 additions & 4 deletions packages/entities/entities-keys/src/components/KeyList.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<template>
<div class="kong-ui-entities-keys-list">
<EntityBaseTable
:cache-identifier="cacheIdentifier"
:cache-identifier="cacheId"
:disable-sorting="disableSorting"
:empty-state-options="emptyStateOptions"
enable-entity-actions
:error-message="errorMessage"
:fetcher="fetcher"
:fetcher-cache-key="fetcherCacheKey"
pagination-type="offset"
preferences-storage-key="kong-ui-entities-keys-list"
:preferences-storage-key="preferencesStorageKey"
:query="filterQuery"
:table-headers="tableHeaders"
@clear-search-input="clearFilter"
Expand Down Expand Up @@ -216,7 +216,6 @@ const { i18n: { t } } = composables.useI18n()
const router = useRouter()

const { axiosInstance } = useAxios(props.config?.axiosRequestConfig)
const fetcherCacheKey = ref<number>(1)

/**
* Table Headers
Expand Down Expand Up @@ -270,7 +269,14 @@ const filterConfig = computed<InstanceType<typeof EntityFilter>['$props']['confi
} as FuzzyMatchFilterConfig
})

const { fetcher, fetcherState } = useFetcher(props.config, fetcherBaseUrl.value)
const preferencesStorageKey = 'kong-ui-entities-keys-list'
const cacheId = computed(() => props.cacheIdentifier || preferencesStorageKey)

const {
fetcher,
fetcherState,
fetcherCacheKey,
} = useFetcher({ ...props.config, cacheIdentifier: cacheId.value }, fetcherBaseUrl.value)

const clearFilter = (): void => {
filterQuery.value = ''
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<template>
<div class="kong-ui-entities-plugins-list">
<EntityBaseTable
:cache-identifier="cacheIdentifier"
:cache-identifier="cacheId"
:disable-sorting="disableSorting"
:empty-state-options="emptyStateOptions"
enable-entity-actions
:error-message="errorMessage"
:fetcher="fetcher"
:fetcher-cache-key="fetcherCacheKey"
pagination-type="offset"
preferences-storage-key="kong-ui-entities-plugins-list"
:preferences-storage-key="preferencesStorageKey"
:query="filterQuery"
:table-headers="tableHeaders"
:title="title"
Expand Down Expand Up @@ -425,9 +425,14 @@ const filterConfig = computed<InstanceType<typeof EntityFilter>['$props']['confi
} as FuzzyMatchFilterConfig
})

const fetcherCacheKey = ref<number>(1)
const preferencesStorageKey = 'kong-ui-entities-plugins-list'
const cacheId = computed(() => props.cacheIdentifier || preferencesStorageKey)

const { fetcher, fetcherState } = useFetcher(props.config, fetcherBaseUrl.value)
const {
fetcher,
fetcherState,
fetcherCacheKey,
} = useFetcher({ ...props.config, cacheIdentifier: cacheId.value }, fetcherBaseUrl.value)

const clearFilter = (): void => {
filterQuery.value = ''
Expand Down
Loading
Loading