Skip to content

Instantly share code, notes, and snippets.

@RemeJuan
Created May 21, 2018 13:30
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RemeJuan/540800f3d600e95c18f6dad183f4382e to your computer and use it in GitHub Desktop.
Save RemeJuan/540800f3d600e95c18f6dad183f4382e to your computer and use it in GitHub Desktop.
Race Conditions Redux
export const SEARCH_POST_START = 'SEARCH_POST_START';
export const searchPostNoResults = data => ({
type: SEARCH_POST_NO_RESULTS, data,
});
import {
SEARCH_POST_SUCCESS,
SEARCH_POST_ERROR,
SEARCH_POST_START,
SEARCH_POST_NO_RESULTS,
} from '~/apis';
export const initialState = {
error: false,
errorMessage: undefined,
isSearching: false,
searchResults: [],
searchText: '',
timestamp: undefined,
};
function actionIsValid(state, data) {
return data.timestamp >= state.timestamp;
}
export default function searchReducer(state = initialState, action) {
const { type, data } = action;
switch (type) {
case SEARCH_POST_SUCCESS: {
if (actionIsValid(state, data)) {
return {
...state,
...data,
searchResults: mockSearch,
isSearching: false,
};
}
return state;
}
case SEARCH_POST_START:
return {
...state,
...data,
isSearching: true,
};
case SEARCH_POST_ERROR: {
if (actionIsValid(state, data)) {
return {
...state,
...data,
searchResults: mockSearch,
isSearching: false,
};
}
return state;
}
default:
return state;
}
}
export function search(searchQuery) {
return async (dispatch, getState) => {
const timestamp = Date.now();
const startData = { searchText: searchQuery, timestamp };
dispatch(searchPostStart(startData));
try {
const url = `${URL}?searchQuery=${searchQuery}`;
const options = {};
const response = await fetch(url, options);
const json = await response.json();
const success = { searchResults: json, timestamp };
return dispatch(searchPostSuccess(success));
} catch (error) {
const err = { error: true, errorMessage: error };
return dispatch(searchPostError(err));
}
};
}
@shamseerahammedm
Copy link

How would the time be diff coz ur always setting the time on action start and ur using the same time on success right ?

@RemeJuan
Copy link
Author

How would the time be diff coz ur always setting the time on action start and ur using the same time on success right?

This is for handling race conditions, commonly found when allowing "search while you type", when the function starts it sets a time stamp on the state, that same timestamp is used when it ends, but if a 2nd call goes out, the state will have a new timestamp, if the first call comes back, it does not have the new timestamp, it has its timestamp, therefore the timestamp the state is expecting will not equal the timestamp that first call is returning.

The first call goes off with a TS of 10, another one goes off with a TS of 12, and yet another one with TS of 17. The state is expecting 17 now, and the second call comes back, it dispatches success with a TS of 12 so they do not match and an update is not applied, then the first one comes back with a TS of 10 and that still does not match so once again an update is not applied, but the third call finally comes back and it's TS is 17 which does match, therefore the state update will now be applied.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment