From 23b07140c9d82ee4be04362f5e2af2a1cbf7de16 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Mon, 13 May 2024 12:17:55 +0200 Subject: [PATCH 01/20] add encapsulated functionality to OnyxUpdateManager --- src/libs/actions/OnyxUpdateManager/index.ts | 51 +++++++++++++++++++-- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/OnyxUpdateManager/index.ts b/src/libs/actions/OnyxUpdateManager/index.ts index 8c6695379614..e11b8d268616 100644 --- a/src/libs/actions/OnyxUpdateManager/index.ts +++ b/src/libs/actions/OnyxUpdateManager/index.ts @@ -54,6 +54,51 @@ const resetDeferralLogicVariables = () => { deferredUpdatesProxy.deferredUpdates = {}; }; +/** + * Manually processes and applies the updates from the deferred updates queue. (used e.g. for push notifications) + */ +function processDeferredUpdates() { + if (queryPromise) { + queryPromise.finally(OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates); + } + + queryPromise = OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(); +} + +/** + * Allows adding onyx updates to the deferred updates queue manually. + * By default, this will automatically process the updates. Setting "shouldProcessUpdates" to false will prevent this. + * @param updates The updates that should be applied (e.g. updates from push notifications) + * @param shouldProcessUpdates Whether the updates should be processed immediately + * @returns + */ +function enqueueDeferredUpdates(updates: OnyxUpdatesFromServer[], shouldProcessUpdates = true) { + SequentialQueue.pause(); + + updates.forEach((update) => { + const lastUpdateID = Number(update.lastUpdateID); + if (deferredUpdatesProxy.deferredUpdates[lastUpdateID]) return; + + deferredUpdatesProxy.deferredUpdates[lastUpdateID] = update; + }); + + if (!shouldProcessUpdates) return; + + processDeferredUpdates(); +} + +/** + * Clears the deferred updates queue and unpauses the SequentialQueue + */ +function clearDeferredUpdates(shouldUnpauseSequentialQueue = true) { + resetDeferralLogicVariables(); + + if (!shouldUnpauseSequentialQueue) return; + + Onyx.set(ONYXKEYS.ONYX_UPDATES_FROM_SERVER, null); + SequentialQueue.unpause(); +} + // This function will reset the query variables, unpause the SequentialQueue and log an info to the user. function finalizeUpdatesAndResumeQueue() { console.debug('[OnyxUpdateManager] Done applying all updates'); @@ -61,9 +106,7 @@ function finalizeUpdatesAndResumeQueue() { resolveQueryPromiseWrapper(); queryPromiseWrapper = createQueryPromiseWrapper(); - resetDeferralLogicVariables(); - Onyx.set(ONYXKEYS.ONYX_UPDATES_FROM_SERVER, null); - SequentialQueue.unpause(); + clearDeferredUpdates(); } /** @@ -156,4 +199,4 @@ export default () => { }); }; -export {handleOnyxUpdateGap, queryPromiseWrapper as queryPromise, resetDeferralLogicVariables}; +export {handleOnyxUpdateGap, processDeferredUpdates, enqueueDeferredUpdates, clearDeferredUpdates, queryPromiseWrapper as queryPromise, resetDeferralLogicVariables}; From b3de3630f327f9cc72f3459b53c3ace5ee196e44 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 May 2024 12:56:35 +0200 Subject: [PATCH 02/20] restructure deferred updates functions --- src/libs/actions/OnyxUpdateManager/index.ts | 74 ++++--------------- .../utils/GetMissingOnyxUpdatesPromise.ts | 6 ++ .../utils/deferredUpdates.ts | 58 ++++++++++++++- .../actions/OnyxUpdateManager/utils/index.ts | 2 +- 4 files changed, 77 insertions(+), 63 deletions(-) create mode 100644 src/libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise.ts diff --git a/src/libs/actions/OnyxUpdateManager/index.ts b/src/libs/actions/OnyxUpdateManager/index.ts index e11b8d268616..03340d962173 100644 --- a/src/libs/actions/OnyxUpdateManager/index.ts +++ b/src/libs/actions/OnyxUpdateManager/index.ts @@ -1,14 +1,15 @@ import type {OnyxEntry} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; +import GetMissingOnyxUpdatesPromiseProxy from '@libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise'; import * as ActiveClientManager from '@libs/ActiveClientManager'; import Log from '@libs/Log'; import * as SequentialQueue from '@libs/Network/SequentialQueue'; import * as App from '@userActions/App'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {OnyxUpdatesFromServer, Response} from '@src/types/onyx'; +import type {OnyxUpdatesFromServer} from '@src/types/onyx'; import {isValidOnyxUpdateFromServer} from '@src/types/onyx/OnyxUpdatesFromServer'; import * as OnyxUpdateManagerUtils from './utils'; -import deferredUpdatesProxy from './utils/deferredUpdates'; +import DeferredUpdates from './utils/DeferredUpdates'; // This file is in charge of looking at the updateIDs coming from the server and comparing them to the last updateID that the client has. // If the client is behind the server, then we need to @@ -39,8 +40,6 @@ Onyx.connect({ }, }); -let queryPromise: Promise | undefined; - let resolveQueryPromiseWrapper: () => void; const createQueryPromiseWrapper = () => new Promise((resolve) => { @@ -50,55 +49,10 @@ const createQueryPromiseWrapper = () => let queryPromiseWrapper = createQueryPromiseWrapper(); const resetDeferralLogicVariables = () => { - queryPromise = undefined; - deferredUpdatesProxy.deferredUpdates = {}; + GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise = undefined; + DeferredUpdates.deferredUpdates = {}; }; -/** - * Manually processes and applies the updates from the deferred updates queue. (used e.g. for push notifications) - */ -function processDeferredUpdates() { - if (queryPromise) { - queryPromise.finally(OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates); - } - - queryPromise = OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(); -} - -/** - * Allows adding onyx updates to the deferred updates queue manually. - * By default, this will automatically process the updates. Setting "shouldProcessUpdates" to false will prevent this. - * @param updates The updates that should be applied (e.g. updates from push notifications) - * @param shouldProcessUpdates Whether the updates should be processed immediately - * @returns - */ -function enqueueDeferredUpdates(updates: OnyxUpdatesFromServer[], shouldProcessUpdates = true) { - SequentialQueue.pause(); - - updates.forEach((update) => { - const lastUpdateID = Number(update.lastUpdateID); - if (deferredUpdatesProxy.deferredUpdates[lastUpdateID]) return; - - deferredUpdatesProxy.deferredUpdates[lastUpdateID] = update; - }); - - if (!shouldProcessUpdates) return; - - processDeferredUpdates(); -} - -/** - * Clears the deferred updates queue and unpauses the SequentialQueue - */ -function clearDeferredUpdates(shouldUnpauseSequentialQueue = true) { - resetDeferralLogicVariables(); - - if (!shouldUnpauseSequentialQueue) return; - - Onyx.set(ONYXKEYS.ONYX_UPDATES_FROM_SERVER, null); - SequentialQueue.unpause(); -} - // This function will reset the query variables, unpause the SequentialQueue and log an info to the user. function finalizeUpdatesAndResumeQueue() { console.debug('[OnyxUpdateManager] Done applying all updates'); @@ -106,7 +60,7 @@ function finalizeUpdatesAndResumeQueue() { resolveQueryPromiseWrapper(); queryPromiseWrapper = createQueryPromiseWrapper(); - clearDeferredUpdates(); + DeferredUpdates.clearDeferredUpdates(); } /** @@ -154,22 +108,22 @@ function handleOnyxUpdateGap(onyxUpdatesFromServer: OnyxEntry 0) { @@ -185,10 +139,12 @@ function handleOnyxUpdateGap(onyxUpdatesFromServer: OnyxEntry OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(clientLastUpdateID)); + GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise = App.getMissingOnyxUpdates(lastUpdateIDFromClient, previousUpdateIDFromServer).then(() => + OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(clientLastUpdateID), + ); } - queryPromise.finally(finalizeUpdatesAndResumeQueue); + GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise.finally(finalizeUpdatesAndResumeQueue); } export default () => { @@ -199,4 +155,4 @@ export default () => { }); }; -export {handleOnyxUpdateGap, processDeferredUpdates, enqueueDeferredUpdates, clearDeferredUpdates, queryPromiseWrapper as queryPromise, resetDeferralLogicVariables}; +export {handleOnyxUpdateGap, queryPromiseWrapper as queryPromise, resetDeferralLogicVariables}; diff --git a/src/libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise.ts b/src/libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise.ts new file mode 100644 index 000000000000..41e06bafc922 --- /dev/null +++ b/src/libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise.ts @@ -0,0 +1,6 @@ +import {Response} from '@src/types/onyx'; +import createProxyForObject from '@src/utils/createProxyForObject'; + +const GetMissingOnyxUpdatesPromiseValue = {GetMissingOnyxUpdatesPromise: undefined as Promise | undefined}; + +export default createProxyForObject(GetMissingOnyxUpdatesPromiseValue); diff --git a/src/libs/actions/OnyxUpdateManager/utils/deferredUpdates.ts b/src/libs/actions/OnyxUpdateManager/utils/deferredUpdates.ts index 838c27821aae..d9c88c486920 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/deferredUpdates.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/deferredUpdates.ts @@ -1,8 +1,60 @@ +import Onyx from 'react-native-onyx'; import type {DeferredUpdatesDictionary} from '@libs/actions/OnyxUpdateManager/types'; +import GetMissingOnyxUpdatesPromiseProxy from '@libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise'; +import * as SequentialQueue from '@libs/Network/SequentialQueue'; +import ONYXKEYS from '@src/ONYXKEYS'; +import {OnyxUpdatesFromServer} from '@src/types/onyx'; import createProxyForObject from '@src/utils/createProxyForObject'; +import * as OnyxUpdateManagerUtils from '.'; -const deferredUpdatesValue = {deferredUpdates: {} as DeferredUpdatesDictionary}; +let deferredUpdates: DeferredUpdatesDictionary = {}; -const deferredUpdatesProxy = createProxyForObject(deferredUpdatesValue); +/** + * Manually processes and applies the updates from the deferred updates queue. (used e.g. for push notifications) + */ +function processDeferredUpdates() { + if (GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise) { + GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise.finally(OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates); + } -export default deferredUpdatesProxy; + GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise = OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(); +} + +/** + * Allows adding onyx updates to the deferred updates queue manually. + * By default, this will automatically process the updates. Setting "shouldProcessUpdates" to false will prevent this. + * @param updates The updates that should be applied (e.g. updates from push notifications) + * @param shouldProcessUpdates Whether the updates should be processed immediately + * @returns + */ +function enqueueDeferredUpdates(updates: OnyxUpdatesFromServer[], shouldProcessUpdates = true) { + SequentialQueue.pause(); + + updates.forEach((update) => { + const lastUpdateID = Number(update.lastUpdateID); + if (deferredUpdates[lastUpdateID]) return; + + deferredUpdates[lastUpdateID] = update; + }); + + if (!shouldProcessUpdates) return; + + processDeferredUpdates(); +} + +/** + * Clears the deferred updates queue and unpauses the SequentialQueue + */ +function clearDeferredUpdates(shouldUnpauseSequentialQueue = true) { + GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise = undefined; + deferredUpdates = {}; + + if (!shouldUnpauseSequentialQueue) return; + + Onyx.set(ONYXKEYS.ONYX_UPDATES_FROM_SERVER, null); + SequentialQueue.unpause(); +} + +const DeferredUpdates = {deferredUpdates, enqueueDeferredUpdates, clearDeferredUpdates, processDeferredUpdates}; + +export default createProxyForObject(DeferredUpdates); diff --git a/src/libs/actions/OnyxUpdateManager/utils/index.ts b/src/libs/actions/OnyxUpdateManager/utils/index.ts index 04e39610ed6b..573d43e95db8 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/index.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/index.ts @@ -4,7 +4,7 @@ import * as App from '@userActions/App'; import type {DeferredUpdatesDictionary, DetectGapAndSplitResult} from '@userActions/OnyxUpdateManager/types'; import ONYXKEYS from '@src/ONYXKEYS'; import {applyUpdates} from './applyUpdates'; -import deferredUpdatesProxy from './deferredUpdates'; +import deferredUpdatesProxy from './DeferredUpdates'; let lastUpdateIDAppliedToClient = 0; Onyx.connect({ From c385463b64c7e00b0d715e69c0d460d5b73073e3 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 May 2024 13:04:57 +0200 Subject: [PATCH 03/20] fix: wrong imports --- src/libs/actions/OnyxUpdateManager/utils/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/OnyxUpdateManager/utils/index.ts b/src/libs/actions/OnyxUpdateManager/utils/index.ts index 573d43e95db8..5f216bdcbdc4 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/index.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/index.ts @@ -4,7 +4,7 @@ import * as App from '@userActions/App'; import type {DeferredUpdatesDictionary, DetectGapAndSplitResult} from '@userActions/OnyxUpdateManager/types'; import ONYXKEYS from '@src/ONYXKEYS'; import {applyUpdates} from './applyUpdates'; -import deferredUpdatesProxy from './DeferredUpdates'; +import DeferredUpdates from './DeferredUpdates'; let lastUpdateIDAppliedToClient = 0; Onyx.connect({ @@ -84,7 +84,7 @@ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number, previousPa // We only want to apply deferred updates that are newer than the last update that was applied to the client. // At this point, the missing updates from "GetMissingOnyxUpdates" have been applied already, so we can safely filter out. - const pendingDeferredUpdates = Object.entries(deferredUpdatesProxy.deferredUpdates).reduce( + const pendingDeferredUpdates = Object.entries(DeferredUpdates.deferredUpdates).reduce( (accUpdates, [lastUpdateID, update]) => ({ ...accUpdates, ...(Number(lastUpdateID) > lastUpdateIDFromClient ? {[Number(lastUpdateID)]: update} : {}), @@ -106,7 +106,7 @@ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number, previousPa Log.info('[DeferredUpdates] Gap detected in deferred updates', false, {lastUpdateIDFromClient, latestMissingUpdateID}); return new Promise((resolve, reject) => { - deferredUpdatesProxy.deferredUpdates = {}; + DeferredUpdates.deferredUpdates = {}; applyUpdates(applicableUpdates).then(() => { // After we have applied the applicable updates, there might have been new deferred updates added. @@ -116,7 +116,7 @@ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number, previousPa const newLastUpdateIDFromClient = clientLastUpdateID ?? lastUpdateIDAppliedToClient ?? 0; - deferredUpdatesProxy.deferredUpdates = {...deferredUpdatesProxy.deferredUpdates, ...updatesAfterGaps}; + DeferredUpdates.deferredUpdates = {...DeferredUpdates.deferredUpdates, ...updatesAfterGaps}; // If lastUpdateIDAppliedToClient got updated in the meantime, we will just retrigger the validation and application of the current deferred updates. if (latestMissingUpdateID <= newLastUpdateIDFromClient) { From 91032c84f9ba9eeaa5677d5bda0523e9a30a8bae Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 May 2024 13:06:13 +0200 Subject: [PATCH 04/20] rename file --- .../utils/{deferredUpdates.ts => deferredUpdatesTemp.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/libs/actions/OnyxUpdateManager/utils/{deferredUpdates.ts => deferredUpdatesTemp.ts} (100%) diff --git a/src/libs/actions/OnyxUpdateManager/utils/deferredUpdates.ts b/src/libs/actions/OnyxUpdateManager/utils/deferredUpdatesTemp.ts similarity index 100% rename from src/libs/actions/OnyxUpdateManager/utils/deferredUpdates.ts rename to src/libs/actions/OnyxUpdateManager/utils/deferredUpdatesTemp.ts From 4a3b39af18e03029078e4efa50f1f2a9d9d14614 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 May 2024 13:06:25 +0200 Subject: [PATCH 05/20] rename file --- .../utils/{deferredUpdatesTemp.ts => DeferredUpdates.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/libs/actions/OnyxUpdateManager/utils/{deferredUpdatesTemp.ts => DeferredUpdates.ts} (100%) diff --git a/src/libs/actions/OnyxUpdateManager/utils/deferredUpdatesTemp.ts b/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts similarity index 100% rename from src/libs/actions/OnyxUpdateManager/utils/deferredUpdatesTemp.ts rename to src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts From e11b521326b533aa3c2282091863845622f08065 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 May 2024 13:06:28 +0200 Subject: [PATCH 06/20] fix lint --- .../OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise.ts b/src/libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise.ts index 41e06bafc922..a15c787c17d7 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise.ts @@ -1,4 +1,4 @@ -import {Response} from '@src/types/onyx'; +import type {Response} from '@src/types/onyx'; import createProxyForObject from '@src/utils/createProxyForObject'; const GetMissingOnyxUpdatesPromiseValue = {GetMissingOnyxUpdatesPromise: undefined as Promise | undefined}; From d159c0169a9399b87fccf27f3d24b73e89ac9a26 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 May 2024 13:09:03 +0200 Subject: [PATCH 07/20] add comment --- src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts b/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts index d9c88c486920..018c62cf1ec6 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts @@ -44,6 +44,7 @@ function enqueueDeferredUpdates(updates: OnyxUpdatesFromServer[], shouldProcessU /** * Clears the deferred updates queue and unpauses the SequentialQueue + * @param shouldUnpauseSequentialQueue Whether the SequentialQueue should be unpaused after clearing the deferred updates */ function clearDeferredUpdates(shouldUnpauseSequentialQueue = true) { GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise = undefined; From c91b5c0fe21f34640682c98dd3533f26371f42e3 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 May 2024 13:22:17 +0200 Subject: [PATCH 08/20] fix: lint errors --- src/libs/actions/OnyxUpdateManager/index.ts | 2 +- .../utils/DeferredUpdates.ts | 19 +++++++++++++------ .../actions/OnyxUpdateManager/utils/index.ts | 17 ++++++++++++----- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/libs/actions/OnyxUpdateManager/index.ts b/src/libs/actions/OnyxUpdateManager/index.ts index 03340d962173..44b9b45b5680 100644 --- a/src/libs/actions/OnyxUpdateManager/index.ts +++ b/src/libs/actions/OnyxUpdateManager/index.ts @@ -1,6 +1,5 @@ import type {OnyxEntry} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; -import GetMissingOnyxUpdatesPromiseProxy from '@libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise'; import * as ActiveClientManager from '@libs/ActiveClientManager'; import Log from '@libs/Log'; import * as SequentialQueue from '@libs/Network/SequentialQueue'; @@ -10,6 +9,7 @@ import type {OnyxUpdatesFromServer} from '@src/types/onyx'; import {isValidOnyxUpdateFromServer} from '@src/types/onyx/OnyxUpdatesFromServer'; import * as OnyxUpdateManagerUtils from './utils'; import DeferredUpdates from './utils/DeferredUpdates'; +import GetMissingOnyxUpdatesPromiseProxy from './utils/GetMissingOnyxUpdatesPromise'; // This file is in charge of looking at the updateIDs coming from the server and comparing them to the last updateID that the client has. // If the client is behind the server, then we need to diff --git a/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts b/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts index 018c62cf1ec6..c90379b07042 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts @@ -1,11 +1,12 @@ import Onyx from 'react-native-onyx'; import type {DeferredUpdatesDictionary} from '@libs/actions/OnyxUpdateManager/types'; -import GetMissingOnyxUpdatesPromiseProxy from '@libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise'; import * as SequentialQueue from '@libs/Network/SequentialQueue'; import ONYXKEYS from '@src/ONYXKEYS'; -import {OnyxUpdatesFromServer} from '@src/types/onyx'; +import type {OnyxUpdatesFromServer} from '@src/types/onyx'; import createProxyForObject from '@src/utils/createProxyForObject'; +// eslint-disable-next-line import/no-cycle import * as OnyxUpdateManagerUtils from '.'; +import GetMissingOnyxUpdatesPromiseProxy from './GetMissingOnyxUpdatesPromise'; let deferredUpdates: DeferredUpdatesDictionary = {}; @@ -14,7 +15,7 @@ let deferredUpdates: DeferredUpdatesDictionary = {}; */ function processDeferredUpdates() { if (GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise) { - GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise.finally(OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates); + GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise.finally(() => OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates); } GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise = OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(); @@ -32,12 +33,16 @@ function enqueueDeferredUpdates(updates: OnyxUpdatesFromServer[], shouldProcessU updates.forEach((update) => { const lastUpdateID = Number(update.lastUpdateID); - if (deferredUpdates[lastUpdateID]) return; + if (deferredUpdates[lastUpdateID]) { + return; + } deferredUpdates[lastUpdateID] = update; }); - if (!shouldProcessUpdates) return; + if (!shouldProcessUpdates) { + return; + } processDeferredUpdates(); } @@ -50,7 +55,9 @@ function clearDeferredUpdates(shouldUnpauseSequentialQueue = true) { GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise = undefined; deferredUpdates = {}; - if (!shouldUnpauseSequentialQueue) return; + if (!shouldUnpauseSequentialQueue) { + return; + } Onyx.set(ONYXKEYS.ONYX_UPDATES_FROM_SERVER, null); SequentialQueue.unpause(); diff --git a/src/libs/actions/OnyxUpdateManager/utils/index.ts b/src/libs/actions/OnyxUpdateManager/utils/index.ts index 5f216bdcbdc4..a8ebd2b6ae04 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/index.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/index.ts @@ -4,6 +4,7 @@ import * as App from '@userActions/App'; import type {DeferredUpdatesDictionary, DetectGapAndSplitResult} from '@userActions/OnyxUpdateManager/types'; import ONYXKEYS from '@src/ONYXKEYS'; import {applyUpdates} from './applyUpdates'; +// eslint-disable-next-line import/no-cycle import DeferredUpdates from './DeferredUpdates'; let lastUpdateIDAppliedToClient = 0; @@ -12,9 +13,13 @@ Onyx.connect({ callback: (value) => (lastUpdateIDAppliedToClient = value ?? 0), }); -// In order for the deferred updates to be applied correctly in order, -// we need to check if there are any gaps between deferred updates. - +/** + * In order for the deferred updates to be applied correctly in order, + * we need to check if there are any gaps between deferred updates. + * @param updates The deferred updates to be checked for gaps + * @param clientLastUpdateID An optional lastUpdateID passed to use instead of the lastUpdateIDAppliedToClient + * @returns + */ function detectGapsAndSplit(updates: DeferredUpdatesDictionary, clientLastUpdateID?: number): DetectGapAndSplitResult { const lastUpdateIDFromClient = clientLastUpdateID ?? lastUpdateIDAppliedToClient ?? 0; @@ -75,8 +80,10 @@ function detectGapsAndSplit(updates: DeferredUpdatesDictionary, clientLastUpdate return {applicableUpdates, updatesAfterGaps, latestMissingUpdateID}; } -// This function will check for gaps in the deferred updates and -// apply the updates in order after the missing updates are fetched and applied +/** + * This function will check for gaps in the deferred updates and + * apply the updates in order after the missing updates are fetched and applied + */ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number, previousParams?: {newLastUpdateIDFromClient: number; latestMissingUpdateID: number}): Promise { const lastUpdateIDFromClient = clientLastUpdateID ?? lastUpdateIDAppliedToClient ?? 0; From c57a5e910a24738a25030e89f30fe999d7cf64a7 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 May 2024 22:39:54 +0200 Subject: [PATCH 09/20] rename functions --- src/libs/actions/OnyxUpdateManager/index.ts | 2 +- .../actions/OnyxUpdateManager/utils/DeferredUpdates.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/actions/OnyxUpdateManager/index.ts b/src/libs/actions/OnyxUpdateManager/index.ts index 44b9b45b5680..37fc1ebe523b 100644 --- a/src/libs/actions/OnyxUpdateManager/index.ts +++ b/src/libs/actions/OnyxUpdateManager/index.ts @@ -60,7 +60,7 @@ function finalizeUpdatesAndResumeQueue() { resolveQueryPromiseWrapper(); queryPromiseWrapper = createQueryPromiseWrapper(); - DeferredUpdates.clearDeferredUpdates(); + DeferredUpdates.clear(); } /** diff --git a/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts b/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts index c90379b07042..1bd28e5e4d92 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts @@ -13,7 +13,7 @@ let deferredUpdates: DeferredUpdatesDictionary = {}; /** * Manually processes and applies the updates from the deferred updates queue. (used e.g. for push notifications) */ -function processDeferredUpdates() { +function process() { if (GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise) { GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise.finally(() => OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates); } @@ -28,7 +28,7 @@ function processDeferredUpdates() { * @param shouldProcessUpdates Whether the updates should be processed immediately * @returns */ -function enqueueDeferredUpdates(updates: OnyxUpdatesFromServer[], shouldProcessUpdates = true) { +function enqueue(updates: OnyxUpdatesFromServer[], shouldProcessUpdates = true) { SequentialQueue.pause(); updates.forEach((update) => { @@ -44,14 +44,14 @@ function enqueueDeferredUpdates(updates: OnyxUpdatesFromServer[], shouldProcessU return; } - processDeferredUpdates(); + process(); } /** * Clears the deferred updates queue and unpauses the SequentialQueue * @param shouldUnpauseSequentialQueue Whether the SequentialQueue should be unpaused after clearing the deferred updates */ -function clearDeferredUpdates(shouldUnpauseSequentialQueue = true) { +function clear(shouldUnpauseSequentialQueue = true) { GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise = undefined; deferredUpdates = {}; @@ -63,6 +63,6 @@ function clearDeferredUpdates(shouldUnpauseSequentialQueue = true) { SequentialQueue.unpause(); } -const DeferredUpdates = {deferredUpdates, enqueueDeferredUpdates, clearDeferredUpdates, processDeferredUpdates}; +const DeferredUpdates = {deferredUpdates, enqueue, clear, process}; export default createProxyForObject(DeferredUpdates); From 340125ee7f5c1d136854afe8fa41951acedf85df Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 May 2024 23:12:08 +0200 Subject: [PATCH 10/20] restructure --- src/libs/actions/OnyxUpdateManager/index.ts | 19 ++- .../utils/DeferredUpdates.ts | 112 +++++++++++++----- .../utils/GetMissingOnyxUpdatesPromise.ts | 6 - .../actions/OnyxUpdateManager/utils/index.ts | 12 +- 4 files changed, 96 insertions(+), 53 deletions(-) delete mode 100644 src/libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise.ts diff --git a/src/libs/actions/OnyxUpdateManager/index.ts b/src/libs/actions/OnyxUpdateManager/index.ts index 37fc1ebe523b..6a8b8d377ffb 100644 --- a/src/libs/actions/OnyxUpdateManager/index.ts +++ b/src/libs/actions/OnyxUpdateManager/index.ts @@ -9,7 +9,6 @@ import type {OnyxUpdatesFromServer} from '@src/types/onyx'; import {isValidOnyxUpdateFromServer} from '@src/types/onyx/OnyxUpdatesFromServer'; import * as OnyxUpdateManagerUtils from './utils'; import DeferredUpdates from './utils/DeferredUpdates'; -import GetMissingOnyxUpdatesPromiseProxy from './utils/GetMissingOnyxUpdatesPromise'; // This file is in charge of looking at the updateIDs coming from the server and comparing them to the last updateID that the client has. // If the client is behind the server, then we need to @@ -49,8 +48,7 @@ const createQueryPromiseWrapper = () => let queryPromiseWrapper = createQueryPromiseWrapper(); const resetDeferralLogicVariables = () => { - GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise = undefined; - DeferredUpdates.deferredUpdates = {}; + DeferredUpdates.clear({shouldUnpauseSequentialQueue: false}); }; // This function will reset the query variables, unpause the SequentialQueue and log an info to the user. @@ -108,22 +106,21 @@ function handleOnyxUpdateGap(onyxUpdatesFromServer: OnyxEntry 0) { @@ -139,12 +136,12 @@ function handleOnyxUpdateGap(onyxUpdatesFromServer: OnyxEntry - OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(clientLastUpdateID), + DeferredUpdates.setFetchMissingOnyxUpdatesPromise( + App.getMissingOnyxUpdates(lastUpdateIDFromClient, previousUpdateIDFromServer).then(() => OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(clientLastUpdateID)), ); } - GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise.finally(finalizeUpdatesAndResumeQueue); + DeferredUpdates.getFetchMissingOnyxUpdatesPromise()?.finally(finalizeUpdatesAndResumeQueue); } export default () => { diff --git a/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts b/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts index 1bd28e5e4d92..4640b6e49c83 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts @@ -2,25 +2,72 @@ import Onyx from 'react-native-onyx'; import type {DeferredUpdatesDictionary} from '@libs/actions/OnyxUpdateManager/types'; import * as SequentialQueue from '@libs/Network/SequentialQueue'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {OnyxUpdatesFromServer} from '@src/types/onyx'; -import createProxyForObject from '@src/utils/createProxyForObject'; +import type {OnyxUpdatesFromServer, Response} from '@src/types/onyx'; +import {isValidOnyxUpdateFromServer} from '@src/types/onyx/OnyxUpdatesFromServer'; // eslint-disable-next-line import/no-cycle import * as OnyxUpdateManagerUtils from '.'; -import GetMissingOnyxUpdatesPromiseProxy from './GetMissingOnyxUpdatesPromise'; +let fetchMissingOnyxUpdatesPromise: Promise | undefined; let deferredUpdates: DeferredUpdatesDictionary = {}; +/** + * Returns the promise that fetches the missing onyx updates + * @returns the promise + */ +function getFetchMissingOnyxUpdatesPromise() { + return fetchMissingOnyxUpdatesPromise; +} + +/** + * Sets the promise in which the missing onyx updates are being fetched + */ +function setFetchMissingOnyxUpdatesPromise(promise: Promise) { + fetchMissingOnyxUpdatesPromise = promise; +} + +/** + * Returns the deferred updates that are currently in the queue + * @param minUpdateID An optional minimum update ID to filter the deferred updates by + * @returns + */ +function getUpdates(minUpdateID?: number) { + if (minUpdateID == null) { + return deferredUpdates; + } + + return Object.entries(deferredUpdates).reduce( + (accUpdates, [lastUpdateID, update]) => ({ + ...accUpdates, + ...(Number(lastUpdateID) > minUpdateID ? {[Number(lastUpdateID)]: update} : {}), + }), + {}, + ); +} + +/** + * Get the number of deferred updates before adding the new one + * @returns the count of deferred updates in the queue + */ +function getCount() { + return Object.keys(deferredUpdates).length; +} + /** * Manually processes and applies the updates from the deferred updates queue. (used e.g. for push notifications) */ function process() { - if (GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise) { - GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise.finally(() => OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates); + if (fetchMissingOnyxUpdatesPromise) { + fetchMissingOnyxUpdatesPromise.finally(() => OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates); } - GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise = OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(); + fetchMissingOnyxUpdatesPromise = OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(); } +type EnqueueDeferredUpdatesOptions = { + shouldProcessUpdates?: boolean; + shouldPauseSequentialQueue?: boolean; +}; + /** * Allows adding onyx updates to the deferred updates queue manually. * By default, this will automatically process the updates. Setting "shouldProcessUpdates" to false will prevent this. @@ -28,41 +75,52 @@ function process() { * @param shouldProcessUpdates Whether the updates should be processed immediately * @returns */ -function enqueue(updates: OnyxUpdatesFromServer[], shouldProcessUpdates = true) { - SequentialQueue.pause(); - - updates.forEach((update) => { - const lastUpdateID = Number(update.lastUpdateID); - if (deferredUpdates[lastUpdateID]) { - return; - } +function enqueue(updates: OnyxUpdatesFromServer | DeferredUpdatesDictionary, options?: EnqueueDeferredUpdatesOptions) { + if (options?.shouldPauseSequentialQueue ?? true) { + SequentialQueue.pause(); + } - deferredUpdates[lastUpdateID] = update; - }); + if (isValidOnyxUpdateFromServer(updates)) { + const lastUpdateID = Number(updates.lastUpdateID); + deferredUpdates[lastUpdateID] = updates; + } else { + Object.entries(updates).forEach(([lastUpdateIDString, update]) => { + const lastUpdateID = Number(lastUpdateIDString); + if (deferredUpdates[lastUpdateID]) { + return; + } - if (!shouldProcessUpdates) { - return; + deferredUpdates[lastUpdateID] = update; + }); } - process(); + if (options?.shouldProcessUpdates ?? true) { + process(); + } } +type ClearDeferredUpdatesOptions = { + shouldResetGetMissingOnyxUpdatesPromise?: boolean; + shouldUnpauseSequentialQueue?: boolean; +}; + /** * Clears the deferred updates queue and unpauses the SequentialQueue * @param shouldUnpauseSequentialQueue Whether the SequentialQueue should be unpaused after clearing the deferred updates */ -function clear(shouldUnpauseSequentialQueue = true) { - GetMissingOnyxUpdatesPromiseProxy.GetMissingOnyxUpdatesPromise = undefined; +function clear(options?: ClearDeferredUpdatesOptions) { deferredUpdates = {}; - if (!shouldUnpauseSequentialQueue) { - return; + if (options?.shouldResetGetMissingOnyxUpdatesPromise ?? true) { + fetchMissingOnyxUpdatesPromise = undefined; } - Onyx.set(ONYXKEYS.ONYX_UPDATES_FROM_SERVER, null); - SequentialQueue.unpause(); + if (options?.shouldUnpauseSequentialQueue ?? true) { + Onyx.set(ONYXKEYS.ONYX_UPDATES_FROM_SERVER, null); + SequentialQueue.unpause(); + } } -const DeferredUpdates = {deferredUpdates, enqueue, clear, process}; +const DeferredUpdates = {getFetchMissingOnyxUpdatesPromise, setFetchMissingOnyxUpdatesPromise, getUpdates, getCount, enqueue, clear, process}; -export default createProxyForObject(DeferredUpdates); +export default DeferredUpdates; diff --git a/src/libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise.ts b/src/libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise.ts deleted file mode 100644 index a15c787c17d7..000000000000 --- a/src/libs/actions/OnyxUpdateManager/utils/GetMissingOnyxUpdatesPromise.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type {Response} from '@src/types/onyx'; -import createProxyForObject from '@src/utils/createProxyForObject'; - -const GetMissingOnyxUpdatesPromiseValue = {GetMissingOnyxUpdatesPromise: undefined as Promise | undefined}; - -export default createProxyForObject(GetMissingOnyxUpdatesPromiseValue); diff --git a/src/libs/actions/OnyxUpdateManager/utils/index.ts b/src/libs/actions/OnyxUpdateManager/utils/index.ts index a8ebd2b6ae04..0820b1928870 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/index.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/index.ts @@ -91,13 +91,7 @@ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number, previousPa // We only want to apply deferred updates that are newer than the last update that was applied to the client. // At this point, the missing updates from "GetMissingOnyxUpdates" have been applied already, so we can safely filter out. - const pendingDeferredUpdates = Object.entries(DeferredUpdates.deferredUpdates).reduce( - (accUpdates, [lastUpdateID, update]) => ({ - ...accUpdates, - ...(Number(lastUpdateID) > lastUpdateIDFromClient ? {[Number(lastUpdateID)]: update} : {}), - }), - {}, - ); + const pendingDeferredUpdates = DeferredUpdates.getUpdates(lastUpdateIDFromClient); // If there are no remaining deferred updates after filtering out outdated ones, // we can just unpause the queue and return @@ -113,7 +107,7 @@ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number, previousPa Log.info('[DeferredUpdates] Gap detected in deferred updates', false, {lastUpdateIDFromClient, latestMissingUpdateID}); return new Promise((resolve, reject) => { - DeferredUpdates.deferredUpdates = {}; + DeferredUpdates.clear({shouldUnpauseSequentialQueue: false, shouldResetGetMissingOnyxUpdatesPromise: false}); applyUpdates(applicableUpdates).then(() => { // After we have applied the applicable updates, there might have been new deferred updates added. @@ -123,7 +117,7 @@ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number, previousPa const newLastUpdateIDFromClient = clientLastUpdateID ?? lastUpdateIDAppliedToClient ?? 0; - DeferredUpdates.deferredUpdates = {...DeferredUpdates.deferredUpdates, ...updatesAfterGaps}; + DeferredUpdates.enqueue(updatesAfterGaps, {shouldProcessUpdates: false, shouldPauseSequentialQueue: false}); // If lastUpdateIDAppliedToClient got updated in the meantime, we will just retrigger the validation and application of the current deferred updates. if (latestMissingUpdateID <= newLastUpdateIDFromClient) { From 0455e0def3cd42ae32637033bd279c8d2f8c71c5 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 May 2024 23:12:21 +0200 Subject: [PATCH 11/20] rename --- .../actions/OnyxUpdateManager/utils/{DeferredUpdates.ts => s.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/libs/actions/OnyxUpdateManager/utils/{DeferredUpdates.ts => s.ts} (100%) diff --git a/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts b/src/libs/actions/OnyxUpdateManager/utils/s.ts similarity index 100% rename from src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts rename to src/libs/actions/OnyxUpdateManager/utils/s.ts From 6f7436ac4e97c4053042e3bbdb5737e11ee818e9 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 May 2024 23:12:38 +0200 Subject: [PATCH 12/20] rename --- .../actions/OnyxUpdateManager/utils/{s.ts => DeferredUpdates.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/libs/actions/OnyxUpdateManager/utils/{s.ts => DeferredUpdates.ts} (100%) diff --git a/src/libs/actions/OnyxUpdateManager/utils/s.ts b/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts similarity index 100% rename from src/libs/actions/OnyxUpdateManager/utils/s.ts rename to src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts From da8b8bafe66f80c75fb91f9b4e2e2ea82d0ad288 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 May 2024 23:15:29 +0200 Subject: [PATCH 13/20] change functions --- src/libs/actions/OnyxUpdateManager/index.ts | 4 ++-- .../actions/OnyxUpdateManager/utils/DeferredUpdates.ts | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libs/actions/OnyxUpdateManager/index.ts b/src/libs/actions/OnyxUpdateManager/index.ts index 6a8b8d377ffb..b00138f9a707 100644 --- a/src/libs/actions/OnyxUpdateManager/index.ts +++ b/src/libs/actions/OnyxUpdateManager/index.ts @@ -117,13 +117,13 @@ function handleOnyxUpdateGap(onyxUpdatesFromServer: OnyxEntry 0) { + if (areDeferredUpdatesQueued) { return; } diff --git a/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts b/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts index 4640b6e49c83..61164ece0fcd 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts @@ -45,11 +45,11 @@ function getUpdates(minUpdateID?: number) { } /** - * Get the number of deferred updates before adding the new one - * @returns the count of deferred updates in the queue + * Returns a boolean indicating whether the deferred updates queue is empty + * @returns a boolean indicating whether the deferred updates queue is empty */ -function getCount() { - return Object.keys(deferredUpdates).length; +function isEmpty() { + return Object.keys(deferredUpdates).length === 0; } /** @@ -121,6 +121,6 @@ function clear(options?: ClearDeferredUpdatesOptions) { } } -const DeferredUpdates = {getFetchMissingOnyxUpdatesPromise, setFetchMissingOnyxUpdatesPromise, getUpdates, getCount, enqueue, clear, process}; +const DeferredUpdates = {getFetchMissingOnyxUpdatesPromise, setFetchMissingOnyxUpdatesPromise, getUpdates, isEmpty, enqueue, clear, process}; export default DeferredUpdates; From e42703479d51baec9fc752eda56e592e9dc3da69 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Wed, 15 May 2024 11:47:56 +0200 Subject: [PATCH 14/20] rename file --- src/libs/actions/OnyxUpdateManager/index.ts | 18 +++++++++--------- ...ferredUpdates.ts => DeferredOnyxUpdates.ts} | 12 ++++++------ .../actions/OnyxUpdateManager/utils/index.ts | 8 ++++---- 3 files changed, 19 insertions(+), 19 deletions(-) rename src/libs/actions/OnyxUpdateManager/utils/{DeferredUpdates.ts => DeferredOnyxUpdates.ts} (91%) diff --git a/src/libs/actions/OnyxUpdateManager/index.ts b/src/libs/actions/OnyxUpdateManager/index.ts index b00138f9a707..6802a20ab4fa 100644 --- a/src/libs/actions/OnyxUpdateManager/index.ts +++ b/src/libs/actions/OnyxUpdateManager/index.ts @@ -8,7 +8,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {OnyxUpdatesFromServer} from '@src/types/onyx'; import {isValidOnyxUpdateFromServer} from '@src/types/onyx/OnyxUpdatesFromServer'; import * as OnyxUpdateManagerUtils from './utils'; -import DeferredUpdates from './utils/DeferredUpdates'; +import DeferredOnyxUpdates from './utils/DeferredOnyxUpdates'; // This file is in charge of looking at the updateIDs coming from the server and comparing them to the last updateID that the client has. // If the client is behind the server, then we need to @@ -48,7 +48,7 @@ const createQueryPromiseWrapper = () => let queryPromiseWrapper = createQueryPromiseWrapper(); const resetDeferralLogicVariables = () => { - DeferredUpdates.clear({shouldUnpauseSequentialQueue: false}); + DeferredOnyxUpdates.clear({shouldUnpauseSequentialQueue: false}); }; // This function will reset the query variables, unpause the SequentialQueue and log an info to the user. @@ -58,7 +58,7 @@ function finalizeUpdatesAndResumeQueue() { resolveQueryPromiseWrapper(); queryPromiseWrapper = createQueryPromiseWrapper(); - DeferredUpdates.clear(); + DeferredOnyxUpdates.clear(); } /** @@ -106,21 +106,21 @@ function handleOnyxUpdateGap(onyxUpdatesFromServer: OnyxEntry OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(clientLastUpdateID)), ); } - DeferredUpdates.getFetchMissingOnyxUpdatesPromise()?.finally(finalizeUpdatesAndResumeQueue); + DeferredOnyxUpdates.getFetchMissingOnyxUpdatesPromise()?.finally(finalizeUpdatesAndResumeQueue); } export default () => { diff --git a/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts b/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts similarity index 91% rename from src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts rename to src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts index 61164ece0fcd..5f3e94dedfae 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/DeferredUpdates.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts @@ -63,7 +63,7 @@ function process() { fetchMissingOnyxUpdatesPromise = OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(); } -type EnqueueDeferredUpdatesOptions = { +type EnqueueDeferredOnyxUpdatesOptions = { shouldProcessUpdates?: boolean; shouldPauseSequentialQueue?: boolean; }; @@ -75,7 +75,7 @@ type EnqueueDeferredUpdatesOptions = { * @param shouldProcessUpdates Whether the updates should be processed immediately * @returns */ -function enqueue(updates: OnyxUpdatesFromServer | DeferredUpdatesDictionary, options?: EnqueueDeferredUpdatesOptions) { +function enqueue(updates: OnyxUpdatesFromServer | DeferredUpdatesDictionary, options?: EnqueueDeferredOnyxUpdatesOptions) { if (options?.shouldPauseSequentialQueue ?? true) { SequentialQueue.pause(); } @@ -99,7 +99,7 @@ function enqueue(updates: OnyxUpdatesFromServer | DeferredUpdatesDictionary, opt } } -type ClearDeferredUpdatesOptions = { +type ClearDeferredOnyxUpdatesOptions = { shouldResetGetMissingOnyxUpdatesPromise?: boolean; shouldUnpauseSequentialQueue?: boolean; }; @@ -108,7 +108,7 @@ type ClearDeferredUpdatesOptions = { * Clears the deferred updates queue and unpauses the SequentialQueue * @param shouldUnpauseSequentialQueue Whether the SequentialQueue should be unpaused after clearing the deferred updates */ -function clear(options?: ClearDeferredUpdatesOptions) { +function clear(options?: ClearDeferredOnyxUpdatesOptions) { deferredUpdates = {}; if (options?.shouldResetGetMissingOnyxUpdatesPromise ?? true) { @@ -121,6 +121,6 @@ function clear(options?: ClearDeferredUpdatesOptions) { } } -const DeferredUpdates = {getFetchMissingOnyxUpdatesPromise, setFetchMissingOnyxUpdatesPromise, getUpdates, isEmpty, enqueue, clear, process}; +const DeferredOnyxUpdates = {getFetchMissingOnyxUpdatesPromise, setFetchMissingOnyxUpdatesPromise, getUpdates, isEmpty, enqueue, clear, process}; -export default DeferredUpdates; +export default DeferredOnyxUpdates; diff --git a/src/libs/actions/OnyxUpdateManager/utils/index.ts b/src/libs/actions/OnyxUpdateManager/utils/index.ts index 0820b1928870..1ab8b67511f2 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/index.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/index.ts @@ -5,7 +5,7 @@ import type {DeferredUpdatesDictionary, DetectGapAndSplitResult} from '@userActi import ONYXKEYS from '@src/ONYXKEYS'; import {applyUpdates} from './applyUpdates'; // eslint-disable-next-line import/no-cycle -import DeferredUpdates from './DeferredUpdates'; +import DeferredOnyxUpdates from './DeferredOnyxUpdates'; let lastUpdateIDAppliedToClient = 0; Onyx.connect({ @@ -91,7 +91,7 @@ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number, previousPa // We only want to apply deferred updates that are newer than the last update that was applied to the client. // At this point, the missing updates from "GetMissingOnyxUpdates" have been applied already, so we can safely filter out. - const pendingDeferredUpdates = DeferredUpdates.getUpdates(lastUpdateIDFromClient); + const pendingDeferredUpdates = DeferredOnyxUpdates.getUpdates(lastUpdateIDFromClient); // If there are no remaining deferred updates after filtering out outdated ones, // we can just unpause the queue and return @@ -107,7 +107,7 @@ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number, previousPa Log.info('[DeferredUpdates] Gap detected in deferred updates', false, {lastUpdateIDFromClient, latestMissingUpdateID}); return new Promise((resolve, reject) => { - DeferredUpdates.clear({shouldUnpauseSequentialQueue: false, shouldResetGetMissingOnyxUpdatesPromise: false}); + DeferredOnyxUpdates.clear({shouldUnpauseSequentialQueue: false, shouldResetGetMissingOnyxUpdatesPromise: false}); applyUpdates(applicableUpdates).then(() => { // After we have applied the applicable updates, there might have been new deferred updates added. @@ -117,7 +117,7 @@ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number, previousPa const newLastUpdateIDFromClient = clientLastUpdateID ?? lastUpdateIDAppliedToClient ?? 0; - DeferredUpdates.enqueue(updatesAfterGaps, {shouldProcessUpdates: false, shouldPauseSequentialQueue: false}); + DeferredOnyxUpdates.enqueue(updatesAfterGaps, {shouldProcessUpdates: false, shouldPauseSequentialQueue: false}); // If lastUpdateIDAppliedToClient got updated in the meantime, we will just retrigger the validation and application of the current deferred updates. if (latestMissingUpdateID <= newLastUpdateIDFromClient) { From 4379a0ad303998a57b3c4935b558ee2981860b71 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Wed, 15 May 2024 11:49:58 +0200 Subject: [PATCH 15/20] rename functions --- src/libs/actions/OnyxUpdateManager/index.ts | 8 +++---- .../utils/DeferredOnyxUpdates.ts | 22 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/libs/actions/OnyxUpdateManager/index.ts b/src/libs/actions/OnyxUpdateManager/index.ts index 6802a20ab4fa..b15b44663922 100644 --- a/src/libs/actions/OnyxUpdateManager/index.ts +++ b/src/libs/actions/OnyxUpdateManager/index.ts @@ -106,14 +106,14 @@ function handleOnyxUpdateGap(onyxUpdatesFromServer: OnyxEntry OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(clientLastUpdateID)), ); } - DeferredOnyxUpdates.getFetchMissingOnyxUpdatesPromise()?.finally(finalizeUpdatesAndResumeQueue); + DeferredOnyxUpdates.getMissingOnyxUpdatesQueryPromise()?.finally(finalizeUpdatesAndResumeQueue); } export default () => { diff --git a/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts b/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts index 5f3e94dedfae..2d1eeeec8804 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts @@ -7,22 +7,22 @@ import {isValidOnyxUpdateFromServer} from '@src/types/onyx/OnyxUpdatesFromServer // eslint-disable-next-line import/no-cycle import * as OnyxUpdateManagerUtils from '.'; -let fetchMissingOnyxUpdatesPromise: Promise | undefined; +let missingOnyxUpdatesQueryPromise: Promise | undefined; let deferredUpdates: DeferredUpdatesDictionary = {}; /** * Returns the promise that fetches the missing onyx updates * @returns the promise */ -function getFetchMissingOnyxUpdatesPromise() { - return fetchMissingOnyxUpdatesPromise; +function getMissingOnyxUpdatesQueryPromise() { + return missingOnyxUpdatesQueryPromise; } /** - * Sets the promise in which the missing onyx updates are being fetched + * Sets the promise that fetches the missing onyx updates */ -function setFetchMissingOnyxUpdatesPromise(promise: Promise) { - fetchMissingOnyxUpdatesPromise = promise; +function setMissingOnyxUpdatesQueryPromise(promise: Promise) { + missingOnyxUpdatesQueryPromise = promise; } /** @@ -56,11 +56,11 @@ function isEmpty() { * Manually processes and applies the updates from the deferred updates queue. (used e.g. for push notifications) */ function process() { - if (fetchMissingOnyxUpdatesPromise) { - fetchMissingOnyxUpdatesPromise.finally(() => OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates); + if (missingOnyxUpdatesQueryPromise) { + missingOnyxUpdatesQueryPromise.finally(() => OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates); } - fetchMissingOnyxUpdatesPromise = OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(); + missingOnyxUpdatesQueryPromise = OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates(); } type EnqueueDeferredOnyxUpdatesOptions = { @@ -112,7 +112,7 @@ function clear(options?: ClearDeferredOnyxUpdatesOptions) { deferredUpdates = {}; if (options?.shouldResetGetMissingOnyxUpdatesPromise ?? true) { - fetchMissingOnyxUpdatesPromise = undefined; + missingOnyxUpdatesQueryPromise = undefined; } if (options?.shouldUnpauseSequentialQueue ?? true) { @@ -121,6 +121,6 @@ function clear(options?: ClearDeferredOnyxUpdatesOptions) { } } -const DeferredOnyxUpdates = {getFetchMissingOnyxUpdatesPromise, setFetchMissingOnyxUpdatesPromise, getUpdates, isEmpty, enqueue, clear, process}; +const DeferredOnyxUpdates = {getMissingOnyxUpdatesQueryPromise, setMissingOnyxUpdatesQueryPromise, getUpdates, isEmpty, enqueue, clear, process}; export default DeferredOnyxUpdates; From 9df344c91610a8382b385851c2c644103cc163e0 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Wed, 15 May 2024 11:50:32 +0200 Subject: [PATCH 16/20] invert condition --- src/libs/actions/OnyxUpdateManager/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/OnyxUpdateManager/index.ts b/src/libs/actions/OnyxUpdateManager/index.ts index b15b44663922..9ac552075f0b 100644 --- a/src/libs/actions/OnyxUpdateManager/index.ts +++ b/src/libs/actions/OnyxUpdateManager/index.ts @@ -117,7 +117,7 @@ function handleOnyxUpdateGap(onyxUpdatesFromServer: OnyxEntry Date: Wed, 15 May 2024 12:07:17 +0200 Subject: [PATCH 17/20] fix: simplify function signatures --- src/libs/actions/OnyxUpdateManager/index.ts | 2 +- .../utils/DeferredOnyxUpdates.ts | 29 ++++++++++++------- .../actions/OnyxUpdateManager/utils/index.ts | 4 +-- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/libs/actions/OnyxUpdateManager/index.ts b/src/libs/actions/OnyxUpdateManager/index.ts index 9ac552075f0b..cbdee3ecd37c 100644 --- a/src/libs/actions/OnyxUpdateManager/index.ts +++ b/src/libs/actions/OnyxUpdateManager/index.ts @@ -120,7 +120,7 @@ function handleOnyxUpdateGap(onyxUpdatesFromServer: OnyxEntry( (accUpdates, [lastUpdateID, update]) => ({ ...accUpdates, - ...(Number(lastUpdateID) > minUpdateID ? {[Number(lastUpdateID)]: update} : {}), + ...(Number(lastUpdateID) > (options.minUpdateID ?? 0) ? {[Number(lastUpdateID)]: update} : {}), }), {}, ); @@ -64,7 +68,6 @@ function process() { } type EnqueueDeferredOnyxUpdatesOptions = { - shouldProcessUpdates?: boolean; shouldPauseSequentialQueue?: boolean; }; @@ -72,8 +75,7 @@ type EnqueueDeferredOnyxUpdatesOptions = { * Allows adding onyx updates to the deferred updates queue manually. * By default, this will automatically process the updates. Setting "shouldProcessUpdates" to false will prevent this. * @param updates The updates that should be applied (e.g. updates from push notifications) - * @param shouldProcessUpdates Whether the updates should be processed immediately - * @returns + * @param options additional flags to change the behaviour of this function */ function enqueue(updates: OnyxUpdatesFromServer | DeferredUpdatesDictionary, options?: EnqueueDeferredOnyxUpdatesOptions) { if (options?.shouldPauseSequentialQueue ?? true) { @@ -93,10 +95,15 @@ function enqueue(updates: OnyxUpdatesFromServer | DeferredUpdatesDictionary, opt deferredUpdates[lastUpdateID] = update; }); } +} - if (options?.shouldProcessUpdates ?? true) { - process(); - } +/** + * Adds updates to the deferred updates queue and processes them immediately + * @param updates The updates that should be applied (e.g. updates from push notifications) + */ +function enqueueAndProcess(updates: OnyxUpdatesFromServer | DeferredUpdatesDictionary, options?: EnqueueDeferredOnyxUpdatesOptions) { + enqueue(updates, options); + process(); } type ClearDeferredOnyxUpdatesOptions = { @@ -106,7 +113,7 @@ type ClearDeferredOnyxUpdatesOptions = { /** * Clears the deferred updates queue and unpauses the SequentialQueue - * @param shouldUnpauseSequentialQueue Whether the SequentialQueue should be unpaused after clearing the deferred updates + * @param options additional flags to change the behaviour of this function */ function clear(options?: ClearDeferredOnyxUpdatesOptions) { deferredUpdates = {}; @@ -121,6 +128,6 @@ function clear(options?: ClearDeferredOnyxUpdatesOptions) { } } -const DeferredOnyxUpdates = {getMissingOnyxUpdatesQueryPromise, setMissingOnyxUpdatesQueryPromise, getUpdates, isEmpty, enqueue, clear, process}; +const DeferredOnyxUpdates = {getMissingOnyxUpdatesQueryPromise, setMissingOnyxUpdatesQueryPromise, getUpdates, isEmpty, process, enqueue, enqueueAndProcess, clear}; export default DeferredOnyxUpdates; diff --git a/src/libs/actions/OnyxUpdateManager/utils/index.ts b/src/libs/actions/OnyxUpdateManager/utils/index.ts index 1ab8b67511f2..ac4f235bb142 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/index.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/index.ts @@ -91,7 +91,7 @@ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number, previousPa // We only want to apply deferred updates that are newer than the last update that was applied to the client. // At this point, the missing updates from "GetMissingOnyxUpdates" have been applied already, so we can safely filter out. - const pendingDeferredUpdates = DeferredOnyxUpdates.getUpdates(lastUpdateIDFromClient); + const pendingDeferredUpdates = DeferredOnyxUpdates.getUpdates({minUpdateID: lastUpdateIDFromClient}); // If there are no remaining deferred updates after filtering out outdated ones, // we can just unpause the queue and return @@ -117,7 +117,7 @@ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number, previousPa const newLastUpdateIDFromClient = clientLastUpdateID ?? lastUpdateIDAppliedToClient ?? 0; - DeferredOnyxUpdates.enqueue(updatesAfterGaps, {shouldProcessUpdates: false, shouldPauseSequentialQueue: false}); + DeferredOnyxUpdates.enqueue(updatesAfterGaps, {shouldPauseSequentialQueue: false}); // If lastUpdateIDAppliedToClient got updated in the meantime, we will just retrigger the validation and application of the current deferred updates. if (latestMissingUpdateID <= newLastUpdateIDFromClient) { From 15600b0d29b1bb745e0c2ea2cf7020bf6e240e96 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Wed, 15 May 2024 12:09:30 +0200 Subject: [PATCH 18/20] use non-default exports --- src/libs/actions/OnyxUpdateManager/index.ts | 2 +- .../actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts | 4 +--- src/libs/actions/OnyxUpdateManager/utils/index.ts | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/libs/actions/OnyxUpdateManager/index.ts b/src/libs/actions/OnyxUpdateManager/index.ts index cbdee3ecd37c..deb530547021 100644 --- a/src/libs/actions/OnyxUpdateManager/index.ts +++ b/src/libs/actions/OnyxUpdateManager/index.ts @@ -8,7 +8,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {OnyxUpdatesFromServer} from '@src/types/onyx'; import {isValidOnyxUpdateFromServer} from '@src/types/onyx/OnyxUpdatesFromServer'; import * as OnyxUpdateManagerUtils from './utils'; -import DeferredOnyxUpdates from './utils/DeferredOnyxUpdates'; +import * as DeferredOnyxUpdates from './utils/DeferredOnyxUpdates'; // This file is in charge of looking at the updateIDs coming from the server and comparing them to the last updateID that the client has. // If the client is behind the server, then we need to diff --git a/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts b/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts index d7fab10c58e1..c876df08d3fb 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts @@ -128,6 +128,4 @@ function clear(options?: ClearDeferredOnyxUpdatesOptions) { } } -const DeferredOnyxUpdates = {getMissingOnyxUpdatesQueryPromise, setMissingOnyxUpdatesQueryPromise, getUpdates, isEmpty, process, enqueue, enqueueAndProcess, clear}; - -export default DeferredOnyxUpdates; +export {getMissingOnyxUpdatesQueryPromise, setMissingOnyxUpdatesQueryPromise, getUpdates, isEmpty, process, enqueue, enqueueAndProcess, clear}; diff --git a/src/libs/actions/OnyxUpdateManager/utils/index.ts b/src/libs/actions/OnyxUpdateManager/utils/index.ts index ac4f235bb142..be062b1e0921 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/index.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/index.ts @@ -5,7 +5,7 @@ import type {DeferredUpdatesDictionary, DetectGapAndSplitResult} from '@userActi import ONYXKEYS from '@src/ONYXKEYS'; import {applyUpdates} from './applyUpdates'; // eslint-disable-next-line import/no-cycle -import DeferredOnyxUpdates from './DeferredOnyxUpdates'; +import * as DeferredOnyxUpdates from './DeferredOnyxUpdates'; let lastUpdateIDAppliedToClient = 0; Onyx.connect({ From ccedd1c5d7e1132539d0a4b68f8285045185a1b8 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Wed, 15 May 2024 12:12:36 +0200 Subject: [PATCH 19/20] add comment --- .../actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts b/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts index c876df08d3fb..d34f069a1d76 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts @@ -82,10 +82,13 @@ function enqueue(updates: OnyxUpdatesFromServer | DeferredUpdatesDictionary, opt SequentialQueue.pause(); } + // We check here if the "updates" param is a single update. + // If so, we only need to insert one update into the deferred updates queue. if (isValidOnyxUpdateFromServer(updates)) { const lastUpdateID = Number(updates.lastUpdateID); deferredUpdates[lastUpdateID] = updates; } else { + // If the "updates" param is an object, we need to insert multiple updates into the deferred updates queue. Object.entries(updates).forEach(([lastUpdateIDString, update]) => { const lastUpdateID = Number(lastUpdateIDString); if (deferredUpdates[lastUpdateID]) { From 342873e939ea4b93ed75c6f717526fd32ea10149 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Wed, 15 May 2024 17:00:38 +0200 Subject: [PATCH 20/20] Update DeferredOnyxUpdates.ts Co-authored-by: Andrew Rosiclair --- src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts b/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts index d34f069a1d76..451de2ed8a5c 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates.ts @@ -73,7 +73,6 @@ type EnqueueDeferredOnyxUpdatesOptions = { /** * Allows adding onyx updates to the deferred updates queue manually. - * By default, this will automatically process the updates. Setting "shouldProcessUpdates" to false will prevent this. * @param updates The updates that should be applied (e.g. updates from push notifications) * @param options additional flags to change the behaviour of this function */