From e6ab4faea715a68ae2f0f0a6aa34ce4aef8f9a5e Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 26 Jul 2023 10:13:30 -0600 Subject: [PATCH 01/25] Add param for putting request at the front of the queue --- src/libs/Network/SequentialQueue.js | 5 +++-- src/libs/actions/PersistedRequests.js | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index 93e3ba6bc207..ac71cec554b6 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -101,10 +101,11 @@ NetworkStore.onReconnection(flush); /** * @param {Object} request + * @param {Boolean} [front] whether or not the request should be placed in the front of the queue */ -function push(request) { +function push(request, front = false) { // Add request to Persisted Requests so that it can be retried if it fails - PersistedRequests.save([request]); + PersistedRequests.save([request], front); // If we are offline we don't need to trigger the queue to empty as it will happen when we come back online if (NetworkStore.isOffline()) { diff --git a/src/libs/actions/PersistedRequests.js b/src/libs/actions/PersistedRequests.js index c99ed2ace7fe..e6f25d83926e 100644 --- a/src/libs/actions/PersistedRequests.js +++ b/src/libs/actions/PersistedRequests.js @@ -15,9 +15,10 @@ function clear() { /** * @param {Array} requestsToPersist + * @param {Boolean} [front] whether or not the request should go in the front of the queue */ -function save(requestsToPersist) { - persistedRequests = persistedRequests.concat(requestsToPersist); +function save(requestsToPersist, front = false) { + persistedRequests = front ? persistedRequests.unshift(...requestsToPersist) : persistedRequests.concat(requestsToPersist); Onyx.set(ONYXKEYS.PERSISTED_REQUESTS, persistedRequests); } From 414957082ac06e9739be15ec3eb26af3a0de3a97 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 26 Jul 2023 10:28:21 -0600 Subject: [PATCH 02/25] Add new param for prioritizing a request --- src/libs/API.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/API.js b/src/libs/API.js index 9405fb8f3a51..d1c88f93b669 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -36,8 +36,9 @@ Request.use(Middleware.SaveResponseInOnyx); * @param {Object} [onyxData.optimisticData] - Onyx instructions that will be passed to Onyx.update() before the request is made. * @param {Object} [onyxData.successData] - Onyx instructions that will be passed to Onyx.update() when the response has jsonCode === 200. * @param {Object} [onyxData.failureData] - Onyx instructions that will be passed to Onyx.update() when the response has jsonCode !== 200. + * @param {Boolean} [prioritizeRequest] Whether or not the request should be prioritized at the front of the queue or placed onto the back of the queue */ -function write(command, apiCommandParameters = {}, onyxData = {}) { +function write(command, apiCommandParameters = {}, onyxData = {}, prioritizeRequest = false) { Log.info('Called API write', false, {command, ...apiCommandParameters}); // Optimistically update Onyx @@ -70,7 +71,7 @@ function write(command, apiCommandParameters = {}, onyxData = {}) { }; // Write commands can be saved and retried, so push it to the SequentialQueue - SequentialQueue.push(request); + SequentialQueue.push(request, prioritizeRequest); } /** From 8bff72f52f268e42674ffe32726cf27e9db2bdf7 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 26 Jul 2023 10:28:57 -0600 Subject: [PATCH 03/25] Change param name sent to API --- src/libs/actions/App.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index fbdb20715c55..a6259f68fd34 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -150,7 +150,7 @@ function openApp(fetchIncrementalUpdates = false) { // Include the last update ID when reconnecting so that the server can send incremental updates if they are available. // Otherwise, a full set of app data will be returned. - params.updateIDFrom = onyxUpdatesLastUpdateID; + params.updateIDTo = onyxUpdatesLastUpdateID; } Onyx.disconnect(connectionID); From dab85827d56bcbe7eabb2b1809885581ef111183 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 26 Jul 2023 10:47:22 -0600 Subject: [PATCH 04/25] Fetch incremental updates when receiving pusher events --- src/libs/actions/App.js | 55 +++++++++++++++++++++++----------------- src/libs/actions/User.js | 11 ++++++++ 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index a6259f68fd34..6cba227fec6b 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -151,34 +151,43 @@ function openApp(fetchIncrementalUpdates = false) { // Include the last update ID when reconnecting so that the server can send incremental updates if they are available. // Otherwise, a full set of app data will be returned. params.updateIDTo = onyxUpdatesLastUpdateID; + // @TODO: figure out what this value is supposed to be + params.updateIDFrom = 'TBD'; } Onyx.disconnect(connectionID); // eslint-disable-next-line rulesdir/no-multiple-api-calls const apiMethod = fetchIncrementalUpdates ? API.write : API.read; - apiMethod(fetchIncrementalUpdates ? 'ReconnectApp' : 'OpenApp', params, { - optimisticData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.IS_LOADING_REPORT_DATA, - value: true, - }, - ], - successData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.IS_LOADING_REPORT_DATA, - value: false, - }, - ], - failureData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.IS_LOADING_REPORT_DATA, - value: false, - }, - ], - }); + apiMethod( + fetchIncrementalUpdates ? 'ReconnectApp' : 'OpenApp', + params, + { + optimisticData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.IS_LOADING_REPORT_DATA, + value: true, + }, + ], + successData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.IS_LOADING_REPORT_DATA, + value: false, + }, + ], + failureData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.IS_LOADING_REPORT_DATA, + value: false, + }, + ], + }, + + // For write requests, when this is true, the request is prioritized and put into the front of the sequential queue instead of the back. + fetchIncrementalUpdates, + ); }, }); }); diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index d40412246d8c..0102ec2de80f 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -18,6 +18,7 @@ import * as ReportActionsUtils from '../ReportActionsUtils'; import * as ErrorUtils from '../ErrorUtils'; import * as Session from './Session'; import * as PersonalDetails from './PersonalDetails'; +import * as App from './App'; let currentUserAccountID = ''; let currentEmail = ''; @@ -41,6 +42,12 @@ Onyx.connect({ }, }); +let onyxUpdatesLastUpdateID; +Onyx.connect({ + key: ONYXKEYS.ONYX_UPDATES.LAST_UPDATE_ID, + callback: (val) => (onyxUpdatesLastUpdateID = val), +}); + /** * Attempt to close the user's account * @@ -545,6 +552,10 @@ function subscribeToUserEvents() { [ONYXKEYS.ONYX_UPDATES.PREVIOUS_UPDATE_ID]: pushJSON.previousUpdateID, }); updates = pushJSON.updates; + + if (pushJSON.lastUpdateID !== onyxUpdatesLastUpdateID) { + App.openApp(true); + } } _.each(updates, (multipleEvent) => { PusherUtils.triggerMultiEventHandler(multipleEvent.eventType, multipleEvent.data); From 1abb3ff3952362c812b7903c30aeaa9281113b3c Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Mon, 7 Aug 2023 10:41:25 -0600 Subject: [PATCH 05/25] Cast values to ints --- src/libs/actions/User.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index 67400fa26110..1be66a01a365 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -565,16 +565,19 @@ function subscribeToUserEvents() { // until we finish the migration to reliable updates. So let's check it before actually updating // the properties in Onyx if (pushJSON.lastUpdateID && pushJSON.previousUpdateID) { - console.debug('[OnyxUpdates] Received lastUpdateID from pusher', pushJSON.lastUpdateID); - console.debug('[OnyxUpdates] Received previousUpdateID from pusher', pushJSON.previousUpdateID); + const pushJSONLastUpdateID = Number(pushJSON.lastUpdateID || 0); + const pushJSONPreviousUpdateID = Number(pushJSON.previousUpdateID || 0); + + console.debug('[OnyxUpdates] Received lastUpdateID from pusher', pushJSONLastUpdateID); + console.debug('[OnyxUpdates] Received previousUpdateID from pusher', pushJSONPreviousUpdateID); // Store these values in Onyx to allow App.reconnectApp() to fetch incremental updates from the server when a previous session is being reconnected to. Onyx.multiSet({ - [ONYXKEYS.ONYX_UPDATES.LAST_UPDATE_ID]: Number(pushJSON.lastUpdateID || 0), - [ONYXKEYS.ONYX_UPDATES.PREVIOUS_UPDATE_ID]: Number(pushJSON.previousUpdateID || 0), + [ONYXKEYS.ONYX_UPDATES.LAST_UPDATE_ID]: pushJSONLastUpdateID, + [ONYXKEYS.ONYX_UPDATES.PREVIOUS_UPDATE_ID]: pushJSONPreviousUpdateID, }); - if (pushJSON.lastUpdateID !== onyxUpdatesLastUpdateID) { - App.reconnectApp(onyxUpdatesLastUpdateID, pushJSON.lastUpdateID); + if (pushJSONLastUpdateID !== onyxUpdatesLastUpdateID) { + App.reconnectApp(onyxUpdatesLastUpdateID, pushJSONLastUpdateID); } } else { console.debug('[OnyxUpdates] No lastUpdateID and previousUpdateID provided'); From 276ad1eb2d42f33207a568095961caaabe0e6f65 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Mon, 7 Aug 2023 10:57:14 -0600 Subject: [PATCH 06/25] Explain the check for incremental updates --- src/libs/actions/User.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index 1be66a01a365..3c0ec6d10c63 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -576,7 +576,9 @@ function subscribeToUserEvents() { [ONYXKEYS.ONYX_UPDATES.PREVIOUS_UPDATE_ID]: pushJSONPreviousUpdateID, }); - if (pushJSONLastUpdateID !== onyxUpdatesLastUpdateID) { + // The previous update from the server does not match the last update the client got which means the client is missing some updates. + // ReconnectApp will fetch updates starting from the last update this client got and going to the last update the server sent. + if (pushJSONPreviousUpdateID !== onyxUpdatesLastUpdateID) { App.reconnectApp(onyxUpdatesLastUpdateID, pushJSONLastUpdateID); } } else { From 38a52618b6008b1ebf48787b7cb2ab275a9ea141 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Mon, 7 Aug 2023 11:00:46 -0600 Subject: [PATCH 07/25] Reduce the values stored in Onyx --- src/ONYXKEYS.js | 8 +------- src/libs/actions/User.js | 10 +++++----- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index a02f9a2c356f..352604c38b41 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -243,13 +243,7 @@ export default { // Experimental memory only Onyx mode flag IS_USING_MEMORY_ONLY_KEYS: 'isUsingMemoryOnlyKeys', - ONYX_UPDATES: { - // The ID of the last Onyx update that was applied to this client - LAST_UPDATE_ID: 'onyxUpdatesLastUpdateID', - - // The ID of the previous Onyx update that was applied to this client - PREVIOUS_UPDATE_ID: 'onyxUpdatesPreviousUpdateID', - }, + ONYX_UPDATES_LAST_UPDATE_ID: 'onyxUpdatesLastUpdateID', // Manual request tab selector SELECTED_TAB: 'selectedTab', diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index 3c0ec6d10c63..72cf74145789 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -570,15 +570,15 @@ function subscribeToUserEvents() { console.debug('[OnyxUpdates] Received lastUpdateID from pusher', pushJSONLastUpdateID); console.debug('[OnyxUpdates] Received previousUpdateID from pusher', pushJSONPreviousUpdateID); - // Store these values in Onyx to allow App.reconnectApp() to fetch incremental updates from the server when a previous session is being reconnected to. - Onyx.multiSet({ - [ONYXKEYS.ONYX_UPDATES.LAST_UPDATE_ID]: pushJSONLastUpdateID, - [ONYXKEYS.ONYX_UPDATES.PREVIOUS_UPDATE_ID]: pushJSONPreviousUpdateID, - }); + console.debug('[OnyxUpdates] The lastUpdateID the client received was', onyxUpdatesLastUpdateID); + + // Store this value in Onyx to allow AuthScreens to fetch incremental updates from the server when a previous session is being reconnected to. + Onyx.set(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID, pushJSONLastUpdateID); // The previous update from the server does not match the last update the client got which means the client is missing some updates. // ReconnectApp will fetch updates starting from the last update this client got and going to the last update the server sent. if (pushJSONPreviousUpdateID !== onyxUpdatesLastUpdateID) { + console.debug('[OnyxUpdates] Gap detected in update IDs so fetching incremental updates'); App.reconnectApp(onyxUpdatesLastUpdateID, pushJSONLastUpdateID); } } else { From 4b25d33a36f73230128d5a5dfbb79c1c55095921 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Mon, 7 Aug 2023 14:29:16 -0600 Subject: [PATCH 08/25] Fix key name --- src/libs/Navigation/AppNavigator/AuthScreens.js | 2 +- src/libs/actions/User.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js index ddd61da272e6..db3a9af1c068 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.js +++ b/src/libs/Navigation/AppNavigator/AuthScreens.js @@ -330,7 +330,7 @@ export default compose( key: ONYXKEYS.IS_USING_MEMORY_ONLY_KEYS, }, onyxUpdatesLastUpdateID: { - key: ONYXKEYS.ONYX_UPDATES.LAST_UPDATE_ID, + key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID, }, }), )(AuthScreens); diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index 72cf74145789..1aea72a71c09 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -44,7 +44,7 @@ Onyx.connect({ let onyxUpdatesLastUpdateID; Onyx.connect({ - key: ONYXKEYS.ONYX_UPDATES.LAST_UPDATE_ID, + key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID, callback: (val) => (onyxUpdatesLastUpdateID = val), }); From 0d1f2a7125ce64dbe3ba3e87a4144e5a06f8e3f6 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Mon, 7 Aug 2023 14:29:34 -0600 Subject: [PATCH 09/25] Fix undefined array errors --- src/libs/actions/PersistedRequests.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/PersistedRequests.js b/src/libs/actions/PersistedRequests.js index 45783bfd866c..a71d034c83e1 100644 --- a/src/libs/actions/PersistedRequests.js +++ b/src/libs/actions/PersistedRequests.js @@ -18,7 +18,11 @@ function clear() { * @param {Boolean} [front] whether or not the request should go in the front of the queue */ function save(requestsToPersist, front = false) { - persistedRequests = front ? persistedRequests.unshift(...requestsToPersist) : persistedRequests.concat(requestsToPersist); + if (persistedRequests.length) { + persistedRequests = front ? persistedRequests.unshift(...requestsToPersist) : persistedRequests.concat(requestsToPersist); + } else { + persistedRequests = requestsToPersist; + } Onyx.set(ONYXKEYS.PERSISTED_REQUESTS, persistedRequests); } From 0708d4389b0496a8b25fefb4f303648a8cad8841 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Mon, 7 Aug 2023 14:29:49 -0600 Subject: [PATCH 10/25] Compare IDs --- src/libs/actions/App.js | 5 +++-- src/libs/actions/User.js | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index 356a37970926..e506d5c0356b 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -183,8 +183,9 @@ function openApp() { * Fetches data when the app reconnects to the network * @param {Number} [updateIDFrom] the ID of the Onyx update that we want to start fetching from * @param {Number} [updateIDTo] the ID of the Onyx update that we want to fetch up to + * @param {Boolean} [prioritizeRequest] whether or not the request should be put at the front of the sequential queue before other requests */ -function reconnectApp(updateIDFrom = 0, updateIDTo = 0) { +function reconnectApp(updateIDFrom = 0, updateIDTo = 0, prioritizeRequest = false) { console.debug(`[OnyxUpdates] App reconnecting with updateIDFrom: ${updateIDFrom} and updateIDTo: ${updateIDTo}`); getPolicyParamsForOpenOrReconnect().then((policyParams) => { const params = {...policyParams}; @@ -208,7 +209,7 @@ function reconnectApp(updateIDFrom = 0, updateIDTo = 0) { params.updateIDTo = updateIDTo; } - API.write('ReconnectApp', params, getOnyxDataForOpenOrReconnect()); + API.write('ReconnectApp', params, getOnyxDataForOpenOrReconnect(), prioritizeRequest); }); } diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index 1aea72a71c09..b1334908c745 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -577,12 +577,12 @@ function subscribeToUserEvents() { // The previous update from the server does not match the last update the client got which means the client is missing some updates. // ReconnectApp will fetch updates starting from the last update this client got and going to the last update the server sent. - if (pushJSONPreviousUpdateID !== onyxUpdatesLastUpdateID) { + if (onyxUpdatesLastUpdateID < pushJSONPreviousUpdateID) { console.debug('[OnyxUpdates] Gap detected in update IDs so fetching incremental updates'); - App.reconnectApp(onyxUpdatesLastUpdateID, pushJSONLastUpdateID); + App.reconnectApp(onyxUpdatesLastUpdateID, pushJSONLastUpdateID, true); } } else { - console.debug('[OnyxUpdates] No lastUpdateID and previousUpdateID provided'); + console.debug('[OnyxUpdates] No lastUpdateID and previousUpdateID provided from Pusher'); } } _.each(updates, (multipleEvent) => { From b9c2781bde25b321de0bd2f9942b5bfc2a5c8168 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Mon, 7 Aug 2023 14:38:17 -0600 Subject: [PATCH 11/25] Add a server log when a gap is detected --- src/libs/actions/User.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index b1334908c745..0e12944ba3bf 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -19,6 +19,7 @@ import * as ErrorUtils from '../ErrorUtils'; import * as Session from './Session'; import * as PersonalDetails from './PersonalDetails'; import * as App from './App'; +import Log from '../Log'; let currentUserAccountID = ''; let currentEmail = ''; @@ -579,6 +580,11 @@ function subscribeToUserEvents() { // ReconnectApp will fetch updates starting from the last update this client got and going to the last update the server sent. if (onyxUpdatesLastUpdateID < pushJSONPreviousUpdateID) { console.debug('[OnyxUpdates] Gap detected in update IDs so fetching incremental updates'); + Log.info('Gap detected in update IDs from Pusher so fetching incremental updates', true, { + lastUpdateIDFromPusher: pushJSONLastUpdateID, + previousUpdateIDFromPusher: pushJSONPreviousUpdateID, + lastUpdateIDOnClient: onyxUpdatesLastUpdateID, + }); App.reconnectApp(onyxUpdatesLastUpdateID, pushJSONLastUpdateID, true); } } else { From 9cc2132fe2d2dcadcfb3139a37d00b4a8b4a5241 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Tue, 8 Aug 2023 09:39:03 -0600 Subject: [PATCH 12/25] Add new API method for fetching missed onyx updates --- src/libs/actions/App.js | 33 ++++++++++++++++++++++++--------- src/libs/actions/User.js | 2 +- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index 88751c35cf5d..20753bda6499 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -182,11 +182,9 @@ function openApp() { /** * Fetches data when the app reconnects to the network * @param {Number} [updateIDFrom] the ID of the Onyx update that we want to start fetching from - * @param {Number} [updateIDTo] the ID of the Onyx update that we want to fetch up to - * @param {Boolean} [prioritizeRequest] whether or not the request should be put at the front of the sequential queue before other requests */ -function reconnectApp(updateIDFrom = 0, updateIDTo = 0, prioritizeRequest = false) { - console.debug(`[OnyxUpdates] App reconnecting with updateIDFrom: ${updateIDFrom} and updateIDTo: ${updateIDTo}`); +function reconnectApp(updateIDFrom = 0) { + console.debug(`[OnyxUpdates] App reconnecting with updateIDFrom: ${updateIDFrom}`); getPolicyParamsForOpenOrReconnect().then((policyParams) => { const params = {...policyParams}; @@ -205,13 +203,29 @@ function reconnectApp(updateIDFrom = 0, updateIDTo = 0, prioritizeRequest = fals params.updateIDFrom = updateIDFrom; } - if (updateIDTo) { - params.updateIDTo = updateIDTo; - } - - API.write('ReconnectApp', params, getOnyxDataForOpenOrReconnect(), prioritizeRequest); + API.write('ReconnectApp', params, getOnyxDataForOpenOrReconnect()); }); } +/** + * Fetches data when the client has discovered it missed some Onyx updates from the server + * @param {Number} [updateIDFrom] the ID of the Onyx update that we want to start fetching from + * @param {Number} [updateIDTo] the ID of the Onyx update that we want to fetch up to + */ +function getMissingOnyxUpdates(updateIDFrom = 0, updateIDTo = 0) { + console.debug(`[OnyxUpdates] Fetching missing updates updateIDFrom: ${updateIDFrom} and updateIDTo: ${updateIDTo}`); + + API.write( + 'GetMissingOnyxMessages', + { + updateIDFrom, + updateIDTo, + }, + getOnyxDataForOpenOrReconnect(), + + // Set this to true so that the request will be prioritized at the front of the sequential queue + true, + ); +} /** * This promise is used so that deeplink component know when a transition is end. @@ -388,6 +402,7 @@ export { setUpPoliciesAndNavigate, openProfile, openApp, + getMissingOnyxUpdates, reconnectApp, confirmReadyToOpenApp, beginDeepLinkRedirect, diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index 0e12944ba3bf..e4775ee6ee93 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -585,7 +585,7 @@ function subscribeToUserEvents() { previousUpdateIDFromPusher: pushJSONPreviousUpdateID, lastUpdateIDOnClient: onyxUpdatesLastUpdateID, }); - App.reconnectApp(onyxUpdatesLastUpdateID, pushJSONLastUpdateID, true); + App.getMissingOnyxUpdates(onyxUpdatesLastUpdateID, pushJSONLastUpdateID); } } else { console.debug('[OnyxUpdates] No lastUpdateID and previousUpdateID provided from Pusher'); From 338618dd89d9ca4841ef88257766d896491cb619 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Tue, 8 Aug 2023 09:48:54 -0600 Subject: [PATCH 13/25] Move gap detection to a separate file --- src/libs/actions/OnyxUpdates.js | 42 +++++++++++++++++++++++++++++++++ src/libs/actions/User.js | 39 ++---------------------------- 2 files changed, 44 insertions(+), 37 deletions(-) create mode 100644 src/libs/actions/OnyxUpdates.js diff --git a/src/libs/actions/OnyxUpdates.js b/src/libs/actions/OnyxUpdates.js new file mode 100644 index 000000000000..59a18c4eb181 --- /dev/null +++ b/src/libs/actions/OnyxUpdates.js @@ -0,0 +1,42 @@ +import Onyx from 'react-native-onyx'; +import ONYXKEYS from '../../ONYXKEYS'; +import * as App from './App'; +import Log from '../Log'; + +let onyxUpdatesLastUpdateID; +Onyx.connect({ + key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID, + callback: (val) => (onyxUpdatesLastUpdateID = val), +}); + +/** + * + * @param {Number} [lastUpdateID] + * @param {Number} [previousUpdateID] + */ +function detectAndGetMissingUpdates(lastUpdateID = 0, previousUpdateID = 0) { + // Return early if there were no updateIDs + if (!lastUpdateID || !previousUpdateID) { + return; + } + + console.debug('[OnyxUpdates] Received lastUpdateID from pusher', lastUpdateID); + console.debug('[OnyxUpdates] Received previousUpdateID from pusher', previousUpdateID); + console.debug('[OnyxUpdates] The lastUpdateID the client knows about is', onyxUpdatesLastUpdateID); + + // Store this value in Onyx to allow AuthScreens to fetch incremental updates from the server when a previous session is being reconnected to. + Onyx.set(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID, pushJSONLastUpdateID); + + // The previous update from the server does not match the last update the client got which means the client is missing some updates. + // ReconnectApp will fetch updates starting from the last update this client got and going to the last update the server sent. + if (onyxUpdatesLastUpdateID < previousUpdateID) { + console.debug('[OnyxUpdates] Gap detected in update IDs so fetching incremental updates'); + Log.info('Gap detected in update IDs from Pusher so fetching incremental updates', true, { + lastUpdateIDFromPusher: lastUpdateID, + previousUpdateIDFromPusher: previousUpdateID, + lastUpdateIDOnClient: onyxUpdatesLastUpdateID, + }); + App.getMissingOnyxUpdates(onyxUpdatesLastUpdateID, lastUpdateID); + } +} +export {detectAndGetMissingUpdates}; diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index e4775ee6ee93..680358c73252 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -18,8 +18,7 @@ import * as ReportActionsUtils from '../ReportActionsUtils'; import * as ErrorUtils from '../ErrorUtils'; import * as Session from './Session'; import * as PersonalDetails from './PersonalDetails'; -import * as App from './App'; -import Log from '../Log'; +import * as OnyxUpdates from './OnyxUpdates'; let currentUserAccountID = ''; let currentEmail = ''; @@ -43,12 +42,6 @@ Onyx.connect({ }, }); -let onyxUpdatesLastUpdateID; -Onyx.connect({ - key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID, - callback: (val) => (onyxUpdatesLastUpdateID = val), -}); - /** * Attempt to close the user's account * @@ -561,35 +554,7 @@ function subscribeToUserEvents() { updates = pushJSON; } else { updates = pushJSON.updates; - - // Not always we'll have the lastUpdateID and previousUpdateID properties in the pusher update - // until we finish the migration to reliable updates. So let's check it before actually updating - // the properties in Onyx - if (pushJSON.lastUpdateID && pushJSON.previousUpdateID) { - const pushJSONLastUpdateID = Number(pushJSON.lastUpdateID || 0); - const pushJSONPreviousUpdateID = Number(pushJSON.previousUpdateID || 0); - - console.debug('[OnyxUpdates] Received lastUpdateID from pusher', pushJSONLastUpdateID); - console.debug('[OnyxUpdates] Received previousUpdateID from pusher', pushJSONPreviousUpdateID); - console.debug('[OnyxUpdates] The lastUpdateID the client received was', onyxUpdatesLastUpdateID); - - // Store this value in Onyx to allow AuthScreens to fetch incremental updates from the server when a previous session is being reconnected to. - Onyx.set(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID, pushJSONLastUpdateID); - - // The previous update from the server does not match the last update the client got which means the client is missing some updates. - // ReconnectApp will fetch updates starting from the last update this client got and going to the last update the server sent. - if (onyxUpdatesLastUpdateID < pushJSONPreviousUpdateID) { - console.debug('[OnyxUpdates] Gap detected in update IDs so fetching incremental updates'); - Log.info('Gap detected in update IDs from Pusher so fetching incremental updates', true, { - lastUpdateIDFromPusher: pushJSONLastUpdateID, - previousUpdateIDFromPusher: pushJSONPreviousUpdateID, - lastUpdateIDOnClient: onyxUpdatesLastUpdateID, - }); - App.getMissingOnyxUpdates(onyxUpdatesLastUpdateID, pushJSONLastUpdateID); - } - } else { - console.debug('[OnyxUpdates] No lastUpdateID and previousUpdateID provided from Pusher'); - } + OnyxUpdates.detectAndGetMissingUpdates(Number(pushJSON.lastUpdateID || 0), Number(pushJSON.previousUpdateID || 0)); } _.each(updates, (multipleEvent) => { PusherUtils.triggerMultiEventHandler(multipleEvent.eventType, multipleEvent.data); From fb3ba07bc52c2d6ec156c2e3033f8c628ac1a58c Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Tue, 8 Aug 2023 09:53:18 -0600 Subject: [PATCH 14/25] Start moving logic to a separate method --- src/libs/Middleware/SaveResponseInOnyx.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libs/Middleware/SaveResponseInOnyx.js b/src/libs/Middleware/SaveResponseInOnyx.js index faecda08df7a..8a1b6457c77f 100644 --- a/src/libs/Middleware/SaveResponseInOnyx.js +++ b/src/libs/Middleware/SaveResponseInOnyx.js @@ -2,6 +2,10 @@ import Onyx from 'react-native-onyx'; import CONST from '../../CONST'; import * as QueuedOnyxUpdates from '../actions/QueuedOnyxUpdates'; +function updateOnyx(updates) { + Onyx.update(updates); +} + /** * @param {Promise} response * @param {Object} request @@ -16,7 +20,7 @@ function SaveResponseInOnyx(response, request) { // For most requests we can immediately update Onyx. For write requests we queue the updates and apply them after the sequential queue has flushed to prevent a replay effect in // the UI. See https://github.com/Expensify/App/issues/12775 for more info. - const updateHandler = request.data.apiRequestType === CONST.API_REQUEST_TYPE.WRITE ? QueuedOnyxUpdates.queueOnyxUpdates : Onyx.update; + const updateHandler = request.data.apiRequestType === CONST.API_REQUEST_TYPE.WRITE ? QueuedOnyxUpdates.queueOnyxUpdates : updateOnyx; // First apply any onyx data updates that are being sent back from the API. We wait for this to complete and then // apply successData or failureData. This ensures that we do not update any pending, loading, or other UI states contained From b85320179d123da4884f8e58e6e5574600fa043b Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Tue, 8 Aug 2023 09:58:20 -0600 Subject: [PATCH 15/25] Add logic for detecting missing updates --- src/libs/Middleware/SaveResponseInOnyx.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/libs/Middleware/SaveResponseInOnyx.js b/src/libs/Middleware/SaveResponseInOnyx.js index 8a1b6457c77f..8bcb402b265e 100644 --- a/src/libs/Middleware/SaveResponseInOnyx.js +++ b/src/libs/Middleware/SaveResponseInOnyx.js @@ -1,9 +1,22 @@ import Onyx from 'react-native-onyx'; import CONST from '../../CONST'; import * as QueuedOnyxUpdates from '../actions/QueuedOnyxUpdates'; +import * as OnyxUpdates from '../actions/OnyxUpdates'; +/** + * + * @param {Object} updates + * @param {Object[]} updates.onyxData an array of Onyx update instruction objects + * @param {Number} updates.previousUpdateID + * @param {Number} updates.lastUpdateID + */ function updateOnyx(updates) { - Onyx.update(updates); + if (!updates.onyxData) { + Onyx.update(updates); + } else { + Onyx.update(updates.onyxData); + OnyxUpdates.detectAndGetMissingUpdates(Number(updates.lastUpdateID || 0), Number(updates.previousUpdateID || 0)); + } } /** From 2bd30e81e0e7583066e9ce138078dfd8253cfd5f Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Tue, 8 Aug 2023 13:56:03 -0600 Subject: [PATCH 16/25] Fix error and return a promise --- src/libs/Middleware/SaveResponseInOnyx.js | 10 +++++----- src/libs/Pusher/pusher.js | 5 +++-- src/libs/actions/OnyxUpdates.js | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libs/Middleware/SaveResponseInOnyx.js b/src/libs/Middleware/SaveResponseInOnyx.js index 8bcb402b265e..08aaa4b9aeb2 100644 --- a/src/libs/Middleware/SaveResponseInOnyx.js +++ b/src/libs/Middleware/SaveResponseInOnyx.js @@ -4,19 +4,19 @@ import * as QueuedOnyxUpdates from '../actions/QueuedOnyxUpdates'; import * as OnyxUpdates from '../actions/OnyxUpdates'; /** - * * @param {Object} updates * @param {Object[]} updates.onyxData an array of Onyx update instruction objects * @param {Number} updates.previousUpdateID * @param {Number} updates.lastUpdateID + * @returns {Promise} */ function updateOnyx(updates) { if (!updates.onyxData) { - Onyx.update(updates); - } else { - Onyx.update(updates.onyxData); - OnyxUpdates.detectAndGetMissingUpdates(Number(updates.lastUpdateID || 0), Number(updates.previousUpdateID || 0)); + return Onyx.update(updates); } + + OnyxUpdates.detectAndGetMissingUpdates(Number(updates.lastUpdateID || 0), Number(updates.previousUpdateID || 0)); + return Onyx.update(updates.onyxData); } /** diff --git a/src/libs/Pusher/pusher.js b/src/libs/Pusher/pusher.js index 60587a68e173..267153e9494b 100644 --- a/src/libs/Pusher/pusher.js +++ b/src/libs/Pusher/pusher.js @@ -136,7 +136,7 @@ function bindEventToChannel(channel, eventName, eventCallback = () => {}) { try { data = _.isObject(eventData) ? eventData : JSON.parse(eventData); } catch (err) { - Log.alert('[Pusher] Unable to parse JSON response from Pusher', {error: err, eventData}); + Log.alert('[Pusher] Unable to parse JSON response from Pusher 1', {error: err, eventData}); return; } if (data.id === undefined || data.chunk === undefined || data.final === undefined) { @@ -168,10 +168,11 @@ function bindEventToChannel(channel, eventName, eventCallback = () => {}) { try { eventCallback(JSON.parse(chunkedEvent.chunks.join(''))); } catch (err) { - Log.alert('[Pusher] Unable to parse chunked JSON response from Pusher', { + Log.alert('[Pusher] Unable to parse chunked JSON response from Pusher 2', { error: err, eventData: chunkedEvent.chunks.join(''), }); + console.error(err); } delete chunkedDataEvents[data.id]; diff --git a/src/libs/actions/OnyxUpdates.js b/src/libs/actions/OnyxUpdates.js index 59a18c4eb181..d74789c32a68 100644 --- a/src/libs/actions/OnyxUpdates.js +++ b/src/libs/actions/OnyxUpdates.js @@ -25,7 +25,7 @@ function detectAndGetMissingUpdates(lastUpdateID = 0, previousUpdateID = 0) { console.debug('[OnyxUpdates] The lastUpdateID the client knows about is', onyxUpdatesLastUpdateID); // Store this value in Onyx to allow AuthScreens to fetch incremental updates from the server when a previous session is being reconnected to. - Onyx.set(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID, pushJSONLastUpdateID); + Onyx.set(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID, lastUpdateID); // The previous update from the server does not match the last update the client got which means the client is missing some updates. // ReconnectApp will fetch updates starting from the last update this client got and going to the last update the server sent. From 35bb4822ca83cd1889c70a93c23a751c45bf98c5 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Tue, 8 Aug 2023 14:51:36 -0600 Subject: [PATCH 17/25] Remove circular dependency --- src/libs/actions/App.js | 21 --------------------- src/libs/actions/OnyxUpdates.js | 29 ++++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index 20753bda6499..bb8d46deb635 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -206,26 +206,6 @@ function reconnectApp(updateIDFrom = 0) { API.write('ReconnectApp', params, getOnyxDataForOpenOrReconnect()); }); } -/** - * Fetches data when the client has discovered it missed some Onyx updates from the server - * @param {Number} [updateIDFrom] the ID of the Onyx update that we want to start fetching from - * @param {Number} [updateIDTo] the ID of the Onyx update that we want to fetch up to - */ -function getMissingOnyxUpdates(updateIDFrom = 0, updateIDTo = 0) { - console.debug(`[OnyxUpdates] Fetching missing updates updateIDFrom: ${updateIDFrom} and updateIDTo: ${updateIDTo}`); - - API.write( - 'GetMissingOnyxMessages', - { - updateIDFrom, - updateIDTo, - }, - getOnyxDataForOpenOrReconnect(), - - // Set this to true so that the request will be prioritized at the front of the sequential queue - true, - ); -} /** * This promise is used so that deeplink component know when a transition is end. @@ -402,7 +382,6 @@ export { setUpPoliciesAndNavigate, openProfile, openApp, - getMissingOnyxUpdates, reconnectApp, confirmReadyToOpenApp, beginDeepLinkRedirect, diff --git a/src/libs/actions/OnyxUpdates.js b/src/libs/actions/OnyxUpdates.js index d74789c32a68..1cdfebe509a8 100644 --- a/src/libs/actions/OnyxUpdates.js +++ b/src/libs/actions/OnyxUpdates.js @@ -1,6 +1,6 @@ import Onyx from 'react-native-onyx'; import ONYXKEYS from '../../ONYXKEYS'; -import * as App from './App'; +import * as API from '../API'; import Log from '../Log'; let onyxUpdatesLastUpdateID; @@ -9,6 +9,27 @@ Onyx.connect({ callback: (val) => (onyxUpdatesLastUpdateID = val), }); +/** + * Fetches data when the client has discovered it missed some Onyx updates from the server + * @param {Number} [updateIDFrom] the ID of the Onyx update that we want to start fetching from + * @param {Number} [updateIDTo] the ID of the Onyx update that we want to fetch up to + */ +function getMissingOnyxUpdates(updateIDFrom = 0, updateIDTo = 0) { + console.debug(`[OnyxUpdates] Fetching missing updates updateIDFrom: ${updateIDFrom} and updateIDTo: ${updateIDTo}`); + + API.write( + 'GetMissingOnyxMessages', + { + updateIDFrom, + updateIDTo, + }, + getOnyxDataForOpenOrReconnect(), + + // Set this to true so that the request will be prioritized at the front of the sequential queue + true, + ); +} + /** * * @param {Number} [lastUpdateID] @@ -16,7 +37,7 @@ Onyx.connect({ */ function detectAndGetMissingUpdates(lastUpdateID = 0, previousUpdateID = 0) { // Return early if there were no updateIDs - if (!lastUpdateID || !previousUpdateID) { + if (!lastUpdateID) { return; } @@ -36,7 +57,9 @@ function detectAndGetMissingUpdates(lastUpdateID = 0, previousUpdateID = 0) { previousUpdateIDFromPusher: previousUpdateID, lastUpdateIDOnClient: onyxUpdatesLastUpdateID, }); - App.getMissingOnyxUpdates(onyxUpdatesLastUpdateID, lastUpdateID); + getMissingOnyxUpdates(onyxUpdatesLastUpdateID, lastUpdateID); } } + +// eslint-disable-next-line import/prefer-default-export export {detectAndGetMissingUpdates}; From 09c73273eb71f5f1ab4c2d2829953ccc57cea812 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 9 Aug 2023 15:23:45 -0600 Subject: [PATCH 18/25] Remove circular dependencies --- src/ONYXKEYS.js | 7 ++- .../Navigation/AppNavigator/AuthScreens.js | 21 ++++--- src/libs/actions/App.js | 63 +++++++++++++++++++ src/libs/actions/OnyxUpdates.js | 51 ++------------- 4 files changed, 85 insertions(+), 57 deletions(-) diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index 3b5a2863189a..5cc95ded4765 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -243,8 +243,11 @@ export default { // Experimental memory only Onyx mode flag IS_USING_MEMORY_ONLY_KEYS: 'isUsingMemoryOnlyKeys', - // The ID of the last Onyx update that was applied to this client - ONYX_UPDATES_LAST_UPDATE_ID: 'onyxUpdatesLastUpdateID', + // Information about the onyx updates IDs that were received from the server + ONYX_UPDATES: 'onyxUpdates', + + // The last update ID that was applied to the client + ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT: 'OnyxUpdatesLastUpdateIDAppliedToClient', // The access token to be used with the Mapbox library MAPBOX_ACCESS_TOKEN: 'mapboxAccessToken', diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js index db3a9af1c068..96467518fb8a 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.js +++ b/src/libs/Navigation/AppNavigator/AuthScreens.js @@ -96,8 +96,11 @@ const propTypes = { /** Opt-in experimental mode that prevents certain Onyx keys from persisting to disk */ isUsingMemoryOnlyKeys: PropTypes.bool, - /** The last Onyx update ID that is stored in Onyx (used for getting incremental updates when reconnecting) */ - onyxUpdatesLastUpdateID: PropTypes.number, + /** Information about the onyx update IDs */ + lastUpdateIDAppliedToClient: PropTypes.shape({ + /** The last Onyx update ID was applied to the client */ + lastUpdateIDAppliedToClient: PropTypes.number, + }), ...windowDimensionsPropTypes, }; @@ -108,7 +111,9 @@ const defaultProps = { email: null, }, lastOpenedPublicRoomID: null, - onyxUpdatesLastUpdateID: 0, + lastUpdateIDAppliedToClient: { + lastUpdateIDAppliedToClient: null, + }, }; class AuthScreens extends React.Component { @@ -120,7 +125,7 @@ class AuthScreens extends React.Component { componentDidMount() { NetworkConnection.listenForReconnect(); - NetworkConnection.onReconnect(() => App.reconnectApp(this.props.onyxUpdatesLastUpdateID)); + NetworkConnection.onReconnect(() => App.reconnectApp(this.props.lastUpdateIDAppliedToClient.lastUpdateIDAppliedToClient)); PusherConnectionManager.init(); Pusher.init({ appKey: CONFIG.PUSHER.APP_KEY, @@ -132,7 +137,7 @@ class AuthScreens extends React.Component { // If we are on this screen then we are "logged in", but the user might not have "just logged in". They could be reopening the app // or returning from background. If so, we'll assume they have some app data already and we can call - // reconnectApp(onyxUpdatesLastUpdateID) instead of openApp(). + // reconnectApp(lastUpdateIDAppliedToClientLastUpdateIDAppliedToClient) instead of openApp(). // Note: If a Guide has enabled the memory only key mode then we do want to run OpenApp as their app will not be rehydrated with // the correct state on refresh. They are explicitly opting out of storing data they would need (i.e. reports_) to take advantage of // the optimizations performed during ReconnectApp. @@ -140,7 +145,7 @@ class AuthScreens extends React.Component { if (shouldGetAllData) { App.openApp(); } else { - App.reconnectApp(this.props.onyxUpdatesLastUpdateID); + App.reconnectApp(this.props.lastUpdateIDAppliedToClient.lastUpdateIDAppliedToClient); } App.setUpPoliciesAndNavigate(this.props.session, !this.props.isSmallScreenWidth); @@ -329,8 +334,8 @@ export default compose( isUsingMemoryOnlyKeys: { key: ONYXKEYS.IS_USING_MEMORY_ONLY_KEYS, }, - onyxUpdatesLastUpdateID: { - key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID, + lastUpdateIDAppliedToClient: { + key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, }, }), )(AuthScreens); diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index bb8d46deb635..b90ce2f8c815 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -18,6 +18,7 @@ import * as Session from './Session'; import * as ReportActionsUtils from '../ReportActionsUtils'; import Timing from './Timing'; import * as Browser from '../Browser'; +import {last} from 'lodash'; let currentUserAccountID; let currentUserEmail; @@ -207,6 +208,68 @@ function reconnectApp(updateIDFrom = 0) { }); } +/** + * Fetches data when the client has discovered it missed some Onyx updates from the server + * @param {Number} [updateIDFrom] the ID of the Onyx update that we want to start fetching from + * @param {Number} [updateIDTo] the ID of the Onyx update that we want to fetch up to + */ +function getMissingOnyxUpdates(updateIDFrom = 0, updateIDTo = 0) { + console.debug(`[OnyxUpdates] Fetching missing updates updateIDFrom: ${updateIDFrom} and updateIDTo: ${updateIDTo}`); + + API.write( + 'GetMissingOnyxMessages', + { + updateIDFrom, + updateIDTo, + }, + getOnyxDataForOpenOrReconnect(), + + // Set this to true so that the request will be prioritized at the front of the sequential queue + true, + ); +} + +let lastUpdateIDAppliedToClient = 0; +Onyx.connect({ + key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, + callback: (val) => (lastUpdateIDAppliedToClient = val), +}); +const onyxUpdates = { + lastUpdateIDFromServer: 0, + previousUpdateIDFromServer: 0, +}; +Onyx.connect({ + key: ONYXKEYS.ONYX_UPDATES, + callback: (val) => { + if (!val) { + return; + } + + const {lastUpdateIDFromServer, previousUpdateIDFromServer} = val; + console.debug('[OnyxUpdates] Received lastUpdateID from server', lastUpdateIDFromServer); + console.debug('[OnyxUpdates] Received previousUpdateID from server', previousUpdateIDFromServer); + console.debug('[OnyxUpdates] Last update ID applied to the client', lastUpdateIDAppliedToClient); + + // If the previous update from the server does not match the last update the client got, then the client is missing some updates. + // getMissingOnyxUpdates will fetch updates starting from the last update this client got and going to the last update the server sent. + if (lastUpdateIDAppliedToClient && previousUpdateIDFromServer && lastUpdateIDAppliedToClient < previousUpdateIDFromServer) { + console.debug('[OnyxUpdates] Gap detected in update IDs so fetching incremental updates'); + Log.info('Gap detected in update IDs from Pusher so fetching incremental updates', true, { + lastUpdateIDFromServer, + previousUpdateIDFromServer, + lastUpdateIDAppliedToClient: onyxUpdates.lastUpdateIDAppliedToClient, + }); + getMissingOnyxUpdates(onyxUpdates.lastUpdateIDAppliedToClient, lastUpdateIDFromServer); + } + + // Update the local values to be the same as the values stored in Onyx + onyxUpdates.lastUpdateIDFromServer = lastUpdateIDFromServer || 0; + onyxUpdates.previousUpdateIDFromServer = previousUpdateIDFromServer || 0; + + Onyx.merge(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, lastUpdateIDFromServer || 0); + }, +}); + /** * This promise is used so that deeplink component know when a transition is end. * This is necessary because we want to begin deeplink redirection after the transition is end. diff --git a/src/libs/actions/OnyxUpdates.js b/src/libs/actions/OnyxUpdates.js index 1cdfebe509a8..ffb6c4250aef 100644 --- a/src/libs/actions/OnyxUpdates.js +++ b/src/libs/actions/OnyxUpdates.js @@ -1,34 +1,5 @@ import Onyx from 'react-native-onyx'; import ONYXKEYS from '../../ONYXKEYS'; -import * as API from '../API'; -import Log from '../Log'; - -let onyxUpdatesLastUpdateID; -Onyx.connect({ - key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID, - callback: (val) => (onyxUpdatesLastUpdateID = val), -}); - -/** - * Fetches data when the client has discovered it missed some Onyx updates from the server - * @param {Number} [updateIDFrom] the ID of the Onyx update that we want to start fetching from - * @param {Number} [updateIDTo] the ID of the Onyx update that we want to fetch up to - */ -function getMissingOnyxUpdates(updateIDFrom = 0, updateIDTo = 0) { - console.debug(`[OnyxUpdates] Fetching missing updates updateIDFrom: ${updateIDFrom} and updateIDTo: ${updateIDTo}`); - - API.write( - 'GetMissingOnyxMessages', - { - updateIDFrom, - updateIDTo, - }, - getOnyxDataForOpenOrReconnect(), - - // Set this to true so that the request will be prioritized at the front of the sequential queue - true, - ); -} /** * @@ -41,24 +12,10 @@ function detectAndGetMissingUpdates(lastUpdateID = 0, previousUpdateID = 0) { return; } - console.debug('[OnyxUpdates] Received lastUpdateID from pusher', lastUpdateID); - console.debug('[OnyxUpdates] Received previousUpdateID from pusher', previousUpdateID); - console.debug('[OnyxUpdates] The lastUpdateID the client knows about is', onyxUpdatesLastUpdateID); - - // Store this value in Onyx to allow AuthScreens to fetch incremental updates from the server when a previous session is being reconnected to. - Onyx.set(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID, lastUpdateID); - - // The previous update from the server does not match the last update the client got which means the client is missing some updates. - // ReconnectApp will fetch updates starting from the last update this client got and going to the last update the server sent. - if (onyxUpdatesLastUpdateID < previousUpdateID) { - console.debug('[OnyxUpdates] Gap detected in update IDs so fetching incremental updates'); - Log.info('Gap detected in update IDs from Pusher so fetching incremental updates', true, { - lastUpdateIDFromPusher: lastUpdateID, - previousUpdateIDFromPusher: previousUpdateID, - lastUpdateIDOnClient: onyxUpdatesLastUpdateID, - }); - getMissingOnyxUpdates(onyxUpdatesLastUpdateID, lastUpdateID); - } + Onyx.merge(ONYXKEYS.ONYX_UPDATES, { + lastUpdateIDFromServer: lastUpdateID, + previousUpdateIDFromServer: previousUpdateID, + }); } // eslint-disable-next-line import/prefer-default-export From f17e3f34a67db20ba92a22e83396cb03f83b8171 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 9 Aug 2023 16:20:58 -0600 Subject: [PATCH 19/25] Add comments and clean up code --- src/libs/Middleware/SaveResponseInOnyx.js | 2 +- src/libs/Navigation/AppNavigator/AuthScreens.js | 15 +++++---------- src/libs/actions/App.js | 11 +++++++++-- src/libs/actions/OnyxUpdates.js | 4 ++-- src/libs/actions/User.js | 2 +- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/libs/Middleware/SaveResponseInOnyx.js b/src/libs/Middleware/SaveResponseInOnyx.js index 08aaa4b9aeb2..a3f265d561f5 100644 --- a/src/libs/Middleware/SaveResponseInOnyx.js +++ b/src/libs/Middleware/SaveResponseInOnyx.js @@ -15,7 +15,7 @@ function updateOnyx(updates) { return Onyx.update(updates); } - OnyxUpdates.detectAndGetMissingUpdates(Number(updates.lastUpdateID || 0), Number(updates.previousUpdateID || 0)); + OnyxUpdates.saveUpdateIDs(Number(updates.lastUpdateID || 0), Number(updates.previousUpdateID || 0)); return Onyx.update(updates.onyxData); } diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js index 96467518fb8a..b4ce4ac621f1 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.js +++ b/src/libs/Navigation/AppNavigator/AuthScreens.js @@ -96,11 +96,8 @@ const propTypes = { /** Opt-in experimental mode that prevents certain Onyx keys from persisting to disk */ isUsingMemoryOnlyKeys: PropTypes.bool, - /** Information about the onyx update IDs */ - lastUpdateIDAppliedToClient: PropTypes.shape({ - /** The last Onyx update ID was applied to the client */ - lastUpdateIDAppliedToClient: PropTypes.number, - }), + /** The last Onyx update ID was applied to the client */ + lastUpdateIDAppliedToClient: PropTypes.number, ...windowDimensionsPropTypes, }; @@ -111,9 +108,7 @@ const defaultProps = { email: null, }, lastOpenedPublicRoomID: null, - lastUpdateIDAppliedToClient: { - lastUpdateIDAppliedToClient: null, - }, + lastUpdateIDAppliedToClient: null, }; class AuthScreens extends React.Component { @@ -125,7 +120,7 @@ class AuthScreens extends React.Component { componentDidMount() { NetworkConnection.listenForReconnect(); - NetworkConnection.onReconnect(() => App.reconnectApp(this.props.lastUpdateIDAppliedToClient.lastUpdateIDAppliedToClient)); + NetworkConnection.onReconnect(() => App.reconnectApp(this.props.lastUpdateIDAppliedToClient)); PusherConnectionManager.init(); Pusher.init({ appKey: CONFIG.PUSHER.APP_KEY, @@ -145,7 +140,7 @@ class AuthScreens extends React.Component { if (shouldGetAllData) { App.openApp(); } else { - App.reconnectApp(this.props.lastUpdateIDAppliedToClient.lastUpdateIDAppliedToClient); + App.reconnectApp(this.props.lastUpdateIDAppliedToClient); } App.setUpPoliciesAndNavigate(this.props.session, !this.props.isSmallScreenWidth); diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index b90ce2f8c815..7cc75fcd5fec 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -229,11 +229,17 @@ function getMissingOnyxUpdates(updateIDFrom = 0, updateIDTo = 0) { ); } +// The next 40ish lines of code are used for detecting when there is a gap of OnyxUpdates between what was last applied to the client and the updates the server has. +// When a gap is detected, the missing updates are fetched from the API. + +// These key needs to be separate from ONYXKEYS.ONYX_UPDATES so that it can be updated without triggering the callback when the server IDs are updated let lastUpdateIDAppliedToClient = 0; Onyx.connect({ key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, callback: (val) => (lastUpdateIDAppliedToClient = val), }); + +// This object is stored in Onyx and the callback is triggered anytime new update IDs are received either from Pusher or from HTTPs (it was the only way to keep the code DRY and to prevent circular dependencies) const onyxUpdates = { lastUpdateIDFromServer: 0, previousUpdateIDFromServer: 0, @@ -257,15 +263,16 @@ Onyx.connect({ Log.info('Gap detected in update IDs from Pusher so fetching incremental updates', true, { lastUpdateIDFromServer, previousUpdateIDFromServer, - lastUpdateIDAppliedToClient: onyxUpdates.lastUpdateIDAppliedToClient, + lastUpdateIDAppliedToClient, }); - getMissingOnyxUpdates(onyxUpdates.lastUpdateIDAppliedToClient, lastUpdateIDFromServer); + getMissingOnyxUpdates(lastUpdateIDAppliedToClient, lastUpdateIDFromServer); } // Update the local values to be the same as the values stored in Onyx onyxUpdates.lastUpdateIDFromServer = lastUpdateIDFromServer || 0; onyxUpdates.previousUpdateIDFromServer = previousUpdateIDFromServer || 0; + // Update this value so that it matches what was just received from the server Onyx.merge(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, lastUpdateIDFromServer || 0); }, }); diff --git a/src/libs/actions/OnyxUpdates.js b/src/libs/actions/OnyxUpdates.js index ffb6c4250aef..182cdcc225e5 100644 --- a/src/libs/actions/OnyxUpdates.js +++ b/src/libs/actions/OnyxUpdates.js @@ -6,7 +6,7 @@ import ONYXKEYS from '../../ONYXKEYS'; * @param {Number} [lastUpdateID] * @param {Number} [previousUpdateID] */ -function detectAndGetMissingUpdates(lastUpdateID = 0, previousUpdateID = 0) { +function saveUpdateIDs(lastUpdateID = 0, previousUpdateID = 0) { // Return early if there were no updateIDs if (!lastUpdateID) { return; @@ -19,4 +19,4 @@ function detectAndGetMissingUpdates(lastUpdateID = 0, previousUpdateID = 0) { } // eslint-disable-next-line import/prefer-default-export -export {detectAndGetMissingUpdates}; +export {saveUpdateIDs}; diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index 680358c73252..e79d121caf37 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -554,7 +554,7 @@ function subscribeToUserEvents() { updates = pushJSON; } else { updates = pushJSON.updates; - OnyxUpdates.detectAndGetMissingUpdates(Number(pushJSON.lastUpdateID || 0), Number(pushJSON.previousUpdateID || 0)); + OnyxUpdates.saveUpdateIDs(Number(pushJSON.lastUpdateID || 0), Number(pushJSON.previousUpdateID || 0)); } _.each(updates, (multipleEvent) => { PusherUtils.triggerMultiEventHandler(multipleEvent.eventType, multipleEvent.data); From 021e41b11d2dbc2cd66f753d1ce792e0abbc8c36 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 9 Aug 2023 16:27:13 -0600 Subject: [PATCH 20/25] Remove unused import --- src/libs/actions/App.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index 7cc75fcd5fec..d4d9f8f9876b 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -18,7 +18,6 @@ import * as Session from './Session'; import * as ReportActionsUtils from '../ReportActionsUtils'; import Timing from './Timing'; import * as Browser from '../Browser'; -import {last} from 'lodash'; let currentUserAccountID; let currentUserEmail; From d77564c05959933956e278f377fbca02c7906b2a Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 9 Aug 2023 16:33:13 -0600 Subject: [PATCH 21/25] Correct docs, update comments --- src/libs/Middleware/SaveResponseInOnyx.js | 8 +++++--- src/libs/Navigation/AppNavigator/AuthScreens.js | 3 +-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libs/Middleware/SaveResponseInOnyx.js b/src/libs/Middleware/SaveResponseInOnyx.js index a3f265d561f5..c9233e046a7a 100644 --- a/src/libs/Middleware/SaveResponseInOnyx.js +++ b/src/libs/Middleware/SaveResponseInOnyx.js @@ -5,12 +5,14 @@ import * as OnyxUpdates from '../actions/OnyxUpdates'; /** * @param {Object} updates - * @param {Object[]} updates.onyxData an array of Onyx update instruction objects - * @param {Number} updates.previousUpdateID - * @param {Number} updates.lastUpdateID + * @param {Object[]} [updates.onyxData] an array of Onyx update instruction objects + * @param {Number} [updates.previousUpdateID] + * @param {Number} [updates.lastUpdateID] * @returns {Promise} */ function updateOnyx(updates) { + // `updates.onyxData` only exists in the latest format of the OnyxUpdates provided by the RELIABLE_UPDATES beta. + // If the value doesn't exist, then onyx is updated with the old format of updates. if (!updates.onyxData) { return Onyx.update(updates); } diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js index b4ce4ac621f1..13216ea3b662 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.js +++ b/src/libs/Navigation/AppNavigator/AuthScreens.js @@ -131,8 +131,7 @@ class AuthScreens extends React.Component { }); // If we are on this screen then we are "logged in", but the user might not have "just logged in". They could be reopening the app - // or returning from background. If so, we'll assume they have some app data already and we can call - // reconnectApp(lastUpdateIDAppliedToClientLastUpdateIDAppliedToClient) instead of openApp(). + // or returning from background. If so, we'll assume they have some app data already and we can call reconnectApp() instead of openApp(). // Note: If a Guide has enabled the memory only key mode then we do want to run OpenApp as their app will not be rehydrated with // the correct state on refresh. They are explicitly opting out of storing data they would need (i.e. reports_) to take advantage of // the optimizations performed during ReconnectApp. From 6a25f772849a385ae0da379620c488b14748bb2f Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Thu, 10 Aug 2023 07:52:33 -0600 Subject: [PATCH 22/25] Correct comments and improve logs --- src/libs/Pusher/pusher.js | 6 ++++-- src/libs/actions/App.js | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libs/Pusher/pusher.js b/src/libs/Pusher/pusher.js index 267153e9494b..43fde187d00b 100644 --- a/src/libs/Pusher/pusher.js +++ b/src/libs/Pusher/pusher.js @@ -136,7 +136,7 @@ function bindEventToChannel(channel, eventName, eventCallback = () => {}) { try { data = _.isObject(eventData) ? eventData : JSON.parse(eventData); } catch (err) { - Log.alert('[Pusher] Unable to parse JSON response from Pusher 1', {error: err, eventData}); + Log.alert('[Pusher] Unable to parse single JSON event data from Pusher', {error: err, eventData}); return; } if (data.id === undefined || data.chunk === undefined || data.final === undefined) { @@ -168,10 +168,12 @@ function bindEventToChannel(channel, eventName, eventCallback = () => {}) { try { eventCallback(JSON.parse(chunkedEvent.chunks.join(''))); } catch (err) { - Log.alert('[Pusher] Unable to parse chunked JSON response from Pusher 2', { + Log.alert('[Pusher] Unable to parse chunked JSON response from Pusher', { error: err, eventData: chunkedEvent.chunks.join(''), }); + + // Using console.error is helpful here because it will print a usable stack trace to the console to debug where the error comes from console.error(err); } diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index d4d9f8f9876b..21bed264562a 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -259,7 +259,7 @@ Onyx.connect({ // getMissingOnyxUpdates will fetch updates starting from the last update this client got and going to the last update the server sent. if (lastUpdateIDAppliedToClient && previousUpdateIDFromServer && lastUpdateIDAppliedToClient < previousUpdateIDFromServer) { console.debug('[OnyxUpdates] Gap detected in update IDs so fetching incremental updates'); - Log.info('Gap detected in update IDs from Pusher so fetching incremental updates', true, { + Log.info('Gap detected in update IDs from server so fetching incremental updates', true, { lastUpdateIDFromServer, previousUpdateIDFromServer, lastUpdateIDAppliedToClient, From 2eb7c879c934a248c5f48c195aa3223c7145ce7a Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Thu, 10 Aug 2023 07:59:39 -0600 Subject: [PATCH 23/25] Remove unnecessary method --- src/libs/Middleware/SaveResponseInOnyx.js | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/src/libs/Middleware/SaveResponseInOnyx.js b/src/libs/Middleware/SaveResponseInOnyx.js index c9233e046a7a..b347e45ab61c 100644 --- a/src/libs/Middleware/SaveResponseInOnyx.js +++ b/src/libs/Middleware/SaveResponseInOnyx.js @@ -3,24 +3,6 @@ import CONST from '../../CONST'; import * as QueuedOnyxUpdates from '../actions/QueuedOnyxUpdates'; import * as OnyxUpdates from '../actions/OnyxUpdates'; -/** - * @param {Object} updates - * @param {Object[]} [updates.onyxData] an array of Onyx update instruction objects - * @param {Number} [updates.previousUpdateID] - * @param {Number} [updates.lastUpdateID] - * @returns {Promise} - */ -function updateOnyx(updates) { - // `updates.onyxData` only exists in the latest format of the OnyxUpdates provided by the RELIABLE_UPDATES beta. - // If the value doesn't exist, then onyx is updated with the old format of updates. - if (!updates.onyxData) { - return Onyx.update(updates); - } - - OnyxUpdates.saveUpdateIDs(Number(updates.lastUpdateID || 0), Number(updates.previousUpdateID || 0)); - return Onyx.update(updates.onyxData); -} - /** * @param {Promise} response * @param {Object} request @@ -33,9 +15,12 @@ function SaveResponseInOnyx(response, request) { return; } + // Save the update IDs to Onyx so they can be used to fetch incremental updates if the client gets out of sync from the server + OnyxUpdates.saveUpdateIDs(Number(responseData.lastUpdateID || 0), Number(responseData.previousUpdateID || 0)); + // For most requests we can immediately update Onyx. For write requests we queue the updates and apply them after the sequential queue has flushed to prevent a replay effect in // the UI. See https://github.com/Expensify/App/issues/12775 for more info. - const updateHandler = request.data.apiRequestType === CONST.API_REQUEST_TYPE.WRITE ? QueuedOnyxUpdates.queueOnyxUpdates : updateOnyx; + const updateHandler = request.data.apiRequestType === CONST.API_REQUEST_TYPE.WRITE ? QueuedOnyxUpdates.queueOnyxUpdates : Onyx.update; // First apply any onyx data updates that are being sent back from the API. We wait for this to complete and then // apply successData or failureData. This ensures that we do not update any pending, loading, or other UI states contained From 7934f373fdb0ee19698c44945b9cee4593349a5f Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Thu, 10 Aug 2023 08:13:41 -0600 Subject: [PATCH 24/25] Remove unnecessary local variables --- src/libs/actions/App.js | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index 21bed264562a..9f9a05b53c26 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -238,11 +238,6 @@ Onyx.connect({ callback: (val) => (lastUpdateIDAppliedToClient = val), }); -// This object is stored in Onyx and the callback is triggered anytime new update IDs are received either from Pusher or from HTTPs (it was the only way to keep the code DRY and to prevent circular dependencies) -const onyxUpdates = { - lastUpdateIDFromServer: 0, - previousUpdateIDFromServer: 0, -}; Onyx.connect({ key: ONYXKEYS.ONYX_UPDATES, callback: (val) => { @@ -267,12 +262,10 @@ Onyx.connect({ getMissingOnyxUpdates(lastUpdateIDAppliedToClient, lastUpdateIDFromServer); } - // Update the local values to be the same as the values stored in Onyx - onyxUpdates.lastUpdateIDFromServer = lastUpdateIDFromServer || 0; - onyxUpdates.previousUpdateIDFromServer = previousUpdateIDFromServer || 0; - - // Update this value so that it matches what was just received from the server - Onyx.merge(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, lastUpdateIDFromServer || 0); + if (lastUpdateIDFromServer > lastUpdateIDAppliedToClient) { + // Update this value so that it matches what was just received from the server + Onyx.merge(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, lastUpdateIDFromServer || 0); + } }, }); From 636f26c17ada98b2fa7b0617dfcc16c2c88e2590 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Fri, 11 Aug 2023 07:47:35 -0600 Subject: [PATCH 25/25] Rename onyx key --- src/ONYXKEYS.js | 2 +- src/libs/actions/App.js | 4 ++-- src/libs/actions/OnyxUpdates.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index 5cc95ded4765..32a9c1c3185e 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -244,7 +244,7 @@ export default { IS_USING_MEMORY_ONLY_KEYS: 'isUsingMemoryOnlyKeys', // Information about the onyx updates IDs that were received from the server - ONYX_UPDATES: 'onyxUpdates', + ONYX_UPDATES_FROM_SERVER: 'onyxUpdatesFromServer', // The last update ID that was applied to the client ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT: 'OnyxUpdatesLastUpdateIDAppliedToClient', diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index 9f9a05b53c26..fe2c908dfd0b 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -231,7 +231,7 @@ function getMissingOnyxUpdates(updateIDFrom = 0, updateIDTo = 0) { // The next 40ish lines of code are used for detecting when there is a gap of OnyxUpdates between what was last applied to the client and the updates the server has. // When a gap is detected, the missing updates are fetched from the API. -// These key needs to be separate from ONYXKEYS.ONYX_UPDATES so that it can be updated without triggering the callback when the server IDs are updated +// These key needs to be separate from ONYXKEYS.ONYX_UPDATES_FROM_SERVER so that it can be updated without triggering the callback when the server IDs are updated let lastUpdateIDAppliedToClient = 0; Onyx.connect({ key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, @@ -239,7 +239,7 @@ Onyx.connect({ }); Onyx.connect({ - key: ONYXKEYS.ONYX_UPDATES, + key: ONYXKEYS.ONYX_UPDATES_FROM_SERVER, callback: (val) => { if (!val) { return; diff --git a/src/libs/actions/OnyxUpdates.js b/src/libs/actions/OnyxUpdates.js index 182cdcc225e5..e582016f0109 100644 --- a/src/libs/actions/OnyxUpdates.js +++ b/src/libs/actions/OnyxUpdates.js @@ -12,7 +12,7 @@ function saveUpdateIDs(lastUpdateID = 0, previousUpdateID = 0) { return; } - Onyx.merge(ONYXKEYS.ONYX_UPDATES, { + Onyx.merge(ONYXKEYS.ONYX_UPDATES_FROM_SERVER, { lastUpdateIDFromServer: lastUpdateID, previousUpdateIDFromServer: previousUpdateID, });