Skip to content

Commit

Permalink
[PLAT-814] Use sdk discovery-node-selection in libs (#3125)
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanjeffers authored Apr 5, 2023
1 parent 58005c4 commit 1d78774
Show file tree
Hide file tree
Showing 22 changed files with 242 additions and 194 deletions.
6 changes: 3 additions & 3 deletions packages/common/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"url": "https://github.com/AudiusProject/audius-client/issues"
},
"dependencies": {
"@audius/sdk": "2.0.3-beta.4",
"@audius/sdk": "2.0.3-beta.5",
"@fingerprintjs/fingerprintjs-pro": "3.5.6",
"@metaplex-foundation/mpl-token-metadata": "2.5.2",
"@optimizely/optimizely-sdk": "4.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ type AudiusAPIClientConfig = {
remoteConfigInstance: RemoteConfigInstance
localStorage: LocalStorage
env: Env
waitForLibsInit: () => Promise<unknown>
}

export class AudiusAPIClient {
Expand All @@ -516,21 +517,24 @@ export class AudiusAPIClient {
localStorage: LocalStorage
env: Env
isReachable?: boolean = true
waitForLibsInit: () => Promise<unknown>

constructor({
audiusBackendInstance,
getAudiusLibs,
overrideEndpoint,
remoteConfigInstance,
localStorage,
env
env,
waitForLibsInit
}: AudiusAPIClientConfig) {
this.audiusBackendInstance = audiusBackendInstance
this.getAudiusLibs = getAudiusLibs
this.overrideEndpoint = overrideEndpoint
this.remoteConfigInstance = remoteConfigInstance
this.localStorage = localStorage
this.env = env
this.waitForLibsInit = waitForLibsInit
}

setIsReachable(isReachable: boolean) {
Expand Down Expand Up @@ -1870,9 +1874,7 @@ export class AudiusAPIClient {
// Something went wrong with the request and we should wait for the libs
// initialization state if needed before retrying
if (this.initializationState.type === 'manual') {
// use wait for libs init from audius backend instance
// BEEP
// await waitForLibsInit()
await this.waitForLibsInit()
}
return this._getResponse(path, sanitizedParams, retry, pathType)
}
Expand Down
61 changes: 39 additions & 22 deletions packages/common/src/services/audius-backend/AudiusBackend.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { DiscoveryNodeSelector } from '@audius/sdk'
import { DiscoveryAPI } from '@audius/sdk/dist/core'
import type { HedgehogConfig } from '@audius/sdk/dist/services/hedgehog'
import type { LocalStorage } from '@audius/sdk/dist/utils/localStorage'
Expand Down Expand Up @@ -66,7 +67,6 @@ import {
} from '../../store'
import { CIDCache } from '../../store/cache/CIDCache'
import {
Nullable as totalUnviewed,
getErrorMessage,
uuid,
Maybe,
Expand All @@ -76,6 +76,7 @@ import {
Nullable,
removeNullable
} from '../../utils'
import type { DiscoveryNodeSelectorInstance } from '../discovery-node-selector'

import { MonitoringCallbacks } from './types'

Expand Down Expand Up @@ -179,7 +180,7 @@ type TransactionReceipt = { blockHash: string; blockNumber: number }
let preloadImageTimer: Timer
const avoidGC: HTMLImageElement[] = []

type DiscoveryProviderListener = (endpoint: totalUnviewed<string>) => void
type DiscoveryProviderListener = (endpoint: Nullable<string>) => void

type AudiusBackendSolanaConfig = Partial<{
claimableTokenPda: string
Expand Down Expand Up @@ -222,11 +223,12 @@ type AudiusBackendParams = {
ethProviderUrls: Maybe<string[]>
ethRegistryAddress: Maybe<string>
ethTokenAddress: Maybe<string>
discoveryNodeSelectorInstance: DiscoveryNodeSelectorInstance
getFeatureEnabled: (
flag: FeatureFlags,
fallbackFlag?: FeatureFlags
) => Promise<boolean | null> | null | boolean
getHostUrl: () => totalUnviewed<string>
getHostUrl: () => Nullable<string>
getLibs: () => Promise<any>
getWeb3Config: (
libs: any,
Expand Down Expand Up @@ -278,6 +280,7 @@ export const audiusBackend = ({
ethProviderUrls,
ethRegistryAddress,
ethTokenAddress,
discoveryNodeSelectorInstance,
getFeatureEnabled,
getHostUrl,
getLibs,
Expand Down Expand Up @@ -327,7 +330,7 @@ export const audiusBackend = ({
}: AudiusBackendParams) => {
const { getRemoteVar, waitForRemoteConfig } = remoteConfigInstance

const currentDiscoveryProvider: totalUnviewed<string> = null
const currentDiscoveryProvider: Nullable<string> = null
const didSelectDiscoveryProviderListeners: DiscoveryProviderListener[] = []

/**
Expand Down Expand Up @@ -355,7 +358,7 @@ export const audiusBackend = ({
}
}

function getCreatorNodeIPFSGateways(endpoint: totalUnviewed<string>) {
function getCreatorNodeIPFSGateways(endpoint: Nullable<string>) {
if (endpoint) {
return endpoint
.split(',')
Expand Down Expand Up @@ -429,7 +432,7 @@ export const audiusBackend = ({
creatorNodeGateways = [] as string[],
cache = true,
asUrl = true,
trackId: totalUnviewed<ID> = null
trackId: Nullable<ID> = null
) {
await waitForLibsInit()
try {
Expand Down Expand Up @@ -520,8 +523,8 @@ export const audiusBackend = ({
}

async function getImageUrl(
cid: totalUnviewed<CID>,
size: totalUnviewed<string>,
cid: Nullable<CID>,
size: Nullable<string>,
gateways: string[]
) {
if (!cid) return ''
Expand Down Expand Up @@ -668,7 +671,7 @@ export const audiusBackend = ({
SolanaUtils = libsModule.SolanaUtils
RewardsAttester = libsModule.RewardsAttester
// initialize libs
let libsError: totalUnviewed<string> = null
let libsError: Nullable<string> = null
const { web3Config } = await getWeb3Config(
AudiusLibs,
registryAddress,
Expand All @@ -687,6 +690,21 @@ export const audiusBackend = ({
StringKeys.DISCOVERY_NODE_BLOCK_LIST
)

const useSdkDiscoveryNodeSelector = await getFeatureEnabled(
FeatureFlags.SDK_V2
)

let discoveryNodeSelector: Maybe<DiscoveryNodeSelector>

if (useSdkDiscoveryNodeSelector) {
discoveryNodeSelector =
await discoveryNodeSelectorInstance.getDiscoveryNodeSelector()

discoveryNodeSelector.addEventListener('change', (endpoint) => {
discoveryProviderSelectionCallback(endpoint, [])
})
}

try {
audiusLibs = new AudiusLibs({
localStorage,
Expand All @@ -712,9 +730,10 @@ export const audiusBackend = ({
)
? getRemoteVar(IntKeys.DISCOVERY_NODE_MAX_SLOT_DIFF_PLAYS)
: null,
unhealthyBlockDiff: getRemoteVar(
IntKeys.DISCOVERY_NODE_MAX_BLOCK_DIFF
)
unhealthyBlockDiff:
getRemoteVar(IntKeys.DISCOVERY_NODE_MAX_BLOCK_DIFF) ?? undefined,

discoveryNodeSelector
},
identityServiceConfig:
AudiusLibs.configIdentityService(identityServiceUrl),
Expand Down Expand Up @@ -977,8 +996,8 @@ export const audiusBackend = ({
DiscoveryAPIParams<typeof DiscoveryAPI.getTracks>,
'sort' | 'filterDeleted'
> & {
sort: totalUnviewed<boolean>
filterDeleted: totalUnviewed<boolean>
sort: Nullable<boolean>
filterDeleted: Nullable<boolean>
}) {
try {
const tracks = await withEagerOption(
Expand Down Expand Up @@ -1547,8 +1566,8 @@ export const audiusBackend = ({
}

async function getPlaylists(
userId: totalUnviewed<ID>,
playlistIds: totalUnviewed<ID[]>,
userId: Nullable<ID>,
playlistIds: Nullable<ID[]>,
withUsers = true
): Promise<CollectionMetadata[]> {
try {
Expand Down Expand Up @@ -1890,8 +1909,8 @@ export const audiusBackend = ({
coverPhoto: File
}
hasWallet: boolean
referrer: totalUnviewed<ID>
feePayerOverride: totalUnviewed<string>
referrer: Nullable<ID>
feePayerOverride: Nullable<string>
}) {
await waitForLibsInit()
const metadata = schemas.newUserMetadata()
Expand Down Expand Up @@ -2458,13 +2477,12 @@ export const audiusBackend = ({
}) {
await waitForLibsInit()
const account = audiusLibs.Account.getCurrentUser()
if (!account) {
if (!account)
return {
message: 'error',
error: new Error('User not signed in'),
isRequestError: false
}
}
const encodedUserId = encodeHashId(account.user_id)

type DiscoveryNotificationsResponse = {
Expand All @@ -2491,7 +2509,6 @@ export const audiusBackend = ({
const { unread_count, notifications } = response

return {
message: 'success',
totalUnviewed: unread_count,
notifications: notifications.map(
mapDiscoveryNotification
Expand Down Expand Up @@ -3483,7 +3500,7 @@ export const audiusBackend = ({
endpoints: string[]
AAOEndpoint: string
parallelization: number
feePayerOverride: totalUnviewed<string>
feePayerOverride: Nullable<string>
isFinalAttempt: boolean
}) {
await waitForLibsInit()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import {
developmentConfig,
DiscoveryNodeSelector,
productionConfig,
stagingConfig
} from '@audius/sdk'

import { Env } from '../env'
import {
BooleanKeys,
IntKeys,
RemoteConfigInstance,
StringKeys
} from '../remote-config'

type DiscoveryNodeSelectorConfig = {
env: Env
remoteConfigInstance: RemoteConfigInstance
}

export class DiscoveryNodeSelectorInstance {
private env: Env
private remoteConfigInstance: RemoteConfigInstance
private discoveryNodeSelectorPromise: Promise<DiscoveryNodeSelector> | null

constructor(config: DiscoveryNodeSelectorConfig) {
const { env, remoteConfigInstance } = config
this.env = env
this.remoteConfigInstance = remoteConfigInstance
this.discoveryNodeSelectorPromise = null
}

private async makeDiscoveryNodeSelector() {
const { getRemoteVar, waitForRemoteConfig } = this.remoteConfigInstance

await waitForRemoteConfig()

const bootstrapConfig =
this.env.ENVIRONMENT === 'development'
? developmentConfig
: this.env.ENVIRONMENT === 'staging'
? stagingConfig
: productionConfig

const { minVersion, discoveryNodes } = bootstrapConfig

const maxBlockDiff =
getRemoteVar(IntKeys.DISCOVERY_NODE_MAX_BLOCK_DIFF) ?? undefined
const maxSlotDiffPlays = getRemoteVar(
BooleanKeys.ENABLE_DISCOVERY_NODE_MAX_SLOT_DIFF_PLAYS
)
? getRemoteVar(IntKeys.DISCOVERY_NODE_MAX_SLOT_DIFF_PLAYS)
: null

const healthCheckThresholds = { minVersion, maxBlockDiff, maxSlotDiffPlays }

const blocklist = this.getBlockList(StringKeys.DISCOVERY_NODE_BLOCK_LIST)

const requestTimeout =
getRemoteVar(IntKeys.DISCOVERY_PROVIDER_SELECTION_TIMEOUT_MS) ?? undefined

return new DiscoveryNodeSelector({
healthCheckThresholds,
blocklist,
requestTimeout,
bootstrapServices: discoveryNodes
})
}

private getBlockList(remoteVarKey: StringKeys) {
const list = this.remoteConfigInstance.getRemoteVar(remoteVarKey)
if (list) {
try {
return new Set<string>(list.split(','))
} catch (e) {
console.error(e)
return null
}
}
return null
}

public async getDiscoveryNodeSelector() {
if (!this.discoveryNodeSelectorPromise) {
this.discoveryNodeSelectorPromise = this.makeDiscoveryNodeSelector()
}
return await this.discoveryNodeSelectorPromise
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './DiscoveryNodeSelectorInstance'
1 change: 1 addition & 0 deletions packages/common/src/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export * from './cognito'
export * from './track-download'
export * from './oauth'
export * from './location'
export * from './discovery-node-selector'
6 changes: 4 additions & 2 deletions packages/common/src/services/remote-config/feature-flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ export enum FeatureFlags {
TRENDING_PLAYLIST_NOTIFICATIONS = 'trending_playlist_notifications',
TRENDING_UNDERGROUND_NOTIFICATIONS = 'trending_underground_notifications',
TASTEMAKER_NOTIFICATIONS = 'tastemaker_notifications',
STORAGE_V2 = 'storage_v2'
STORAGE_V2 = 'storage_v2',
SDK_V2 = 'sdk_v2'
}

type FlagDefaults = Record<FeatureFlags, boolean>
Expand Down Expand Up @@ -108,5 +109,6 @@ export const flagDefaults: FlagDefaults = {
[FeatureFlags.TRENDING_PLAYLIST_NOTIFICATIONS]: false,
[FeatureFlags.TRENDING_UNDERGROUND_NOTIFICATIONS]: false,
[FeatureFlags.TASTEMAKER_NOTIFICATIONS]: false,
[FeatureFlags.STORAGE_V2]: false
[FeatureFlags.STORAGE_V2]: false,
[FeatureFlags.SDK_V2]: false
}
4 changes: 2 additions & 2 deletions packages/common/src/store/pages/chat/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChatEvents, type sdk } from '@audius/sdk'
import { type AudiusSdk, ChatEvents } from '@audius/sdk'
import { Middleware } from 'redux'

import { Status } from 'models/Status'
Expand All @@ -14,7 +14,7 @@ const {
} = chatActions

export const chatMiddleware =
(audiusSdk: () => Promise<ReturnType<typeof sdk>>): Middleware =>
(audiusSdk: () => Promise<AudiusSdk>): Middleware =>
(store) => {
let messageListener: ChatEvents['message'] | null = null
let reactionListener: ChatEvents['reaction'] | null = null
Expand Down
Loading

0 comments on commit 1d78774

Please sign in to comment.