Skip to content

Commit

Permalink
fix: avoid fetching data/geojson multiple times (#310)
Browse files Browse the repository at this point in the history
* fetch data and geojson only once when re-used

* avoid fetching the same mapping at the same time

* use dataset key with timekey

* Restyled by prettier (#311)

Co-authored-by: Restyled.io <[email protected]>

* refactor: extract data/geo fetching methods

Co-authored-by: restyled-io[bot] <32688539+restyled-io[bot]@users.noreply.github.com>
Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
3 people authored Oct 31, 2020
1 parent fc80428 commit 111c51b
Showing 1 changed file with 65 additions and 21 deletions.
86 changes: 65 additions & 21 deletions src/state/thunks/fetchMappedSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,41 +35,84 @@ const fetchAndTransform = async (
return null;
};

const currentlyFetchingMapping = new Set();
const currentlyFetchingData = new Map();
const currentlyFetchingGeo = new Map();

async function fetchDataset(datasource, date, mapping, datasets, dispatch) {
const timeKey = formatUTCDate(date);
const { datasourceId, transformData, dataProperty } = mapping;
const datasetKey = `${timeKey}-${datasourceId}`;

if (currentlyFetchingData.has(datasetKey)) {
return currentlyFetchingData.get(datasetKey);
}

const datasetPromise = (async () => {
if (datasets.has(datasetKey)) {
return datasets.get(datasetKey);
}
const dataset = await fetchAndTransform(datasource.url, timeKey, date, dataProperty, transformData);
dispatch(AppApi.addDataset(datasetKey, dataset));

currentlyFetchingData.delete(datasetKey);

return dataset;
})();

currentlyFetchingData.set(datasetKey, datasetPromise);

return datasetPromise;
}

async function fetchGeo(geo, date, mapping, geos, dispatch): Promise<GeoJSON | undefined> {
const timeKey = formatUTCDate(date);
const { geoId, transformGeo, geoProperty } = mapping;

if (currentlyFetchingGeo.has(geoId)) {
return currentlyFetchingGeo.get(geoId);
}

const geoPromise = (async () => {
const geoKey = `${geoId}`;
if (geos.has(geoKey)) {
return geos.get(geoKey);
}
const geoset = await fetchAndTransform(geo.url, timeKey, date, geoProperty, transformGeo);
dispatch(AppApi.addGeo(geoKey, geoset));

currentlyFetchingGeo.delete(geoId);

return geoset;
})();

currentlyFetchingGeo.set(geoId, geoPromise);

return geoPromise;
}

export function fetchMappedSet(visualId: VisualId, mappingId: string, date: Moment) {
return async (dispatch: ReduxDispatch, getState: () => State) => {
const timeKey = formatUTCDate(date);
const loadingKey = `loading-${mappingId}-${timeKey}`;

if (currentlyFetchingMapping.has(loadingKey)) {
return;
}
currentlyFetchingMapping.add(loadingKey);

dispatch(AppApi.pushLoading(loadingKey));

try {
const mapping = config.visuals[visualId].mappings[mappingId];
const { datasourceId, geoId, transformData, transformGeo, geoProperty, dataProperty } = mapping;
const { datasourceId, geoId, geoProperty } = mapping;
const { datasets, geos, mappedSets } = getState().app;
const datasource = config.datasources[datasourceId];
const geo = config.geos[geoId];

const [data, geojson] = await Promise.all([
Promise.resolve().then(async () => {
const datasetKey = `${formatUTCDate(date)}-${datasourceId}`;
if (datasets.has(datasetKey)) {
return datasets.get(datasetKey);
}
const dataset = await fetchAndTransform(datasource.url, timeKey, date, dataProperty, transformData);
dispatch(AppApi.addDataset(datasetKey, dataset));
return dataset;
}),
Promise.resolve().then(
async (): Promise<GeoJSON | undefined> => {
const geoKey = `${geoId}`;
if (geos.has(geoKey)) {
return geos.get(geoKey);
}
const geoset = await fetchAndTransform(geo.url, timeKey, date, geoProperty, transformGeo);
dispatch(AppApi.addGeo(geoKey, geoset));
return geoset;
},
),
fetchDataset(datasource, date, mapping, datasets, dispatch),
fetchGeo(geo, date, mapping, geos, dispatch),
]);

if (!data || !geojson) {
Expand Down Expand Up @@ -109,6 +152,7 @@ export function fetchMappedSet(visualId: VisualId, mappingId: string, date: Mome
console.error(err);
} finally {
dispatch(AppApi.popLoading(loadingKey));
currentlyFetchingMapping.delete(loadingKey);
}
};
}

0 comments on commit 111c51b

Please sign in to comment.