From 0bc6d78133ed5dd4723e0fca150e3a307dcf5d38 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Thu, 27 Oct 2022 17:05:20 -0700 Subject: [PATCH 01/23] call process/finally before makeRequestWithSideEffects --- src/libs/API.js | 13 ++++++++++++- src/libs/Network/SequentialQueue.js | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/libs/API.js b/src/libs/API.js index 83b0dcd9d159..2ba7a3138f9c 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -4,6 +4,8 @@ import * as Request from './Request'; import * as SequentialQueue from './Network/SequentialQueue'; import pkg from '../../package.json'; import CONST from '../CONST'; +import ONYXKEYS from '../ONYXKEYS'; +import {process} from './Network/SequentialQueue'; /** * All calls to API.write() will be persisted to disk as JSON with the params, successData, and failureData. @@ -105,7 +107,16 @@ function makeRequestWithSideEffects(command, apiCommandParameters = {}, onyxData * @param {Object} [onyxData.failureData] - Onyx instructions that will be passed to Onyx.update() when the response has jsonCode !== 200. */ function read(command, apiCommandParameters, onyxData) { - makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ); + const connectionID = Onyx.connect({ + key: ONYXKEYS.PERSISTED_REQUESTS, + callback: () => { + Onyx.disconnect(connectionID); + process() + .finally(() => { + makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ); + }); + }, + }); } export { diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index fc670d118405..f3d52d0f78f7 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -18,6 +18,8 @@ let isSequentialQueueRunning = false; let currentRequest = null; + + /** * This method will get any persisted requests and fire them off in sequence to retry them. * @@ -115,6 +117,7 @@ function getCurrentRequest() { } export { + process, flush, getCurrentRequest, isRunning, From 99aa8e8b9c9d038c01a4ba316d6429cf8f5aa47e Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Thu, 27 Oct 2022 17:06:01 -0700 Subject: [PATCH 02/23] whitespace --- src/libs/Network/SequentialQueue.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index f3d52d0f78f7..38ae4826d6b1 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -18,8 +18,6 @@ let isSequentialQueueRunning = false; let currentRequest = null; - - /** * This method will get any persisted requests and fire them off in sequence to retry them. * From dca802b0e235db3c0c51f5d540b3d9cb40d57a1d Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 31 Oct 2022 12:23:04 -0700 Subject: [PATCH 03/23] wip --- src/libs/API.js | 15 +++------------ src/libs/Network/SequentialQueue.js | 18 +++++++++++++++--- .../reimburse/WorkspaceReimburseView.js | 2 ++ 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/libs/API.js b/src/libs/API.js index 2ba7a3138f9c..964bd807e0fa 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -4,8 +4,6 @@ import * as Request from './Request'; import * as SequentialQueue from './Network/SequentialQueue'; import pkg from '../../package.json'; import CONST from '../CONST'; -import ONYXKEYS from '../ONYXKEYS'; -import {process} from './Network/SequentialQueue'; /** * All calls to API.write() will be persisted to disk as JSON with the params, successData, and failureData. @@ -107,16 +105,9 @@ function makeRequestWithSideEffects(command, apiCommandParameters = {}, onyxData * @param {Object} [onyxData.failureData] - Onyx instructions that will be passed to Onyx.update() when the response has jsonCode !== 200. */ function read(command, apiCommandParameters, onyxData) { - const connectionID = Onyx.connect({ - key: ONYXKEYS.PERSISTED_REQUESTS, - callback: () => { - Onyx.disconnect(connectionID); - process() - .finally(() => { - makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ); - }); - }, - }); + console.log(">>>> in API.read for", command); + SequentialQueue.getActiveRun().then(() => makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ)); + // makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ) } export { diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index 38ae4826d6b1..2ec2cdeff2e1 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -18,6 +18,8 @@ let isSequentialQueueRunning = false; let currentRequest = null; +let activeRun = Promise.resolve(); + /** * This method will get any persisted requests and fire them off in sequence to retry them. * @@ -32,6 +34,7 @@ function process() { } const task = _.reduce(persistedRequests, (previousRequest, request) => previousRequest.then(() => { + console.log(">>>> retrying", request.command); currentRequest = Request.processWithMiddleware(request, true); return currentRequest; }), Promise.resolve()); @@ -42,13 +45,13 @@ function process() { function flush() { if (isSequentialQueueRunning) { - return; + return Promise.resolve(); } // ONYXKEYS.PERSISTED_REQUESTS is shared across clients, thus every client/tab will have a copy // It is very important to only process the queue from leader client otherwise requests will be duplicated. if (!ActiveClientManager.isClientTheLeader()) { - return; + return Promise.resolve(); } isSequentialQueueRunning = true; @@ -63,12 +66,15 @@ function flush() { key: ONYXKEYS.PERSISTED_REQUESTS, callback: () => { Onyx.disconnect(connectionID); - process() + + activeRun = process() .finally(() => { isSequentialQueueRunning = false; resolveIsReadyPromise(); currentRequest = null; + activeRun = Promise.resolve(); }); + console.log(">>>> set activeRun to be process.finally"); }, }); } @@ -114,10 +120,16 @@ function getCurrentRequest() { return currentRequest; } +function getActiveRun() { + console.log(">>>> getting active run, isSequentialQueueRunning:", isSequentialQueueRunning); + return activeRun; +} + export { process, flush, getCurrentRequest, isRunning, push, + getActiveRun, }; diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 8b6bf8ad7523..a7fb2e2a11a4 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -110,6 +110,8 @@ class WorkspaceReimburseView extends React.Component { return; } + console.log(">>>> componentDidUpdate: calling openWorkspaceReimburseView"); + Policy.openWorkspaceReimburseView(this.props.policy.id); } From 38553d8ba477d4ce93092bfd4b5622c6e1a72222 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 31 Oct 2022 13:21:49 -0700 Subject: [PATCH 04/23] wip, almost working --- src/libs/API.js | 4 +- src/libs/Middleware/SaveResponseInOnyx.js | 2 + src/libs/Network/SequentialQueue.js | 73 +++++++++++++++-------- src/libs/NetworkConnection.js | 6 +- 4 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/libs/API.js b/src/libs/API.js index 964bd807e0fa..09a280ff8410 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -4,6 +4,7 @@ import * as Request from './Request'; import * as SequentialQueue from './Network/SequentialQueue'; import pkg from '../../package.json'; import CONST from '../CONST'; +import {getIsDonePromise} from './Network/SequentialQueue'; /** * All calls to API.write() will be persisted to disk as JSON with the params, successData, and failureData. @@ -69,6 +70,7 @@ function write(command, apiCommandParameters = {}, onyxData = {}) { * @returns {Promise} */ function makeRequestWithSideEffects(command, apiCommandParameters = {}, onyxData = {}, apiRequestType = CONST.API_REQUEST_TYPE.MAKE_REQUEST_WITH_SIDE_EFFECTS) { + console.log(">>>>!!!! makeRequestWithSideEffects"); // Optimistically update Onyx if (onyxData.optimisticData) { Onyx.update(onyxData.optimisticData); @@ -106,7 +108,7 @@ function makeRequestWithSideEffects(command, apiCommandParameters = {}, onyxData */ function read(command, apiCommandParameters, onyxData) { console.log(">>>> in API.read for", command); - SequentialQueue.getActiveRun().then(() => makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ)); + SequentialQueue.getIsDonePromise().then(() => makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ)); // makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ) } diff --git a/src/libs/Middleware/SaveResponseInOnyx.js b/src/libs/Middleware/SaveResponseInOnyx.js index 2138ff91108c..95a3bf8a4ecf 100644 --- a/src/libs/Middleware/SaveResponseInOnyx.js +++ b/src/libs/Middleware/SaveResponseInOnyx.js @@ -11,6 +11,8 @@ function SaveResponseInOnyx(response, request) { .then((responseData) => { const onyxUpdates = []; + console.log(">>>> SaveResponseInOnyx for", request.command); + // Make sure we have response data (i.e. response isn't a promise being passed down to us by a failed retry request and responseData undefined) if (!responseData) { return; diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index 2ec2cdeff2e1..855a6b38faaa 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -18,7 +18,12 @@ let isSequentialQueueRunning = false; let currentRequest = null; -let activeRun = Promise.resolve(); +let resolveIsDonePromise; +let isDonePromise = new Promise((resolve) => { + resolveIsDonePromise = resolve; +}); + +let pendingRequests = []; /** * This method will get any persisted requests and fire them off in sequence to retry them. @@ -33,11 +38,14 @@ function process() { return Promise.resolve(); } - const task = _.reduce(persistedRequests, (previousRequest, request) => previousRequest.then(() => { - console.log(">>>> retrying", request.command); - currentRequest = Request.processWithMiddleware(request, true); - return currentRequest; - }), Promise.resolve()); + const task = _.reduce(persistedRequests, (previousRequest, request) => { + return previousRequest.then(() => { + console.log(">>>> retrying", request.command); + currentRequest = Request.processWithMiddleware(request, true); + pendingRequests.push(currentRequest); + return currentRequest; + }); + }, Promise.resolve()); // Do a recursive call in case the queue is not empty after processing the current batch return task.then(process); @@ -62,20 +70,30 @@ function flush() { }); // Ensure persistedRequests are read from storage before proceeding with the queue - const connectionID = Onyx.connect({ - key: ONYXKEYS.PERSISTED_REQUESTS, - callback: () => { - Onyx.disconnect(connectionID); - - activeRun = process() - .finally(() => { - isSequentialQueueRunning = false; - resolveIsReadyPromise(); - currentRequest = null; - activeRun = Promise.resolve(); - }); - console.log(">>>> set activeRun to be process.finally"); - }, + return new Promise((resolve) => { + const connectionID = Onyx.connect({ + key: ONYXKEYS.PERSISTED_REQUESTS, + callback: () => { + Onyx.disconnect(connectionID); + + process() + .finally(() => { + isSequentialQueueRunning = false; + resolve(); + resolveIsReadyPromise(); + currentRequest = null; + + + // Resolve the isDonePromise once all the pending requests complete, + // and reset the pendingRequests array + console.log(">>>> # of pendingRequests requests", pendingRequests.length); + Promise.all(pendingRequests).then(() => { + resolveIsDonePromise(); + pendingRequests = []; + }); + }); + }, + }); }); } @@ -120,9 +138,16 @@ function getCurrentRequest() { return currentRequest; } -function getActiveRun() { - console.log(">>>> getting active run, isSequentialQueueRunning:", isSequentialQueueRunning); - return activeRun; +function getIsDonePromise() { + console.log(">>>> getIsDonePromise, isSequentialQueueRunning:", isSequentialQueueRunning); + return isDonePromise.then(() => { + console.log(">>>> resetting isDonePromise"); + + // Reset the isDonePromise so we can use it again on the next run + isDonePromise = new Promise((resolve) => { + resolveIsDonePromise = resolve; + }); + }); } export { @@ -131,5 +156,5 @@ export { getCurrentRequest, isRunning, push, - getActiveRun, + getIsDonePromise, }; diff --git a/src/libs/NetworkConnection.js b/src/libs/NetworkConnection.js index 972c3dcd5179..5f133f777520 100644 --- a/src/libs/NetworkConnection.js +++ b/src/libs/NetworkConnection.js @@ -5,6 +5,7 @@ import Log from './Log'; import * as NetworkActions from './actions/Network'; import CONFIG from '../CONFIG'; import CONST from '../CONST'; +import * as SequentialQueue from './Network/SequentialQueue'; let isOffline = false; let hasPendingNetworkCheck = false; @@ -33,7 +34,10 @@ function setOfflineStatus(isCurrentlyOffline) { // When reconnecting, ie, going from offline to online, all the reconnection callbacks // are triggered (this is usually Actions that need to re-download data from the server) if (isOffline && !isCurrentlyOffline) { - triggerReconnectionCallbacks('offline status changed'); + SequentialQueue.flush().then(() => { + console.log(">>>> triggering reconnection callbacks"); + triggerReconnectionCallbacks('offline status changed'); + }); } isOffline = isCurrentlyOffline; From 826e2eaa9ccf06e61577c069213a6f421a86ad54 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 31 Oct 2022 13:27:41 -0700 Subject: [PATCH 05/23] working! --- src/libs/API.js | 2 - src/libs/Middleware/SaveResponseInOnyx.js | 2 - src/libs/Network/SequentialQueue.js | 76 +++++++++---------- src/libs/NetworkConnection.js | 5 +- .../reimburse/WorkspaceReimburseView.js | 2 - 5 files changed, 35 insertions(+), 52 deletions(-) diff --git a/src/libs/API.js b/src/libs/API.js index 09a280ff8410..9a5766d6e846 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -70,7 +70,6 @@ function write(command, apiCommandParameters = {}, onyxData = {}) { * @returns {Promise} */ function makeRequestWithSideEffects(command, apiCommandParameters = {}, onyxData = {}, apiRequestType = CONST.API_REQUEST_TYPE.MAKE_REQUEST_WITH_SIDE_EFFECTS) { - console.log(">>>>!!!! makeRequestWithSideEffects"); // Optimistically update Onyx if (onyxData.optimisticData) { Onyx.update(onyxData.optimisticData); @@ -107,7 +106,6 @@ function makeRequestWithSideEffects(command, apiCommandParameters = {}, onyxData * @param {Object} [onyxData.failureData] - Onyx instructions that will be passed to Onyx.update() when the response has jsonCode !== 200. */ function read(command, apiCommandParameters, onyxData) { - console.log(">>>> in API.read for", command); SequentialQueue.getIsDonePromise().then(() => makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ)); // makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ) } diff --git a/src/libs/Middleware/SaveResponseInOnyx.js b/src/libs/Middleware/SaveResponseInOnyx.js index 95a3bf8a4ecf..2138ff91108c 100644 --- a/src/libs/Middleware/SaveResponseInOnyx.js +++ b/src/libs/Middleware/SaveResponseInOnyx.js @@ -11,8 +11,6 @@ function SaveResponseInOnyx(response, request) { .then((responseData) => { const onyxUpdates = []; - console.log(">>>> SaveResponseInOnyx for", request.command); - // Make sure we have response data (i.e. response isn't a promise being passed down to us by a failed retry request and responseData undefined) if (!responseData) { return; diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index 855a6b38faaa..fbf7dbc9529b 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -38,14 +38,12 @@ function process() { return Promise.resolve(); } - const task = _.reduce(persistedRequests, (previousRequest, request) => { - return previousRequest.then(() => { - console.log(">>>> retrying", request.command); - currentRequest = Request.processWithMiddleware(request, true); - pendingRequests.push(currentRequest); - return currentRequest; - }); - }, Promise.resolve()); + const task = _.reduce(persistedRequests, (previousRequest, request) => previousRequest.then(() => { + console.log('>>>> retrying', request.command); + currentRequest = Request.processWithMiddleware(request, true); + pendingRequests.push(currentRequest); + return currentRequest; + }), Promise.resolve()); // Do a recursive call in case the queue is not empty after processing the current batch return task.then(process); @@ -53,13 +51,13 @@ function process() { function flush() { if (isSequentialQueueRunning) { - return Promise.resolve(); + return; } // ONYXKEYS.PERSISTED_REQUESTS is shared across clients, thus every client/tab will have a copy // It is very important to only process the queue from leader client otherwise requests will be duplicated. if (!ActiveClientManager.isClientTheLeader()) { - return Promise.resolve(); + return; } isSequentialQueueRunning = true; @@ -70,30 +68,31 @@ function flush() { }); // Ensure persistedRequests are read from storage before proceeding with the queue - return new Promise((resolve) => { - const connectionID = Onyx.connect({ - key: ONYXKEYS.PERSISTED_REQUESTS, - callback: () => { - Onyx.disconnect(connectionID); - - process() - .finally(() => { - isSequentialQueueRunning = false; - resolve(); - resolveIsReadyPromise(); - currentRequest = null; - - - // Resolve the isDonePromise once all the pending requests complete, - // and reset the pendingRequests array - console.log(">>>> # of pendingRequests requests", pendingRequests.length); - Promise.all(pendingRequests).then(() => { - resolveIsDonePromise(); - pendingRequests = []; - }); + const connectionID = Onyx.connect({ + key: ONYXKEYS.PERSISTED_REQUESTS, + callback: () => { + Onyx.disconnect(connectionID); + + process() + .finally(() => { + isSequentialQueueRunning = false; + resolveIsReadyPromise(); + currentRequest = null; + + // Resolve the isDonePromise once all the pending requests complete, + // and reset the pendingRequests array + Promise.all(pendingRequests).then(() => { + resolveIsDonePromise(); + pendingRequests = []; + }); + }).then(() => { + // Reset the isDonePromise so we can use it again on the next run, + // this has to be done after the finally runs otherwise it'll have no effect + isDonePromise = new Promise((resolve) => { + resolveIsDonePromise = resolve; }); - }, - }); + }); + }, }); } @@ -139,15 +138,8 @@ function getCurrentRequest() { } function getIsDonePromise() { - console.log(">>>> getIsDonePromise, isSequentialQueueRunning:", isSequentialQueueRunning); - return isDonePromise.then(() => { - console.log(">>>> resetting isDonePromise"); - - // Reset the isDonePromise so we can use it again on the next run - isDonePromise = new Promise((resolve) => { - resolveIsDonePromise = resolve; - }); - }); + console.log('>>>> getIsDonePromise, isSequentialQueueRunning:', isSequentialQueueRunning); + return isDonePromise; } export { diff --git a/src/libs/NetworkConnection.js b/src/libs/NetworkConnection.js index 5f133f777520..ffbaa4266753 100644 --- a/src/libs/NetworkConnection.js +++ b/src/libs/NetworkConnection.js @@ -34,10 +34,7 @@ function setOfflineStatus(isCurrentlyOffline) { // When reconnecting, ie, going from offline to online, all the reconnection callbacks // are triggered (this is usually Actions that need to re-download data from the server) if (isOffline && !isCurrentlyOffline) { - SequentialQueue.flush().then(() => { - console.log(">>>> triggering reconnection callbacks"); - triggerReconnectionCallbacks('offline status changed'); - }); + triggerReconnectionCallbacks('offline status changed'); } isOffline = isCurrentlyOffline; diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index a7fb2e2a11a4..8b6bf8ad7523 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -110,8 +110,6 @@ class WorkspaceReimburseView extends React.Component { return; } - console.log(">>>> componentDidUpdate: calling openWorkspaceReimburseView"); - Policy.openWorkspaceReimburseView(this.props.policy.id); } From a7bd2b8f3dd66310b5a7c9f67b6b21ba9b5ed8a2 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 31 Oct 2022 13:33:20 -0700 Subject: [PATCH 06/23] remove unused and fix style --- src/libs/API.js | 4 +--- src/libs/Network/SequentialQueue.js | 2 -- src/libs/NetworkConnection.js | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/libs/API.js b/src/libs/API.js index 9a5766d6e846..00053a4f9220 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -1,10 +1,9 @@ import _ from 'underscore'; import Onyx from 'react-native-onyx'; import * as Request from './Request'; -import * as SequentialQueue from './Network/SequentialQueue'; import pkg from '../../package.json'; import CONST from '../CONST'; -import {getIsDonePromise} from './Network/SequentialQueue'; +import * as SequentialQueue from './Network/SequentialQueue'; /** * All calls to API.write() will be persisted to disk as JSON with the params, successData, and failureData. @@ -107,7 +106,6 @@ function makeRequestWithSideEffects(command, apiCommandParameters = {}, onyxData */ function read(command, apiCommandParameters, onyxData) { SequentialQueue.getIsDonePromise().then(() => makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ)); - // makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ) } export { diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index fbf7dbc9529b..422baa1ffc87 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -39,7 +39,6 @@ function process() { } const task = _.reduce(persistedRequests, (previousRequest, request) => previousRequest.then(() => { - console.log('>>>> retrying', request.command); currentRequest = Request.processWithMiddleware(request, true); pendingRequests.push(currentRequest); return currentRequest; @@ -138,7 +137,6 @@ function getCurrentRequest() { } function getIsDonePromise() { - console.log('>>>> getIsDonePromise, isSequentialQueueRunning:', isSequentialQueueRunning); return isDonePromise; } diff --git a/src/libs/NetworkConnection.js b/src/libs/NetworkConnection.js index ffbaa4266753..972c3dcd5179 100644 --- a/src/libs/NetworkConnection.js +++ b/src/libs/NetworkConnection.js @@ -5,7 +5,6 @@ import Log from './Log'; import * as NetworkActions from './actions/Network'; import CONFIG from '../CONFIG'; import CONST from '../CONST'; -import * as SequentialQueue from './Network/SequentialQueue'; let isOffline = false; let hasPendingNetworkCheck = false; From e84e2f5feb24499160448961967740641873f5a1 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 31 Oct 2022 13:34:06 -0700 Subject: [PATCH 07/23] whitespace --- src/libs/Network/SequentialQueue.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index 422baa1ffc87..c59f8a5b9a0b 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -71,7 +71,6 @@ function flush() { key: ONYXKEYS.PERSISTED_REQUESTS, callback: () => { Onyx.disconnect(connectionID); - process() .finally(() => { isSequentialQueueRunning = false; From 8e0453db5050e40c9b9d4dfe2d3d14973ec93f91 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 31 Oct 2022 13:34:39 -0700 Subject: [PATCH 08/23] remove unused --- src/libs/Network/SequentialQueue.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index c59f8a5b9a0b..950d7975a744 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -140,7 +140,6 @@ function getIsDonePromise() { } export { - process, flush, getCurrentRequest, isRunning, From 6de781d9dce5b3a8462f1abb433bcb3e712bc1be Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 31 Oct 2022 13:45:30 -0700 Subject: [PATCH 09/23] only use the isDonePromise if the SequentialQueue is running --- src/libs/Network/SequentialQueue.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index 950d7975a744..6b63a0141a93 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -136,7 +136,11 @@ function getCurrentRequest() { } function getIsDonePromise() { - return isDonePromise; + if (isSequentialQueueRunning) { + return isDonePromise; + } + + return Promise.resolve(); } export { From 47148652638699626eced28a78c83f514e89c24a Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 31 Oct 2022 13:46:34 -0700 Subject: [PATCH 10/23] fix early return to be more readable --- src/libs/Network/SequentialQueue.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index 6b63a0141a93..ef0de2134f71 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -136,11 +136,11 @@ function getCurrentRequest() { } function getIsDonePromise() { - if (isSequentialQueueRunning) { - return isDonePromise; + if (!isSequentialQueueRunning) { + return Promise.resolve(); } - return Promise.resolve(); + return isDonePromise; } export { From e03b3eedb6ec62ab926a7b296d2cf50b418d59f8 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 31 Oct 2022 13:46:46 -0700 Subject: [PATCH 11/23] whitespace --- src/libs/Network/SequentialQueue.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index ef0de2134f71..90db8e438ba1 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -139,7 +139,6 @@ function getIsDonePromise() { if (!isSequentialQueueRunning) { return Promise.resolve(); } - return isDonePromise; } From 005240398e3a43328a07ce8791825fd415d4459f Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 31 Oct 2022 13:47:40 -0700 Subject: [PATCH 12/23] remove unused --- src/libs/API.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/API.js b/src/libs/API.js index 00053a4f9220..a4ad78b65c15 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Onyx from 'react-native-onyx'; import * as Request from './Request'; +import * as SequentialQueue from './Network/SequentialQueue'; import pkg from '../../package.json'; import CONST from '../CONST'; -import * as SequentialQueue from './Network/SequentialQueue'; /** * All calls to API.write() will be persisted to disk as JSON with the params, successData, and failureData. From 417e5fe75f85917c58ed6577715b99d396a12661 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 2 Nov 2022 07:23:07 -0700 Subject: [PATCH 13/23] use single promise --- src/libs/API.js | 2 +- src/libs/Network/SequentialQueue.js | 29 ++++------------------------- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/src/libs/API.js b/src/libs/API.js index a4ad78b65c15..267942930b32 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -105,7 +105,7 @@ function makeRequestWithSideEffects(command, apiCommandParameters = {}, onyxData * @param {Object} [onyxData.failureData] - Onyx instructions that will be passed to Onyx.update() when the response has jsonCode !== 200. */ function read(command, apiCommandParameters, onyxData) { - SequentialQueue.getIsDonePromise().then(() => makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ)); + SequentialQueue.getIsReadyPromise().then(() => makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ)); } export { diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index 90db8e438ba1..e869012a6411 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -18,13 +18,6 @@ let isSequentialQueueRunning = false; let currentRequest = null; -let resolveIsDonePromise; -let isDonePromise = new Promise((resolve) => { - resolveIsDonePromise = resolve; -}); - -let pendingRequests = []; - /** * This method will get any persisted requests and fire them off in sequence to retry them. * @@ -40,7 +33,6 @@ function process() { const task = _.reduce(persistedRequests, (previousRequest, request) => previousRequest.then(() => { currentRequest = Request.processWithMiddleware(request, true); - pendingRequests.push(currentRequest); return currentRequest; }), Promise.resolve()); @@ -74,21 +66,8 @@ function flush() { process() .finally(() => { isSequentialQueueRunning = false; - resolveIsReadyPromise(); currentRequest = null; - - // Resolve the isDonePromise once all the pending requests complete, - // and reset the pendingRequests array - Promise.all(pendingRequests).then(() => { - resolveIsDonePromise(); - pendingRequests = []; - }); - }).then(() => { - // Reset the isDonePromise so we can use it again on the next run, - // this has to be done after the finally runs otherwise it'll have no effect - isDonePromise = new Promise((resolve) => { - resolveIsDonePromise = resolve; - }); + resolveIsReadyPromise(); }); }, }); @@ -135,11 +114,11 @@ function getCurrentRequest() { return currentRequest; } -function getIsDonePromise() { +function getIsReadyPromise() { if (!isSequentialQueueRunning) { return Promise.resolve(); } - return isDonePromise; + return isReadyPromise; } export { @@ -147,5 +126,5 @@ export { getCurrentRequest, isRunning, push, - getIsDonePromise, + getIsReadyPromise, }; From 43e7635625b3920c0883d5119a7ee2cd4b46fa1d Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 2 Nov 2022 07:24:11 -0700 Subject: [PATCH 14/23] use single promise --- src/libs/Network/SequentialQueue.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index e869012a6411..b92e9ca654a6 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -114,6 +114,10 @@ function getCurrentRequest() { return currentRequest; } +/** + * Returns a promise that resolves when the last request on the queue responds. + * @returns {Promise} + */ function getIsReadyPromise() { if (!isSequentialQueueRunning) { return Promise.resolve(); From 306185f40ce31eb8b37fbf43e5285157d1d5e671 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 2 Nov 2022 07:29:27 -0700 Subject: [PATCH 15/23] remove unused --- src/libs/Network/SequentialQueue.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index b92e9ca654a6..afeb0c0fe633 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -66,8 +66,8 @@ function flush() { process() .finally(() => { isSequentialQueueRunning = false; - currentRequest = null; resolveIsReadyPromise(); + currentRequest = null; }); }, }); From f3f69ad5d3de0742f486588c9e153ece9444888a Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 2 Nov 2022 14:14:33 -0700 Subject: [PATCH 16/23] comment --- src/libs/API.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libs/API.js b/src/libs/API.js index 267942930b32..92e506f89e18 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -105,6 +105,10 @@ function makeRequestWithSideEffects(command, apiCommandParameters = {}, onyxData * @param {Object} [onyxData.failureData] - Onyx instructions that will be passed to Onyx.update() when the response has jsonCode !== 200. */ function read(command, apiCommandParameters, onyxData) { + // We need to ensure all the write requests on the sequential queue have responded first before running read requests. + // This is because if we make write requests offline, their optimisticData can get overwritten by responses from + // lightweight read requests that access the same Onyx key and modify its value before the write request has had a chance to update it after responding. + // This prevents the "flickering" effect. SequentialQueue.getIsReadyPromise().then(() => makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ)); } From 132add70e1bb5cdc6dead75cff2c4126bd9b64c2 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 2 Nov 2022 17:29:30 -0700 Subject: [PATCH 17/23] rename function --- src/libs/API.js | 2 +- src/libs/Network/SequentialQueue.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/API.js b/src/libs/API.js index 92e506f89e18..d14fb42dd071 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -109,7 +109,7 @@ function read(command, apiCommandParameters, onyxData) { // This is because if we make write requests offline, their optimisticData can get overwritten by responses from // lightweight read requests that access the same Onyx key and modify its value before the write request has had a chance to update it after responding. // This prevents the "flickering" effect. - SequentialQueue.getIsReadyPromise().then(() => makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ)); + SequentialQueue.waitForIdle().then(() => makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ)); } export { diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index afeb0c0fe633..7b922ce5872f 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -118,7 +118,7 @@ function getCurrentRequest() { * Returns a promise that resolves when the last request on the queue responds. * @returns {Promise} */ -function getIsReadyPromise() { +function waitForIdle() { if (!isSequentialQueueRunning) { return Promise.resolve(); } @@ -130,5 +130,5 @@ export { getCurrentRequest, isRunning, push, - getIsReadyPromise, + waitForIdle, }; From 4c48dbf626b9735d7f66504d0c6d4d97db5e7a95 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 2 Nov 2022 17:33:42 -0700 Subject: [PATCH 18/23] directly use promise --- ios/NewExpensify.xcodeproj/project.pbxproj | 6 ++++-- .../xcshareddata/WorkspaceSettings.xcsettings | 8 ++++++++ ios/NewExpensify.xcworkspace/contents.xcworkspacedata | 10 ++++++++++ ios/Podfile.lock | 10 +++++----- src/libs/Network/SequentialQueue.js | 3 --- 5 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 ios/NewExpensify.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 ios/NewExpensify.xcworkspace/contents.xcworkspacedata diff --git a/ios/NewExpensify.xcodeproj/project.pbxproj b/ios/NewExpensify.xcodeproj/project.pbxproj index cad2b5f4eb2e..5b46ea16f0cf 100644 --- a/ios/NewExpensify.xcodeproj/project.pbxproj +++ b/ios/NewExpensify.xcodeproj/project.pbxproj @@ -750,7 +750,7 @@ COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -775,6 +775,7 @@ ); MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; + REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; }; name = Debug; @@ -811,7 +812,7 @@ COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -828,6 +829,7 @@ "\"$(inherited)\"", ); MTL_ENABLE_DEBUG_INFO = NO; + REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; diff --git a/ios/NewExpensify.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/NewExpensify.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000000..f9b0d7c5ea15 --- /dev/null +++ b/ios/NewExpensify.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/NewExpensify.xcworkspace/contents.xcworkspacedata b/ios/NewExpensify.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..bf66f1bed435 --- /dev/null +++ b/ios/NewExpensify.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/ios/Podfile.lock b/ios/Podfile.lock index eddd669073a3..391c25036bea 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -975,7 +975,7 @@ SPEC CHECKSUMS: React-jsinspector: 0f08037401626246e5c760871a023769b9815619 React-logger: 0a8e62c840f534936c2cb2c96d0e6d507010e862 react-native-blob-util: c3b0faecd2919db568e9d552084396f3e50b57c7 - react-native-cameraroll: 2957f2bce63ae896a848fbe0d5352c1bd4d20866 + react-native-cameraroll: 60ac50a5209777cbccfe8d7a62d0743a9da87060 react-native-config: 7cd105e71d903104e8919261480858940a6b9c0e react-native-document-picker: f68191637788994baed5f57d12994aa32cf8bf88 react-native-flipper: dc5290261fbeeb2faec1bdc57ae6dd8d562e1de4 @@ -984,9 +984,9 @@ SPEC CHECKSUMS: react-native-netinfo: 1a6035d3b9780221d407c277ebfb5722ace00658 react-native-pdf: 33c622cbdf776a649929e8b9d1ce2d313347c4fa react-native-plaid-link-sdk: 77052f329310ff5a36ddda276793f40d27c02bc4 - react-native-progress-bar-android: be43138ab7da30d51fc038bafa98e9ed594d0c40 + react-native-progress-bar-android: ce95a69f11ac580799021633071368d08aaf9ad8 react-native-progress-view: 4d3bbe6a099ba027b1fedb1548c2c87f74249b70 - react-native-render-html: 96c979fe7452a0a41559685d2f83b12b93edac8c + react-native-render-html: 786d150a8e38d3d299bc21dc4848c5d70edc5a5f react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a react-native-webview: e771bc375f789ebfa02a26939a57dbc6fa897336 React-perflogger: d4c9c4cfcc30a0d6cca35ddbd40a85ad4d3e4db1 @@ -1002,9 +1002,9 @@ SPEC CHECKSUMS: React-runtimeexecutor: a0bd76a1162262d2945d467f6b978116e740904f ReactCommon: cf8ef38ad293cc8a30b02f858bd16719b64a985b RNCAsyncStorage: 0c357f3156fcb16c8589ede67cc036330b6698ca - RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495 + RNCClipboard: 5e299c6df8e0c98f3d7416b86ae563d3a9f768a3 RNCPicker: 0b65be85fe7954fbb2062ef079e3d1cde252d888 - RNDateTimePicker: 7658208086d86d09e1627b5c34ba0cf237c60140 + RNDateTimePicker: c9911be59b1f8670b9f244b85af3a7c295e175ed RNFastImage: 1f2cab428712a4baaf78d6169eaec7f622556dd7 RNFBAnalytics: f76bfa164ac235b00505deb9fc1776634056898c RNFBApp: 729c0666395b1953198dc4a1ec6deb8fbe1c302e diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index 7b922ce5872f..63f9290f3b00 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -119,9 +119,6 @@ function getCurrentRequest() { * @returns {Promise} */ function waitForIdle() { - if (!isSequentialQueueRunning) { - return Promise.resolve(); - } return isReadyPromise; } From 0984812e1c674e96570386aa72886222904ebb37 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 2 Nov 2022 17:35:06 -0700 Subject: [PATCH 19/23] revert unneeded --- ios/NewExpensify.xcodeproj/project.pbxproj | 6 ++---- ios/Podfile.lock | 10 +++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/ios/NewExpensify.xcodeproj/project.pbxproj b/ios/NewExpensify.xcodeproj/project.pbxproj index 5b46ea16f0cf..cad2b5f4eb2e 100644 --- a/ios/NewExpensify.xcodeproj/project.pbxproj +++ b/ios/NewExpensify.xcodeproj/project.pbxproj @@ -750,7 +750,7 @@ COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -775,7 +775,6 @@ ); MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; }; name = Debug; @@ -812,7 +811,7 @@ COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -829,7 +828,6 @@ "\"$(inherited)\"", ); MTL_ENABLE_DEBUG_INFO = NO; - REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 391c25036bea..eddd669073a3 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -975,7 +975,7 @@ SPEC CHECKSUMS: React-jsinspector: 0f08037401626246e5c760871a023769b9815619 React-logger: 0a8e62c840f534936c2cb2c96d0e6d507010e862 react-native-blob-util: c3b0faecd2919db568e9d552084396f3e50b57c7 - react-native-cameraroll: 60ac50a5209777cbccfe8d7a62d0743a9da87060 + react-native-cameraroll: 2957f2bce63ae896a848fbe0d5352c1bd4d20866 react-native-config: 7cd105e71d903104e8919261480858940a6b9c0e react-native-document-picker: f68191637788994baed5f57d12994aa32cf8bf88 react-native-flipper: dc5290261fbeeb2faec1bdc57ae6dd8d562e1de4 @@ -984,9 +984,9 @@ SPEC CHECKSUMS: react-native-netinfo: 1a6035d3b9780221d407c277ebfb5722ace00658 react-native-pdf: 33c622cbdf776a649929e8b9d1ce2d313347c4fa react-native-plaid-link-sdk: 77052f329310ff5a36ddda276793f40d27c02bc4 - react-native-progress-bar-android: ce95a69f11ac580799021633071368d08aaf9ad8 + react-native-progress-bar-android: be43138ab7da30d51fc038bafa98e9ed594d0c40 react-native-progress-view: 4d3bbe6a099ba027b1fedb1548c2c87f74249b70 - react-native-render-html: 786d150a8e38d3d299bc21dc4848c5d70edc5a5f + react-native-render-html: 96c979fe7452a0a41559685d2f83b12b93edac8c react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a react-native-webview: e771bc375f789ebfa02a26939a57dbc6fa897336 React-perflogger: d4c9c4cfcc30a0d6cca35ddbd40a85ad4d3e4db1 @@ -1002,9 +1002,9 @@ SPEC CHECKSUMS: React-runtimeexecutor: a0bd76a1162262d2945d467f6b978116e740904f ReactCommon: cf8ef38ad293cc8a30b02f858bd16719b64a985b RNCAsyncStorage: 0c357f3156fcb16c8589ede67cc036330b6698ca - RNCClipboard: 5e299c6df8e0c98f3d7416b86ae563d3a9f768a3 + RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495 RNCPicker: 0b65be85fe7954fbb2062ef079e3d1cde252d888 - RNDateTimePicker: c9911be59b1f8670b9f244b85af3a7c295e175ed + RNDateTimePicker: 7658208086d86d09e1627b5c34ba0cf237c60140 RNFastImage: 1f2cab428712a4baaf78d6169eaec7f622556dd7 RNFBAnalytics: f76bfa164ac235b00505deb9fc1776634056898c RNFBApp: 729c0666395b1953198dc4a1ec6deb8fbe1c302e From 42e2912f8bef3828c579b441420e22d40f440a29 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 2 Nov 2022 17:36:53 -0700 Subject: [PATCH 20/23] Delete WorkspaceSettings.xcsettings --- .../xcshareddata/WorkspaceSettings.xcsettings | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 ios/NewExpensify.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/ios/NewExpensify.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/NewExpensify.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5ea15..000000000000 --- a/ios/NewExpensify.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - From 2cb1fa6c20f7003586b7ead8972ece0a548d47fe Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 2 Nov 2022 17:37:00 -0700 Subject: [PATCH 21/23] Delete contents.xcworkspacedata --- ios/NewExpensify.xcworkspace/contents.xcworkspacedata | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 ios/NewExpensify.xcworkspace/contents.xcworkspacedata diff --git a/ios/NewExpensify.xcworkspace/contents.xcworkspacedata b/ios/NewExpensify.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index bf66f1bed435..000000000000 --- a/ios/NewExpensify.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - From c653d1a6d8a906e68ed779f7cbadd45253b1f1ca Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Thu, 3 Nov 2022 08:04:27 -0700 Subject: [PATCH 22/23] make comment more succinct --- src/libs/API.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libs/API.js b/src/libs/API.js index d14fb42dd071..d86fc099a08a 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -105,10 +105,9 @@ function makeRequestWithSideEffects(command, apiCommandParameters = {}, onyxData * @param {Object} [onyxData.failureData] - Onyx instructions that will be passed to Onyx.update() when the response has jsonCode !== 200. */ function read(command, apiCommandParameters, onyxData) { - // We need to ensure all the write requests on the sequential queue have responded first before running read requests. - // This is because if we make write requests offline, their optimisticData can get overwritten by responses from - // lightweight read requests that access the same Onyx key and modify its value before the write request has had a chance to update it after responding. - // This prevents the "flickering" effect. + // Ensure all write requests on the sequential queue have finished responding before running read requests. + // Responses from read requests can overwrite the optimistic data inserted by + // write requests that use the same Onyx keys and haven't responded yet. SequentialQueue.waitForIdle().then(() => makeRequestWithSideEffects(command, apiCommandParameters, onyxData, CONST.API_REQUEST_TYPE.READ)); } From 0885f91b1eb51d337addf338943b60bc110f9f91 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Thu, 3 Nov 2022 08:16:59 -0700 Subject: [PATCH 23/23] Update src/libs/Network/SequentialQueue.js Co-authored-by: Tim Golen --- src/libs/Network/SequentialQueue.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Network/SequentialQueue.js b/src/libs/Network/SequentialQueue.js index 63f9290f3b00..f37eb8422247 100644 --- a/src/libs/Network/SequentialQueue.js +++ b/src/libs/Network/SequentialQueue.js @@ -115,7 +115,7 @@ function getCurrentRequest() { } /** - * Returns a promise that resolves when the last request on the queue responds. + * Returns a promise that resolves when the sequential queue is done processing all persisted write requests. * @returns {Promise} */ function waitForIdle() {