Skip to content

Commit

Permalink
Optim, add user identities cache (#582)
Browse files Browse the repository at this point in the history
* feat(): cache user identities locally and avoid multiple fetches if identity is already known.

Signed-off-by: sBouzols <[email protected]>
  • Loading branch information
sBouzols authored Jan 3, 2025
1 parent 702b5b1 commit 6b0e2ef
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 10 deletions.
28 changes: 19 additions & 9 deletions src/hooks/useDirectoryContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const getName = (userId: string, data: UsersIdentitiesMap): string => {

export const useDirectoryContent = () => {
const currentChildren = useSelector((state: AppState) => state.currentChildren);
const knownUsersIdentitiesRef = useRef<UsersIdentitiesMap>({});
const [childrenMetadata, setChildrenMetadata] = useState<Record<UUID, ElementAttributes>>({});
const { snackError } = useSnackMessage();
const previousData = useRef<ElementAttributes[]>();
Expand Down Expand Up @@ -58,8 +59,14 @@ export const useDirectoryContent = () => {

const metadata: Record<UUID, ElementAttributes> = {};
const childrenToFetchElementsInfos = Object.values(currentChildren).map((e) => e.elementUuid);

const fetchUsersIdentitiesPromise = fetchUsersIdentities(childrenToFetchElementsInfos).catch(() => {
const childrenToFetchUsersIdentitiesInfos = Object.values(currentChildren)
.filter(
(e) =>
knownUsersIdentitiesRef.current?.[e.owner] === undefined ||
knownUsersIdentitiesRef.current?.[e.lastModifiedBy] === undefined
)
.map((e) => e.elementUuid);
const fetchUsersIdentitiesPromise = fetchUsersIdentities(childrenToFetchUsersIdentitiesInfos).catch(() => {
// Last resort, server down, error 500, fallback to subs as users Identities
// We write this code to have the same behavior as when there are partial results,
// (missing users identities), see getName()
Expand All @@ -77,16 +84,19 @@ export const useDirectoryContent = () => {
});

if (childrenToFetchElementsInfos.length > 0) {
Promise.all([
fetchUsersIdentitiesPromise, // TODO cache user identities across elements
fetchElementsInfos(childrenToFetchElementsInfos),
])
Promise.all([fetchUsersIdentitiesPromise, fetchElementsInfos(childrenToFetchElementsInfos)])
.then((res) => {
if (res[0] && res[0].data) {
Object.entries(res[0].data).forEach(([k, v]) => {
knownUsersIdentitiesRef.current[k] = v;
});
}

// discarding request for older directory
if (previousData.current === currentChildren) {
res[1].forEach((e) => {
e.ownerLabel = getName(e.owner, res[0].data);
e.lastModifiedByLabel = getName(e.lastModifiedBy, res[0].data);
e.ownerLabel = getName(e.owner, knownUsersIdentitiesRef.current);
e.lastModifiedByLabel = getName(e.lastModifiedBy, knownUsersIdentitiesRef.current);
metadata[e.elementUuid] = e;
});
setChildrenMetadata(metadata);
Expand All @@ -100,7 +110,7 @@ export const useDirectoryContent = () => {
}
}, [handleError, currentChildren]);

// TODO remove this when global user identity caching is implemented
// TODO remove this when currentChildren and metadata are fetched at once
const currentChildrenWithOwnerNames = useMemo(() => {
if (!currentChildren) {
return currentChildren;
Expand Down
5 changes: 4 additions & 1 deletion src/utils/rest-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,10 @@ export function fetchVersion() {
}

export function fetchUsersIdentities(elementUuids: string[]) {
console.info('fetching users identities for elements : %s', elementUuids);
if (elementUuids.length === 0) {
return Promise.resolve();
}
console.info('fetching users identities for %s elements.', elementUuids.length);
const idsParams = getRequestParamFromList('ids', elementUuids).toString();
const fetchParams = `${PREFIX_EXPLORE_SERVER_QUERIES}/v1/explore/elements/users-identities?${idsParams}`;
return backendFetchJson(fetchParams, {
Expand Down

0 comments on commit 6b0e2ef

Please sign in to comment.