Skip to content

Commit

Permalink
Avoid multiple concurrent requests for lang file. (Automattic#35045)
Browse files Browse the repository at this point in the history
* Avoid multiple concurrent requests for lang file.

In some cases, multiple concurrent requests for the language JSON file
could take place. This behaved normally, but resulted in wasted
bandwidth for the user.

* Avoid reusing response body.

* Handle empty body response in `switchLocale`.
  • Loading branch information
sgomes committed Aug 12, 2019
1 parent 23237b1 commit 1b2f770
Showing 1 changed file with 34 additions and 9 deletions.
43 changes: 34 additions & 9 deletions client/lib/i18n-utils/switch-locale.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@ import { isDefaultLocale, getLanguage } from './utils';

const debug = debugFactory( 'calypso:i18n' );

const getPromises = {};

/**
* De-duplicates repeated GET fetches of the same URL while one is taking place.
* Once it's finished, it'll allow for the same request to be done again.
* @param {string} url The URL to fetch
*
* @returns {Promise} The fetch promise.
*/
function dedupedGet( url ) {
if ( ! ( url in getPromises ) ) {
getPromises[ url ] = fetch( url ).finally( () => delete getPromises[ url ] );
}

return getPromises[ url ];
}

/**
* Get the protocol, domain, and path part of the language file URL.
* Normally it should only serve as a helper function for `getLanguageFileUrl`,
Expand Down Expand Up @@ -63,8 +80,14 @@ function setLocaleInDOM( localeSlug, isRTL ) {
async function getLanguageFile( targetLocaleSlug ) {
const url = getLanguageFileUrl( targetLocaleSlug );

const response = await fetch( url );
const response = await dedupedGet( url );
if ( response.ok ) {
if ( response.bodyUsed ) {
// If the body was already used, we assume that we already parsed the
// response and set the locale in the DOM, so we don't need to do anything
// else here.
return;
}
return await response.json();
}

Expand Down Expand Up @@ -101,17 +124,19 @@ export default function switchLocale( localeSlug ) {
getLanguageFile( targetLocaleSlug ).then(
// Success.
body => {
// Handle race condition when we're requested to switch to a different
// locale while we're in the middle of request, we should abandon result
if ( targetLocaleSlug !== lastRequestedLocale ) {
return;
}
if ( body ) {
// Handle race condition when we're requested to switch to a different
// locale while we're in the middle of request, we should abandon result
if ( targetLocaleSlug !== lastRequestedLocale ) {
return;
}

i18n.setLocale( body );
i18n.setLocale( body );

setLocaleInDOM( domLocaleSlug, !! language.rtl );
setLocaleInDOM( domLocaleSlug, !! language.rtl );

loadUserUndeployedTranslations( targetLocaleSlug );
loadUserUndeployedTranslations( targetLocaleSlug );
}
},
// Failure.
() => {
Expand Down

0 comments on commit 1b2f770

Please sign in to comment.