From f9c052a399c03a13e7ba9e685c46ecc27111b538 Mon Sep 17 00:00:00 2001 From: Adam Wootton Date: Thu, 5 Dec 2024 15:25:20 -0500 Subject: [PATCH 1/2] parallelize config fetch --- sdk/nextjs/src/server/bucketing.ts | 28 ++++++++++++++++++---------- sdk/nextjs/src/server/initialize.ts | 15 ++++++++------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/sdk/nextjs/src/server/bucketing.ts b/sdk/nextjs/src/server/bucketing.ts index 3c00a1b66..d5cead2eb 100644 --- a/sdk/nextjs/src/server/bucketing.ts +++ b/sdk/nextjs/src/server/bucketing.ts @@ -88,21 +88,14 @@ class CDNConfigSource extends ConfigSource { } } -/** - * Retrieve the config from CDN for the current request's SDK Key. This data will often be cached - * Compute the bucketed config for the current request's user using that data, with local bucketing library - * Cache the bucketed config for this request so that repeated calls to this function are memoized - */ -export const getBucketedConfig = async ( +export const getConfigFromSource = async ( sdkKey: string, clientSDKKey: string, - user: DevCycleUser, options: DevCycleNextOptions, - userAgent?: string, -): Promise => { +): Promise<{ config: ConfigBody; lastModified: string | null }> => { const cdnConfigSource = new CDNConfigSource(clientSDKKey) - const configSource = options.configSource ?? cdnConfigSource + const { config, lastModified } = await configSource.getConfig( sdkKey, 'bootstrap', @@ -111,6 +104,21 @@ export const getBucketedConfig = async ( true, ) + return { config, lastModified } +} + +/** + * Retrieve the config from CDN for the current request's SDK Key. This data will often be cached + * Compute the bucketed config for the current request's user using that data, with local bucketing library + * Cache the bucketed config for this request so that repeated calls to this function are memoized + */ +export const getBucketedConfig = async ( + config: ConfigBody, + lastModified: string | null, + user: DevCycleUser, + options: DevCycleNextOptions, + userAgent?: string, +): Promise => { const { bucketedConfig } = await generateBucketedConfigCached( !!options.enableObfuscation, user, diff --git a/sdk/nextjs/src/server/initialize.ts b/sdk/nextjs/src/server/initialize.ts index 0f4db52bb..d34c522dd 100644 --- a/sdk/nextjs/src/server/initialize.ts +++ b/sdk/nextjs/src/server/initialize.ts @@ -3,7 +3,7 @@ import { getClient, setClient } from './requestContext' import { getUserAgent } from './userAgent' import { DevCycleNextOptions, DevCycleServerData } from '../common/types' import { cache } from 'react' -import { getBucketedConfig } from './bucketing' +import { getBucketedConfig, getConfigFromSource } from './bucketing' const jsClientOptions = { // pass next object to enable "next" mode in JS SDK @@ -29,11 +29,12 @@ export const initialize = async ( userGetter: () => DevCycleUser | Promise, options: DevCycleNextOptions = {}, ): Promise => { - // TODO moving this call to inside `getBucketedConfig` appears to cause static build issues from reading headers - // Might be a bug in Next, if moving this make sure to verify you can `yarn next build` the e2e app router app - const userAgent = await getUserAgent(options) + const [userAgent, user, configData] = await Promise.all([ + getUserAgent(options), + cachedUserGetter(userGetter), + getConfigFromSource(sdkKey, clientSDKKey, options), + ]) - const user = await cachedUserGetter(userGetter) if (!user || typeof user.user_id !== 'string') { throw new Error('DevCycle user getter must return a user') } @@ -53,8 +54,8 @@ export const initialize = async ( let config = null try { config = await getBucketedConfig( - sdkKey, - clientSDKKey, + configData.config, + configData.lastModified, user, options, userAgent, From 3fe7e985d8c22385ce1ca4da32e817a305d58c56 Mon Sep 17 00:00:00 2001 From: Adam Wootton Date: Thu, 5 Dec 2024 15:28:15 -0500 Subject: [PATCH 2/2] update docs --- sdk/nextjs/src/server/bucketing.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/nextjs/src/server/bucketing.ts b/sdk/nextjs/src/server/bucketing.ts index d5cead2eb..a666c430a 100644 --- a/sdk/nextjs/src/server/bucketing.ts +++ b/sdk/nextjs/src/server/bucketing.ts @@ -108,8 +108,7 @@ export const getConfigFromSource = async ( } /** - * Retrieve the config from CDN for the current request's SDK Key. This data will often be cached - * Compute the bucketed config for the current request's user using that data, with local bucketing library + * Compute the bucketed config for the current request's user using raw config data, with local bucketing library * Cache the bucketed config for this request so that repeated calls to this function are memoized */ export const getBucketedConfig = async (