-
Notifications
You must be signed in to change notification settings - Fork 31
fix(node-server-sdk): No FDv1 fallback when using custom datasystem #1088
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e2a9d38
35e43ca
6864953
e7a2241
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,8 @@ import ld, { | |
| LDOptions, | ||
| LDSerialExecution, | ||
| LDUser, | ||
| PollingDataSourceConfiguration, | ||
| StreamingDataSourceConfiguration, | ||
| } from '@launchdarkly/node-server-sdk'; | ||
|
|
||
| import BigSegmentTestStore from './BigSegmentTestStore.js'; | ||
|
|
@@ -36,7 +38,7 @@ interface SdkConfigOptions { | |
| }; | ||
| dataSystem?: { | ||
| initializers?: SDKDataSystemInitializerParams[]; | ||
| synchronizers?: SDKDataSystemSynchronizerParams; | ||
| synchronizers?: SDKDataSystemSynchronizerParams[]; | ||
| payloadFilter?: string; | ||
| }; | ||
| events?: { | ||
|
|
@@ -74,14 +76,8 @@ interface SdkConfigOptions { | |
| } | ||
|
|
||
| export interface SDKDataSystemSynchronizerParams { | ||
| primary?: { | ||
| streaming?: SDKDataSourceStreamingParams; | ||
| polling?: SDKDataSourcePollingParams; | ||
| }; | ||
| secondary?: { | ||
| streaming?: SDKDataSourceStreamingParams; | ||
| polling?: SDKDataSourcePollingParams; | ||
| }; | ||
| streaming?: SDKDataSourceStreamingParams; | ||
| polling?: SDKDataSourcePollingParams; | ||
| } | ||
|
|
||
| export interface SDKDataSystemInitializerParams { | ||
|
|
@@ -222,52 +218,54 @@ export function makeSdkConfig(options: SdkConfigOptions, tag: string): LDOptions | |
| } | ||
|
|
||
| if (options.dataSystem) { | ||
| const dataSourceStreamingOptions: SDKDataSourceStreamingParams | undefined = | ||
| options.dataSystem.synchronizers?.primary?.streaming ?? | ||
| options.dataSystem.synchronizers?.secondary?.streaming; | ||
| const dataSourcePollingOptions: SDKDataSourcePollingParams | undefined = | ||
| options.dataSystem.initializers?.[0]?.polling ?? | ||
| options.dataSystem.synchronizers?.primary?.polling ?? | ||
| options.dataSystem.synchronizers?.secondary?.polling; | ||
|
|
||
| if (dataSourceStreamingOptions) { | ||
| cf.streamUri = dataSourceStreamingOptions.baseUri; | ||
| cf.streamInitialReconnectDelay = maybeTime(dataSourceStreamingOptions.initialRetryDelayMs); | ||
| } | ||
| if (dataSourcePollingOptions) { | ||
| cf.stream = false; | ||
| cf.baseUri = dataSourcePollingOptions.baseUri; | ||
| cf.pollInterval = maybeTime(dataSourcePollingOptions.pollIntervalMs); | ||
| const dataSourceOptions: DataSourceOptions = { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. converting the datasystem to only use custom which allows us to ingest a more free form array of initializers/synchronizers
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we not have a fallback synchronizer to configure somewhere?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, later. |
||
| dataSourceOptionsType: 'custom', | ||
| initializers: [], | ||
| synchronizers: [], | ||
| }; | ||
|
|
||
| if (options.dataSystem.initializers) { | ||
| options.dataSystem.initializers.forEach((initializer) => { | ||
| if (initializer.polling) { | ||
| cf.baseUri = initializer.polling.baseUri; | ||
| cf.pollInterval = maybeTime(initializer.polling.pollIntervalMs); | ||
|
|
||
| const initializerOptions: PollingDataSourceConfiguration = { | ||
| type: 'polling', | ||
| pollInterval: maybeTime(initializer.polling.pollIntervalMs), | ||
| }; | ||
|
|
||
| dataSourceOptions.initializers.push(initializerOptions); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| let dataSourceOptions: DataSourceOptions | undefined; | ||
| if (dataSourceStreamingOptions && dataSourcePollingOptions) { | ||
| dataSourceOptions = { | ||
| dataSourceOptionsType: 'standard', | ||
| ...(dataSourceStreamingOptions.initialRetryDelayMs != null && { | ||
| streamInitialReconnectDelay: maybeTime(dataSourceStreamingOptions.initialRetryDelayMs), | ||
| }), | ||
| ...(dataSourcePollingOptions.pollIntervalMs != null && { | ||
| pollInterval: dataSourcePollingOptions.pollIntervalMs, | ||
| }), | ||
| }; | ||
| } else if (dataSourceStreamingOptions) { | ||
| dataSourceOptions = { | ||
| dataSourceOptionsType: 'streamingOnly', | ||
| ...(dataSourceStreamingOptions.initialRetryDelayMs != null && { | ||
| streamInitialReconnectDelay: maybeTime(dataSourceStreamingOptions.initialRetryDelayMs), | ||
| }), | ||
| }; | ||
| } else if (dataSourcePollingOptions) { | ||
| dataSourceOptions = { | ||
| dataSourceOptionsType: 'pollingOnly', | ||
| ...(dataSourcePollingOptions.pollIntervalMs != null && { | ||
| pollInterval: dataSourcePollingOptions.pollIntervalMs, | ||
| }), | ||
| }; | ||
| } else { | ||
| // No data source options were specified | ||
| dataSourceOptions = undefined; | ||
| if (options.dataSystem.synchronizers) { | ||
| options.dataSystem.synchronizers.forEach((synchronizer) => { | ||
| if (synchronizer.streaming) { | ||
| cf.streamUri = synchronizer.streaming.baseUri; | ||
|
|
||
| const synchronizerOptions: StreamingDataSourceConfiguration = { | ||
| type: 'streaming', | ||
| }; | ||
|
|
||
| synchronizerOptions.streamInitialReconnectDelay = maybeTime( | ||
| synchronizer.streaming.initialRetryDelayMs, | ||
| ); | ||
|
|
||
| dataSourceOptions.synchronizers.push(synchronizerOptions); | ||
| } else if (synchronizer.polling) { | ||
| cf.baseUri = synchronizer.polling.baseUri; | ||
| cf.pollInterval = maybeTime(synchronizer.polling.pollIntervalMs); | ||
|
|
||
| const synchronizerOptions: PollingDataSourceConfiguration = { | ||
| type: 'polling', | ||
| pollInterval: maybeTime(synchronizer.polling.pollIntervalMs), | ||
| }; | ||
|
|
||
| dataSourceOptions.synchronizers.push(synchronizerOptions); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| if (options.dataSystem.payloadFilter) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,6 @@ streaming/requests/URL path is computed correctly/environment_filter_key="encodi | |
| polling/requests/URL path is computed correctly/environment_filter_key="encoding_not_necessary"/base URI has no trailing slash/GET | ||
| polling/requests/URL path is computed correctly/environment_filter_key="encoding_not_necessary"/base URI has a trailing slash/GET | ||
|
|
||
| streaming/fdv2/reconnection state management/initializes from polling initializer | ||
| streaming/fdv2/reconnection state management/initializes from 2 polling initializers | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we remove any of these other suppressions with the updated config? |
||
| streaming/fdv2/reconnection state management/saves previously known state | ||
| streaming/fdv2/reconnection state management/replaces previously known state | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -437,19 +437,19 @@ function constructFDv2( | |
| ), | ||
| ); | ||
| } | ||
|
|
||
| // This is short term handling and will be removed once FDv2 adoption is sufficient. | ||
| fdv1FallbackSynchronizers.push( | ||
| () => | ||
| new PollingProcessorFDv2( | ||
| new Requestor(config, platform.requests, baseHeaders, '/sdk/latest-all', config.logger), | ||
| pollingInterval, | ||
| config.logger, | ||
| true, | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| // This is short term handling and will be removed once FDv2 adoption is sufficient. | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is moving it out of the top conditional:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, do we not allow you to configure it? I guess we may want to see if we standardize. We allow configuration of the fallback in java/dotnet. In case it needs different endpoints, or need to be streaming or something.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Created a task to track this. In general we don't have a way to customize uris for different synchronizer/initializer/fallback |
||
| fdv1FallbackSynchronizers.push( | ||
| () => | ||
| new PollingProcessorFDv2( | ||
| new Requestor(config, platform.requests, baseHeaders, '/sdk/latest-all', config.logger), | ||
| config.pollInterval ?? DEFAULT_POLL_INTERVAL, | ||
| config.logger, | ||
| true, | ||
| ), | ||
| ); | ||
|
|
||
| dataSource = new CompositeDataSource( | ||
| initializers, | ||
| synchronizers, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could use the downloader script to download the v3 version instead. But I am fine with this as well.