Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix: User experienced big delay when posting the messages #26729

Merged
merged 7 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/libs/DateUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ Onyx.connect({
},
});

let networkTimeSkew = 0;
Onyx.connect({
key: ONYXKEYS.NETWORK,
callback: (val) => (networkTimeSkew = lodashGet(val, 'timeSkew', 0)),
});

/**
* Gets the locale string and setting default locale for date-fns
*
Expand Down Expand Up @@ -307,6 +313,15 @@ function getDBTime(timestamp = '') {
return datetime.toISOString().replace('T', ' ').replace('Z', '');
}

/**
* Returns the current time plus skew in milliseconds in the format expected by the database
*
* @returns {String}
*/
function getDBTimeWithSkew() {
return getDBTime(new Date().valueOf() + networkTimeSkew);
}

/**
* @param {String} dateTime
* @param {Number} milliseconds
Expand Down Expand Up @@ -383,6 +398,7 @@ const DateUtils = {
setTimezoneUpdated,
getMicroseconds,
getDBTime,
getDBTimeWithSkew,
subtractMillisecondsFromDateTime,
getDateStringFromISOTimestamp,
getStatusUntilDate,
Expand Down
24 changes: 24 additions & 0 deletions src/libs/HttpUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ONYXKEYS from '../ONYXKEYS';
import HttpsError from './Errors/HttpsError';
import * as ApiUtils from './ApiUtils';
import alert from '../components/Alert';
import * as NetworkActions from './actions/Network';

let shouldFailAllRequests = false;
let shouldForceOffline = false;
Expand All @@ -22,6 +23,16 @@ Onyx.connect({
// We use the AbortController API to terminate pending request in `cancelPendingRequests`
let cancellationController = new AbortController();

/**
* The API commands that require the skew calculation
*/
const addSkewList = ['OpenReport', 'ReconnectApp', 'OpenApp'];

/**
* Regex to get API command from the command
*/
const regex = /[?&]command=([^&]+)/;

/**
* Send an HTTP request, and attempt to resolve the json response.
* If there is a network error, we'll set the application offline.
Expand All @@ -33,12 +44,25 @@ let cancellationController = new AbortController();
* @returns {Promise}
*/
function processHTTPRequest(url, method = 'get', body = null, canCancel = true) {
const startTime = new Date().valueOf();

return fetch(url, {
// We hook requests to the same Controller signal, so we can cancel them all at once
signal: canCancel ? cancellationController.signal : undefined,
method,
body,
})
.then((response) => {
const match = url.match(regex)[1];
if (addSkewList.includes(match) && response.headers) {
const serverTime = new Date(response.headers.get('Date')).valueOf();
const endTime = new Date().valueOf();
const latency = (endTime - startTime) / 2;
const skew = serverTime - startTime + latency;
NetworkActions.setTimeSkew(skew);
}
return response;
})
.then((response) => {
// Test mode where all requests will succeed in the server, but fail to return a response
if (shouldFailAllRequests || shouldForceOffline) {
Expand Down
2 changes: 1 addition & 1 deletion src/libs/ReportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1921,7 +1921,7 @@ function buildOptimisticAddCommentReportAction(text, file) {
],
automatic: false,
avatar: lodashGet(allPersonalDetails, [currentUserAccountID, 'avatar'], UserUtils.getDefaultAvatarURL(currentUserAccountID)),
created: DateUtils.getDBTime(),
created: DateUtils.getDBTimeWithSkew(),
message: [
{
translationKey: isAttachment ? CONST.TRANSLATION_KEYS.ATTACHMENT : '',
Expand Down
6 changes: 5 additions & 1 deletion src/libs/actions/Network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ function setIsOffline(isOffline: boolean) {
Onyx.merge(ONYXKEYS.NETWORK, {isOffline});
}

function setTimeSkew(skew: number) {
Onyx.merge(ONYXKEYS.NETWORK, {timeSkew: skew});
}

function setShouldForceOffline(shouldForceOffline: boolean) {
Onyx.merge(ONYXKEYS.NETWORK, {shouldForceOffline});
}
Expand All @@ -16,4 +20,4 @@ function setShouldFailAllRequests(shouldFailAllRequests: boolean) {
Onyx.merge(ONYXKEYS.NETWORK, {shouldFailAllRequests});
}

export {setIsOffline, setShouldForceOffline, setShouldFailAllRequests};
export {setIsOffline, setShouldForceOffline, setShouldFailAllRequests, setTimeSkew};
2 changes: 1 addition & 1 deletion src/libs/actions/Report.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ function addActions(reportID, text = '', file) {
// Always prefer the file as the last action over text
const lastAction = attachmentAction || reportCommentAction;

const currentTime = DateUtils.getDBTime();
const currentTime = DateUtils.getDBTimeWithSkew();

const lastCommentText = ReportUtils.formatReportLastMessageText(lastAction.message[0].text);

Expand Down
3 changes: 3 additions & 0 deletions src/types/onyx/Network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ type Network = {

/** Whether we should fail all network requests */
shouldFailAllRequests?: boolean;

/** Skew between the client and server clocks */
timeSkew?: number;
};

export default Network;
Loading