Batch resolve with claim_search | [Recommended, Comments]

Ticket: 1189

## Issue
There is a bug in a batched `resolve` that returns jumbled data. Temporarily switch to `claim_search` until that is fixed.

## Notable differences:
- `resolve` will tell us directly that a claim has been removed or filtered, so redux will mark the ID as such. `claim_search` simply returns nothing, so we will still end up with an extra `resolve` for these items when the component tries to display it.

- The new function currently does not handle Collections (i.e. resolving individual items in the Collection) and Reposts. Given that this is temporarily, I'd like to leave `doClaimSearch` as is, instead of trying to replicate what's in `doResolveUris`.

## Notes:
Since we don't care if the resolve fails (and we weren't doing anything in the `catch` anyways), use `finally` instead.
This commit is contained in:
infinite-persistence 2022-03-25 10:52:51 +08:00 committed by Thomas Zarebczan
parent 29ec4e3ad6
commit 122d561a20
3 changed files with 61 additions and 15 deletions

View file

@ -12,6 +12,7 @@ import {
selectPendingClaimsById, selectPendingClaimsById,
selectClaimIsMine, selectClaimIsMine,
selectIsMyChannelCountOverLimit, selectIsMyChannelCountOverLimit,
selectById,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { doFetchTxoPage } from 'redux/actions/wallet'; import { doFetchTxoPage } from 'redux/actions/wallet';
@ -141,6 +142,40 @@ export function doResolveUris(
}; };
} }
/**
* Temporary alternative to doResolveUris() due to a batching bug with
* Lbry.resolve().
*
* Note that is a simpler version that DOES NOT handle Collections and Reposts.
*
* @param claimIds
*/
export function doResolveClaimIds(claimIds: Array<string>) {
return (dispatch: Dispatch, getState: GetState) => {
const state = getState();
const resolvedIds = Object.keys(selectById(state));
const idsToResolve = claimIds.filter((x) => !resolvedIds.includes(x));
if (idsToResolve.length === 0) {
return;
}
return dispatch(
doClaimSearch(
{
claim_ids: idsToResolve,
page: 1,
page_size: Math.min(idsToResolve.length, 50),
no_totals: true,
},
{
useAutoPagination: idsToResolve.length > 50,
}
)
);
};
}
export function doResolveUri( export function doResolveUri(
uri: string, uri: string,
returnCachedClaims: boolean = false, returnCachedClaims: boolean = false,

View file

@ -8,7 +8,7 @@ import { resolveApiMessage } from 'util/api-message';
import { parseURI, buildURI, isURIEqual } from 'util/lbryURI'; import { parseURI, buildURI, isURIEqual } from 'util/lbryURI';
import { devToast, doFailedSignatureToast } from 'util/toast-wrappers'; import { devToast, doFailedSignatureToast } from 'util/toast-wrappers';
import { selectClaimForUri, selectClaimsByUri, selectMyChannelClaims } from 'redux/selectors/claims'; import { selectClaimForUri, selectClaimsByUri, selectMyChannelClaims } from 'redux/selectors/claims';
import { doResolveUris, doClaimSearch } from 'redux/actions/claims'; import { doResolveUris, doClaimSearch, doResolveClaimIds } from 'redux/actions/claims';
import { doToast, doSeeNotifications } from 'redux/actions/notifications'; import { doToast, doSeeNotifications } from 'redux/actions/notifications';
import { import {
selectMyReactsForComment, selectMyReactsForComment,
@ -66,8 +66,6 @@ export function doCommentList(
.then((result: CommentListResponse) => { .then((result: CommentListResponse) => {
const { items: comments, total_items, total_filtered_items, total_pages } = result; const { items: comments, total_items, total_filtered_items, total_pages } = result;
const commentChannelUrls = comments && comments.map((comment) => comment.channel_url || '');
const returnResult = () => { const returnResult = () => {
dispatch({ dispatch({
type: ACTIONS.COMMENT_LIST_COMPLETED, type: ACTIONS.COMMENT_LIST_COMPLETED,
@ -85,16 +83,13 @@ export function doCommentList(
return result; return result;
}; };
// Batch resolve comment channel urls // Batch resolve comment authors
if (commentChannelUrls && !isLivestream) { const commentChannelIds = comments && comments.map((comment) => comment.channel_id || '');
const resolve = async () => await doResolveUris(commentChannelUrls, true); if (commentChannelIds && !isLivestream) {
return dispatch(doResolveClaimIds(commentChannelIds)).finally(() => returnResult());
return resolve()
.then(() => dispatch(doResolveUris(commentChannelUrls, true)).then(() => returnResult()))
.catch(() => returnResult());
} }
returnResult(); return returnResult();
}) })
.catch((error) => { .catch((error) => {
const { message } = error; const { message } = error;

View file

@ -5,7 +5,7 @@ import { doOpenModal } from 'redux/actions/app';
import { doToast } from 'redux/actions/notifications'; import { doToast } from 'redux/actions/notifications';
import { selectShowMatureContent } from 'redux/selectors/settings'; import { selectShowMatureContent } from 'redux/selectors/settings';
import { selectClaimForUri, selectClaimIdForUri, selectClaimIsNsfwForUri } from 'redux/selectors/claims'; import { selectClaimForUri, selectClaimIdForUri, selectClaimIsNsfwForUri } from 'redux/selectors/claims';
import { doClaimSearch, doResolveUris } from 'redux/actions/claims'; import { doClaimSearch, doResolveClaimIds, doResolveUris } from 'redux/actions/claims';
import { buildURI, isURIValid } from 'util/lbryURI'; import { buildURI, isURIValid } from 'util/lbryURI';
import { batchActions } from 'util/batch-actions'; import { batchActions } from 'util/batch-actions';
import { makeSelectSearchUrisForQuery, selectPersonalRecommendations, selectSearchValue } from 'redux/selectors/search'; import { makeSelectSearchUrisForQuery, selectPersonalRecommendations, selectSearchValue } from 'redux/selectors/search';
@ -167,15 +167,31 @@ export const doSearch = (rawQuery: string, searchOptions: SearchOptions) => (
type: ACTIONS.SEARCH_START, type: ACTIONS.SEARCH_START,
}); });
const cmd = searchOptions.hasOwnProperty(SEARCH_OPTIONS.RELATED_TO) const isSearchingRecommendations = searchOptions.hasOwnProperty(SEARCH_OPTIONS.RELATED_TO);
? lighthouse.searchRecommendations const cmd = isSearchingRecommendations ? lighthouse.searchRecommendations : lighthouse.search;
: lighthouse.search;
cmd(queryWithOptions) cmd(queryWithOptions)
.then((data: { body: Array<{ name: string, claimId: string }>, poweredBy: string }) => { .then((data: { body: Array<{ name: string, claimId: string }>, poweredBy: string }) => {
const { body: result, poweredBy } = data; const { body: result, poweredBy } = data;
const uris = processLighthouseResults(result); const uris = processLighthouseResults(result);
if (isSearchingRecommendations) {
const claimIds = result.map((x) => x.claimId);
dispatch(doResolveClaimIds(claimIds)).finally(() => {
dispatch({
type: ACTIONS.SEARCH_SUCCESS,
data: {
query: queryWithOptions,
from: from,
size: size,
uris,
recsys: poweredBy,
},
});
});
return;
}
const actions = []; const actions = [];
actions.push(doResolveUris(uris)); actions.push(doResolveUris(uris));
actions.push({ actions.push({