Skip to content

Commit

Permalink
fix: sdk not recovering from failure on first config fetch (#866)
Browse files Browse the repository at this point in the history
  • Loading branch information
elliotCamblor authored May 30, 2024
1 parent cdc5cd3 commit 9279ffa
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 13 deletions.
12 changes: 7 additions & 5 deletions lib/shared/config-manager/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type TrackSDKConfigEventInterface = (
) => void

export class EnvironmentConfigManager {
private hasConfig = false
private _hasConfig = false
configEtag?: string
configLastModified?: string
private readonly pollingIntervalMS: number
Expand Down Expand Up @@ -75,7 +75,9 @@ export class EnvironmentConfigManager {
}, this.pollingIntervalMS)
})
}

get hasConfig(): boolean {
return this._hasConfig
}
stopPolling(): void {
this.disablePolling = true
this.clearInterval(this.intervalTimeout)
Expand Down Expand Up @@ -106,7 +108,7 @@ export class EnvironmentConfigManager {
const errMsg =
`Request to get config failed for url: ${url}, ` +
`response message: ${error.message}, response data: ${projectConfig}`
if (this.hasConfig) {
if (this._hasConfig) {
this.logger.warn(errMsg)
} else {
this.logger.error(errMsg)
Expand Down Expand Up @@ -165,7 +167,7 @@ export class EnvironmentConfigManager {
`${this.sdkKey}${this.clientMode ? '_client' : ''}`,
projectConfig,
)
this.hasConfig = true
this._hasConfig = true
this.configEtag = res?.headers.get('etag') || ''
this.configLastModified =
res?.headers.get('last-modified') || ''
Expand All @@ -179,7 +181,7 @@ export class EnvironmentConfigManager {
}
}

if (this.hasConfig) {
if (this._hasConfig) {
this.logger.warn(
`Failed to download config, using cached version. url: ${url}.`,
)
Expand Down
25 changes: 24 additions & 1 deletion sdk/nodejs/__tests__/client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,30 @@ import { DevCycleClient } from '../src/client'
import { DevCycleUser } from '@devcycle/js-cloud-server-sdk'

jest.mock('../src/bucketing')
jest.mock('@devcycle/config-manager')
jest.mock('@devcycle/config-manager', () => {
return {
EnvironmentConfigManager: class {
hasConfig: boolean
config: unknown

constructor() {
this.hasConfig = true // Set hasConfig to true in the constructor
}

cleanup(): void {
return
}

getConfigURL(): string {
return 'url'
}

async _fetchConfig(): Promise<void> {
this.config = {}
}
},
}
})
jest.mock('../src/eventQueue')

describe('DevCycleClient', () => {
Expand Down
16 changes: 9 additions & 7 deletions sdk/nodejs/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ export class DevCycleClient {
this.onInitialized = initializePromise
.then(() => {
this.logger.info('DevCycle initialized')
this._isInitialized = true
return this
})
.catch((err) => {
Expand All @@ -148,6 +147,9 @@ export class DevCycleClient {
}
return this
})
.finally(() => {
this._isInitialized = true
})

process.on('exit', () => {
this.close()
Expand Down Expand Up @@ -209,9 +211,9 @@ export class DevCycleClient {
)
const populatedUser = DVCPopulatedUserFromDevCycleUser(incomingUser)

if (!this._isInitialized) {
if (!this.configHelper.hasConfig) {
this.logger.warn(
'variable called before DevCycleClient initialized, returning default value',
'variable called before DevCycleClient has config, returning default value',
)

this.eventQueue?.queueAggregateEvent(populatedUser, {
Expand Down Expand Up @@ -263,9 +265,9 @@ export class DevCycleClient {
allVariables(user: DevCycleUser): DVCVariableSet {
const incomingUser = castIncomingUser(user)

if (!this._isInitialized) {
if (!this.configHelper.hasConfig) {
this.logger.warn(
'allVariables called before DevCycleClient initialized',
'allVariables called before DevCycleClient has config',
)
return {}
}
Expand All @@ -278,9 +280,9 @@ export class DevCycleClient {
allFeatures(user: DevCycleUser): DVCFeatureSet {
const incomingUser = castIncomingUser(user)

if (!this._isInitialized) {
if (!this.configHelper.hasConfig) {
this.logger.warn(
'allFeatures called before DevCycleClient initialized',
'allFeatures called before DevCycleClient has config',
)
return {}
}
Expand Down

0 comments on commit 9279ffa

Please sign in to comment.