generated from well-known-components/template-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Get friends and Get Mutual optimizations and improved responses (…
…#37) * refactor: Change logs and return empty lists on get friends errors * feat: Add Catalyst Client adapter implementation with catalyst rotation and utils * feat: Get profiles from catalyst and map to friends * feat: GetMutualFriends also retrieves profiles and improves the response * fix: Wrong usage of table alias * feat: Get sent and received friendship requests optimizations (#38) * chore: seq diag improvements * feat: Use the profile image url to create the full url * feat: Get Sent and Received Friendship Requests respond with profile data * chore: Remove unused imports * refactor: Try with filter boolean but doesn't work * refactor: Pick specific props from entity * chore: Use Avatar type from schemas
- Loading branch information
1 parent
19b23c0
commit 0958107
Showing
39 changed files
with
999 additions
and
200 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { Entity } from '@dcl/schemas' | ||
import { createContentClient, ContentClient } from 'dcl-catalyst-client' | ||
import { getCatalystServersFromCache } from 'dcl-catalyst-client/dist/contracts-snapshots' | ||
import { AppComponents, ICatalystClient, ICatalystClientRequestOptions } from '../types' | ||
import { retry } from '../utils/retrier' | ||
import { shuffleArray } from '../utils/array' | ||
|
||
const L1_MAINNET = 'mainnet' | ||
const L1_TESTNET = 'sepolia' | ||
|
||
export async function createCatalystClient({ | ||
fetcher, | ||
config | ||
}: Pick<AppComponents, 'fetcher' | 'config'>): Promise<ICatalystClient> { | ||
const loadBalancer = await config.requireString('CATALYST_CONTENT_URL_LOADBALANCER') | ||
const contractNetwork = (await config.getString('ENV')) === 'prod' ? L1_MAINNET : L1_TESTNET | ||
|
||
function getContentClientOrDefault(contentServerUrl?: string): ContentClient { | ||
return contentServerUrl | ||
? createContentClient({ fetcher, url: contentServerUrl }) | ||
: createContentClient({ | ||
fetcher, | ||
url: loadBalancer | ||
}) | ||
} | ||
|
||
function rotateContentServerClient<T>( | ||
executeClientRequest: (client: ContentClient) => Promise<T>, | ||
contentServerUrl?: string | ||
) { | ||
const catalystServers = shuffleArray(getCatalystServersFromCache(contractNetwork)).map((server) => server.address) | ||
let contentClientToUse: ContentClient = getContentClientOrDefault(contentServerUrl) | ||
|
||
return (attempt: number): Promise<T> => { | ||
if (attempt > 1 && catalystServers.length > 0) { | ||
const [catalystServerUrl] = catalystServers.splice(attempt % catalystServers.length, 1) | ||
contentClientToUse = getContentClientOrDefault(catalystServerUrl) | ||
} | ||
|
||
return executeClientRequest(contentClientToUse) | ||
} | ||
} | ||
|
||
async function getEntitiesByPointers( | ||
pointers: string[], | ||
options: ICatalystClientRequestOptions = {} | ||
): Promise<Entity[]> { | ||
const { retries = 3, waitTime = 300, contentServerUrl } = options | ||
const executeClientRequest = rotateContentServerClient( | ||
(contentClientToUse) => contentClientToUse.fetchEntitiesByPointers(pointers), | ||
contentServerUrl | ||
) | ||
return retry(executeClientRequest, retries, waitTime) | ||
} | ||
|
||
return { getEntitiesByPointers } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,53 @@ | ||
import { RpcServerContext, RPCServiceContext } from '../../../types' | ||
import { INTERNAL_SERVER_ERROR, FRIENDSHIPS_PER_PAGE } from '../constants' | ||
import { FRIENDSHIPS_PER_PAGE } from '../constants' | ||
import { | ||
GetMutualFriendsPayload, | ||
PaginatedUsersResponse | ||
PaginatedFriendsProfilesResponse | ||
} from '@dcl/protocol/out-js/decentraland/social_service/v2/social_service_v2.gen' | ||
import { normalizeAddress } from '../../../utils/address' | ||
import { getPage } from '../../../utils/pagination' | ||
import { parseProfilesToFriends } from '../../../logic/friends' | ||
|
||
export function getMutualFriendsService({ components: { logs, db } }: RPCServiceContext<'logs' | 'db'>) { | ||
export async function getMutualFriendsService({ | ||
components: { logs, db, catalystClient, config } | ||
}: RPCServiceContext<'logs' | 'db' | 'catalystClient' | 'config'>) { | ||
const logger = logs.getLogger('get-mutual-friends-service') | ||
const profileImagesUrl = await config.requireString('PROFILE_IMAGES_URL') | ||
|
||
return async function ( | ||
request: GetMutualFriendsPayload, | ||
context: RpcServerContext | ||
): Promise<PaginatedFriendsProfilesResponse> { | ||
logger.debug(`Getting mutual friends ${context.address}<>${request.user!.address}`) | ||
|
||
return async function (request: GetMutualFriendsPayload, context: RpcServerContext): Promise<PaginatedUsersResponse> { | ||
logger.debug(`getting mutual friends ${context.address}<>${request.user!.address}`) | ||
try { | ||
const { address: requester } = context | ||
const { pagination, user } = request | ||
const requested = normalizeAddress(user!.address) | ||
|
||
const [mutualFriends, total] = await Promise.all([ | ||
db.getMutualFriends(requester, requested, pagination), | ||
db.getMutualFriendsCount(requester, requested) | ||
]) | ||
|
||
const profiles = await catalystClient.getEntitiesByPointers(mutualFriends.map((friend) => friend.address)) | ||
|
||
return { | ||
users: mutualFriends, | ||
friends: parseProfilesToFriends(profiles, profileImagesUrl), | ||
paginationData: { | ||
total, | ||
page: getPage(pagination?.limit || FRIENDSHIPS_PER_PAGE, pagination?.offset) | ||
} | ||
} | ||
} catch (error) { | ||
logger.error(error as any) | ||
// throw an error bc there is no sense to create a generator to send an error | ||
// as it's done in the previous Social Service | ||
throw new Error(INTERNAL_SERVER_ERROR) | ||
} catch (error: any) { | ||
logger.error(`Error getting mutual friends: ${error.message}`) | ||
return { | ||
friends: [], | ||
paginationData: { | ||
total: 0, | ||
page: 1 | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.