doFetchSubCount: batch support; fetch interval gap;
1. The API supports batching -- updated the code to use that. Retained string as the parameter (instead of changing it to array) so that existing clients won't be affected. 2. Make `doFetchSubCount` a batched command by default through an idle timer. This way, none of the clients need to collect IDs -- it's all done behind the scenes. 3. Added minimum of 5 minutes between each sub-count fetch for a claim ID.
This commit is contained in:
parent
cbedc4b933
commit
5dd5826b33
2 changed files with 75 additions and 13 deletions
|
@ -2,6 +2,9 @@
|
|||
import { Lbryio } from 'lbryinc';
|
||||
import * as ACTIONS from 'constants/action_types';
|
||||
|
||||
const FETCH_SUB_COUNT_MIN_INTERVAL_MS = 5 * 60 * 1000;
|
||||
const FETCH_SUB_COUNT_IDLE_FIRE_MS = 100;
|
||||
|
||||
export const doFetchViewCount = (claimIdCsv: string) => (dispatch: Dispatch) => {
|
||||
dispatch({ type: ACTIONS.FETCH_VIEW_COUNT_STARTED });
|
||||
|
||||
|
@ -10,23 +13,56 @@ export const doFetchViewCount = (claimIdCsv: string) => (dispatch: Dispatch) =>
|
|||
const viewCounts = result;
|
||||
dispatch({ type: ACTIONS.FETCH_VIEW_COUNT_COMPLETED, data: { claimIdCsv, viewCounts } });
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
dispatch({ type: ACTIONS.FETCH_VIEW_COUNT_FAILED, data: error });
|
||||
});
|
||||
};
|
||||
|
||||
export const doFetchSubCount = (claimId: string) => (dispatch: Dispatch) => {
|
||||
const executeFetchSubCount = (claimIdCsv: string) => (dispatch: Dispatch, getState: GetState) => {
|
||||
const state = getState();
|
||||
const subCountLastFetchedById = state.stats.subCountLastFetchedById;
|
||||
const now = Date.now();
|
||||
|
||||
const claimIds = claimIdCsv.split(',').filter((id) => {
|
||||
const prev = subCountLastFetchedById[id];
|
||||
return !prev || now - prev > FETCH_SUB_COUNT_MIN_INTERVAL_MS;
|
||||
});
|
||||
|
||||
if (claimIds.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({ type: ACTIONS.FETCH_SUB_COUNT_STARTED });
|
||||
|
||||
return Lbryio.call('subscription', 'sub_count', { claim_id: claimId })
|
||||
return Lbryio.call('subscription', 'sub_count', { claim_id: claimIds.join(',') })
|
||||
.then((result: Array<number>) => {
|
||||
const subCount = result[0];
|
||||
const subCounts = result;
|
||||
dispatch({
|
||||
type: ACTIONS.FETCH_SUB_COUNT_COMPLETED,
|
||||
data: { claimId, subCount },
|
||||
data: { claimIdCsv, subCounts, fetchDate: now },
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
dispatch({ type: ACTIONS.FETCH_SUB_COUNT_FAILED, data: error });
|
||||
});
|
||||
};
|
||||
|
||||
let fetchSubCountTimer;
|
||||
let fetchSubCountQueue = '';
|
||||
|
||||
export const doFetchSubCount = (claimIdCsv: string) => (dispatch: Dispatch) => {
|
||||
if (fetchSubCountTimer) {
|
||||
clearTimeout(fetchSubCountTimer);
|
||||
}
|
||||
|
||||
if (fetchSubCountQueue && !fetchSubCountQueue.endsWith(',')) {
|
||||
fetchSubCountQueue += ',';
|
||||
}
|
||||
|
||||
fetchSubCountQueue += claimIdCsv;
|
||||
|
||||
fetchSubCountTimer = setTimeout(() => {
|
||||
dispatch(executeFetchSubCount(fetchSubCountQueue));
|
||||
fetchSubCountQueue = '';
|
||||
}, FETCH_SUB_COUNT_IDLE_FIRE_MS);
|
||||
};
|
||||
|
|
|
@ -8,15 +8,18 @@ const defaultState = {
|
|||
fetchingSubCount: false,
|
||||
subCountError: undefined,
|
||||
subCountById: {},
|
||||
subCountLastFetchedById: {},
|
||||
};
|
||||
|
||||
export const statsReducer = handleActions(
|
||||
{
|
||||
[ACTIONS.FETCH_VIEW_COUNT_STARTED]: state => ({ ...state, fetchingViewCount: true }),
|
||||
[ACTIONS.FETCH_VIEW_COUNT_STARTED]: (state) => ({ ...state, fetchingViewCount: true }),
|
||||
|
||||
[ACTIONS.FETCH_VIEW_COUNT_FAILED]: (state, action) => ({
|
||||
...state,
|
||||
viewCountError: action.data,
|
||||
}),
|
||||
|
||||
[ACTIONS.FETCH_VIEW_COUNT_COMPLETED]: (state, action) => {
|
||||
const { claimIdCsv, viewCounts } = action.data;
|
||||
|
||||
|
@ -35,20 +38,43 @@ export const statsReducer = handleActions(
|
|||
viewCountById,
|
||||
};
|
||||
},
|
||||
[ACTIONS.FETCH_SUB_COUNT_STARTED]: state => ({ ...state, fetchingSubCount: true }),
|
||||
|
||||
[ACTIONS.FETCH_SUB_COUNT_STARTED]: (state) => ({ ...state, fetchingSubCount: true }),
|
||||
|
||||
[ACTIONS.FETCH_SUB_COUNT_FAILED]: (state, action) => ({
|
||||
...state,
|
||||
subCountError: action.data,
|
||||
}),
|
||||
[ACTIONS.FETCH_SUB_COUNT_COMPLETED]: (state, action) => {
|
||||
const { claimId, subCount } = action.data;
|
||||
|
||||
const subCountById = { ...state.subCountById, [claimId]: subCount };
|
||||
return {
|
||||
[ACTIONS.FETCH_SUB_COUNT_COMPLETED]: (state, action) => {
|
||||
const { claimIdCsv, subCounts, fetchDate } = action.data;
|
||||
|
||||
const subCountById = Object.assign({}, state.subCountById);
|
||||
const subCountLastFetchedById = Object.assign({}, state.subCountLastFetchedById);
|
||||
const claimIds = claimIdCsv.split(',');
|
||||
let dataChanged = false;
|
||||
|
||||
if (claimIds.length === subCounts.length) {
|
||||
claimIds.forEach((claimId, index) => {
|
||||
if (subCountById[claimId] !== subCounts[index]) {
|
||||
subCountById[claimId] = subCounts[index];
|
||||
dataChanged = true;
|
||||
}
|
||||
subCountLastFetchedById[claimId] = fetchDate;
|
||||
});
|
||||
}
|
||||
|
||||
const newState = {
|
||||
...state,
|
||||
fetchingSubCount: false,
|
||||
subCountById,
|
||||
subCountLastFetchedById,
|
||||
};
|
||||
|
||||
if (dataChanged) {
|
||||
newState.subCountById = subCountById;
|
||||
}
|
||||
|
||||
return newState;
|
||||
},
|
||||
},
|
||||
defaultState
|
||||
|
|
Loading…
Reference in a new issue