From 720e7d907bdc13827b9d5fc684df132d25c896df Mon Sep 17 00:00:00 2001 From: Sairam Girirao <105053210+Sairam-g9162@users.noreply.github.com> Date: Wed, 18 Jun 2025 12:22:02 +0530 Subject: [PATCH] Injimob 3186 - Added TTL to the cache (#1947) * [INJIMOB-3186]:Added ttl to the cache Signed-off-by: sairam-g9162 * [INJIMOB-3186]: Added TTL to cache Signed-off-by: sairam-g9162 * [INJIMOB-3186]-Add TTL to cache Signed-off-by: sairam-g9162 * INJIMOB-3186 Added TTL to cache with dynamic update from config Signed-off-by: Sairam Girirao * [INJIMOB-3186]: Resolved review comments for card INJIMOB-3186 Signed-off-by: Sairam Girirao --------- Signed-off-by: sairam-g9162 Signed-off-by: Sairam Girirao --- machines/app.ts | 31 ++++++++++++++++++++ shared/InitialConfig.ts | 1 + shared/api.ts | 63 ++++++++++++++++++++++++++++------------- shared/constants.ts | 6 ++++ 4 files changed, 81 insertions(+), 20 deletions(-) diff --git a/machines/app.ts b/machines/app.ts index 51fb5385..2e7834cc 100644 --- a/machines/app.ts +++ b/machines/app.ts @@ -20,6 +20,7 @@ import { changeEsignetUrl, ESIGNET_BASE_URL, isAndroid, + updateCacheTTL, MIMOTO_BASE_URL, SETTINGS_STORE_KEY, } from '../shared/constants'; @@ -40,6 +41,7 @@ import { checkAllKeyPairs, generateKeyPairsAndStoreOrder, } from '../shared/cryptoutil/cryptoUtil'; +import getAllConfigurations from '../shared/api'; const DeepLinkIntent = NativeModules.DeepLinkIntent; @@ -153,6 +155,21 @@ export const appMachine = model.createMachine( invoke: { src: 'generateKeyPairsAndStoreOrder', onDone: [ + { + target: 'fetchConfig', + }, + ], + }, + }, + fetchConfig: { + invoke: { + src: 'fetchAndUpdateCacheTTLFromConfig', + onDone: [ + { + target: 'checkKeyPairs', + }, + ], + onError: [ { target: 'checkKeyPairs', }, @@ -512,6 +529,11 @@ export const appMachine = model.createMachine( generateKeyPairsAndStoreOrder: async () => { return await generateKeyPairsAndStoreOrder(); }, + + fetchAndUpdateCacheTTLFromConfig: async () => { + return await updateCacheTTLFromConfig(); + }, + checkNetworkState: () => callback => { return NetInfo.addEventListener(state => { if (state.isConnected) { @@ -532,6 +554,15 @@ interface AppInfo { type State = StateFrom; +const updateCacheTTLFromConfig = async () => { + const response = await getAllConfigurations(undefined, false); + if (response && response.cacheTTLInMilliSeconds) { + console.info( + 'All Properties API is called and updated the cacheTTL based on config/OnErrorHardCodedValue', + ); + } +}; + export function selectAppInfo(state: State) { return state.context.info; } diff --git a/shared/InitialConfig.ts b/shared/InitialConfig.ts index cef9f230..84516b61 100644 --- a/shared/InitialConfig.ts +++ b/shared/InitialConfig.ts @@ -18,5 +18,6 @@ export const INITIAL_CONFIG = { aboutInjiUrl: 'https://docs.mosip.io/inji/inji-wallet/inji-mobile', faceSdkModelUrl: '', openId4VCIDownloadVCTimeout: '30000', + cacheTTLInMilliSeconds: '3600000', }, }; diff --git a/shared/api.ts b/shared/api.ts index ab6e5aa5..551c05b6 100644 --- a/shared/api.ts +++ b/shared/api.ts @@ -3,6 +3,8 @@ import { API_CACHED_STORAGE_KEYS, changeCrendetialRegistry, COMMON_PROPS_KEY, + CACHE_TTL, + updateCacheTTL, } from './constants'; import {INITIAL_CONFIG} from './InitialConfig'; import {getItem, setItem} from '../machines/store'; @@ -17,6 +19,23 @@ import { import {TelemetryConstants} from './telemetry/TelemetryConstants'; import NetInfo from '@react-native-community/netinfo'; +const createCacheObject = (response: any) => { + const currentTime = Date.now(); + return { + response, + cachedTime: currentTime, + }; +}; + +const isCacheValid = (cachedData: any) => { + if (!cachedData?.cachedTime || typeof cachedData.cachedTime !== 'number') { + return false; + } + const currentTime = Date.now(); + const expiryTime = Number(cachedData.cachedTime) + CACHE_TTL; + return currentTime < expiryTime; +}; + export const API_URLS: ApiUrls = { trustedVerifiersList: { method: 'GET', @@ -231,14 +250,15 @@ async function generateCacheAPIFunctionWithCachePreference( onErrorHardCodedValue?: any, ) { try { - const response = await getItem(cacheKey, null, ''); - - if (response) { - return response; + const cachedData = await getItem(cacheKey, null, ''); + if (cachedData && isCacheValid(cachedData)) { + console.info('Returned cached response for' + cacheKey); + return cachedData.response; } else { const response = await fetchCall(); - setItem(cacheKey, response, '').then(() => - console.log('Cached response for ' + cacheKey), + const cacheObject = createCacheObject(response); + setItem(cacheKey, cacheObject, '').then(() => + console.info('Cached response for ' + cacheKey), ); return response; @@ -263,10 +283,18 @@ async function generateCacheAPIFunctionWithAPIPreference( fetchCall: (...props: any[]) => any, onErrorHardCodedValue?: any, ) { + let cacheObject; try { const response = await fetchCall(); - setItem(cacheKey, response, '').then(() => - console.log('Cached response for ' + cacheKey), + if (!response) { + throw new Error('Received Empty response in fetch call'); + } + if (response?.cacheTTLInMilliSeconds) { + updateCacheTTL(Number(response.cacheTTLInMilliSeconds)); + } + cacheObject = createCacheObject(response); + setItem(cacheKey, cacheObject, '').then(() => + console.info('Cached response for ' + cacheKey), ); return response; } catch (error) { @@ -274,22 +302,17 @@ async function generateCacheAPIFunctionWithAPIPreference( cache key:${cacheKey} and has onErrorHardCodedValue:${ onErrorHardCodedValue != undefined }`); - console.error(`The error in fetching api ${cacheKey}`, error); - var response = null; + var cachedData = null; if (!(await NetInfo.fetch()).isConnected) { - response = await getItem(cacheKey, null, ''); + cachedData = await getItem(cacheKey, null, ''); } - if (response) { - return response; + if (cachedData && isCacheValid(cachedData)) { + return cachedData.response; + } else if (onErrorHardCodedValue != undefined) { + return onErrorHardCodedValue; } else { - if (response == null) { - throw error; - } else if (onErrorHardCodedValue != undefined) { - return onErrorHardCodedValue; - } else { - throw error; - } + throw error; } } } diff --git a/shared/constants.ts b/shared/constants.ts index d1f39bf1..2045177b 100644 --- a/shared/constants.ts +++ b/shared/constants.ts @@ -12,6 +12,7 @@ import {KeyTypes} from './cryptoutil/KeyTypes'; export let MIMOTO_BASE_URL = MIMOTO_HOST; export let ESIGNET_BASE_URL = ESIGNET_HOST; export let DEBUG_MODE_ENABLED = DEBUG_MODE === 'true'; +export let CACHE_TTL = 60 * 60 * 1000; export const LIVENESS_CHECK = LIVENESS_DETECTION === 'true'; export const LIVENESS_THRESHOLD = 0.4; @@ -20,6 +21,11 @@ export const changeCrendetialRegistry = (host: string) => (MIMOTO_BASE_URL = host); export const changeEsignetUrl = (host: string) => (ESIGNET_BASE_URL = host); +export const updateCacheTTL = (ttl: number) => { + console.info(`Updated CACHE_TTL as per config: ${ttl} ms`); + CACHE_TTL = ttl; +}; + export const COMMON_PROPS_KEY: string = 'CommonPropsKey-' + '6964d04a-9268-11ed-a1eb-0242ac120002';