Skip to content

Commit

Permalink
Switch back to the server-side implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
banderror committed Feb 17, 2021
1 parent fa63097 commit f3e4aba
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 157 deletions.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,6 @@ import * as i18n from '../translations';
import { fetchRules } from '../api';
import { createRulesTableReducer, RulesTableState, RulesTableAction } from './rules_table_reducer';
import { createRulesTableFacade, RulesTableFacade } from './rules_table_facade';
import { useFilteredRules } from './projections/filtering';
import { useSortedRules } from './projections/sorting';
import { usePaginatedRules, useDisplayedPaginationOptions } from './projections/pagination';

// Why these values?
// If we request more rules than 10000, we'll get an error from Elasticsearch (most likely).
// https://www.elastic.co/guide/en/elasticsearch/reference/current/paginate-search-results.html
// https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#dynamic-index-settings
// see `index.max_result_window`, default value is 10000.
// Example:
// In requests like `GET my-index/_search?from=40&size=20` it's not about items per page,
// but overall from+size count (requested page + all previous pages).
// If max_result_window=10000 this will fail: `GET my-index/_search?from=9990&size=20`.
// We load "all" rules in memory at once. So, because we always request page=1:
const MAX_RULES_TO_LOAD = 10000; // must not be increased
const NUM_RULES_TO_LOAD = MAX_RULES_TO_LOAD / 2; // must be < MAX_RULES_TO_LOAD

const INITIAL_SORT_FIELD = 'enabled';

Expand Down Expand Up @@ -84,8 +68,9 @@ export const useRulesTable = (params: UseRulesTableParams): UseRulesTableReturn
const reFetchRules = useRef<() => Promise<void>>(() => Promise.resolve());
const [, dispatchToaster] = useStateToaster();

// Fetch all rules at once (and only once) after mount. Filtering, sorting,
// searching and pagination are implemented in memory on the client side.
const { pagination, filterOptions } = state;
const filterTags = filterOptions.tags.sort().join();

useEffect(() => {
let isSubscribed = true;
const abortCtrl = new AbortController();
Expand All @@ -95,17 +80,15 @@ export const useRulesTable = (params: UseRulesTableParams): UseRulesTableReturn
facade.current.actionStarted('load', []);

const fetchRulesResult = await fetchRules({
filterOptions: initialStateDefaults.filterOptions,
pagination: {
page: 1,
perPage: NUM_RULES_TO_LOAD,
total: -1,
},
filterOptions,
pagination,
signal: abortCtrl.signal,
});

if (isSubscribed) {
facade.current.setRules(fetchRulesResult.data, {
page: fetchRulesResult.page,
perPage: fetchRulesResult.perPage,
total: fetchRulesResult.total,
});
}
Expand All @@ -128,28 +111,21 @@ export const useRulesTable = (params: UseRulesTableParams): UseRulesTableReturn
abortCtrl.abort();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const projections = useProjectedState(state);
}, [
pagination.page,
pagination.perPage,
filterOptions.filter,
filterOptions.sortField,
filterOptions.sortOrder,
filterTags,
filterOptions.showCustomRules,
filterOptions.showElasticRules,
]);

return {
state: { ...state, ...projections },
state,
dispatch,
...facade.current,
reFetchRules: reFetchRules.current,
};
};

const useProjectedState = (state: RulesTableState): Partial<RulesTableState> => {
const { rules, filterOptions, pagination } = state;

const filteredRules = useFilteredRules(rules, filterOptions);
const sortedRules = useSortedRules(filteredRules, filterOptions);
const displayedPagination = useDisplayedPaginationOptions(sortedRules, pagination);
const displayedRules = usePaginatedRules(sortedRules, displayedPagination);

return {
rules: displayedRules,
pagination: displayedPagination,
};
};

0 comments on commit f3e4aba

Please sign in to comment.