1 package ldcomponents 2 3 import ( 4 "time" 5 6 "github.com/launchdarkly/go-server-sdk/v6/subsystems" 7 "github.com/launchdarkly/go-server-sdk/v6/subsystems/ldstoreimpl" 8 ) 9 10 // DefaultBigSegmentsContextCacheSize is the default value for 11 // [BigSegmentsConfigurationBuilder.ContextCacheSize]. 12 const DefaultBigSegmentsContextCacheSize = 1000 13 14 // DefaultBigSegmentsContextCacheTime is the default value for 15 // [BigSegmentsConfigurationBuilder.ContextCacheTime]. 16 const DefaultBigSegmentsContextCacheTime = time.Second * 5 17 18 // DefaultBigSegmentsStatusPollInterval is the default value for 19 // [BigSegmentsConfigurationBuilder.StatusPollInterval]. 20 const DefaultBigSegmentsStatusPollInterval = time.Second * 5 21 22 // DefaultBigSegmentsStaleAfter is the default value for 23 // [BigSegmentsConfigurationBuilder.StaleAfter]. 24 const DefaultBigSegmentsStaleAfter = time.Second * 120 25 26 // BigSegmentsConfigurationBuilder contains methods for configuring the SDK's Big Segments behavior. 27 // 28 // "Big Segments" are a specific type of user segments. For more information, read the LaunchDarkly 29 // documentation about user segments: https://docs.launchdarkly.com/home/users 30 // 31 // If you want to set non-default values for any of these properties, create a builder with 32 // ldcomponents.[BigSegments](), change its properties with the BigSegmentsConfigurationBuilder 33 // methods, and store it in the BigSegments field of [github.com/launchdarkly/go-server-sdk/v6.Config]: 34 // 35 // config := ld.Config{ 36 // BigSegments: ldcomponents.BigSegments(ldredis.DataStore()). 37 // ContextCacheSize(2000). 38 // StaleAfter(time.Second * 60), 39 // } 40 // 41 // You only need to use the methods of BigSegmentsConfigurationBuilder if you want to customize 42 // options other than the data store itself. 43 type BigSegmentsConfigurationBuilder struct { 44 storeConfigurer subsystems.ComponentConfigurer[subsystems.BigSegmentStore] 45 config ldstoreimpl.BigSegmentsConfigurationProperties 46 } 47 48 // BigSegments returns a configuration builder for the SDK's Big Segments feature. 49 // 50 // "Big Segments" are a specific type of user segments. For more information, read the LaunchDarkly 51 // documentation about user segments: https://docs.launchdarkly.com/home/users 52 // 53 // After configuring this object, store it in the BigSegments field of your SDK configuration. For 54 // example, using the Redis integration: 55 // 56 // config := ld.Config{ 57 // BigSegments: ldcomponents.BigSegments(ldredis.BigSegmentStore().Prefix("app1")). 58 // ContextCacheSize(2000), 59 // } 60 // 61 // You must always specify the storeConfigurer parameter, to tell the SDK what database you are using. 62 // Several database integrations exist for the LaunchDarkly SDK, each with a configuration builder 63 // to that database; the BigSegmentsConfigurationBuilder adds configuration options for aspects of 64 // SDK behavior that are independent of the database. In the example above, Prefix() is an option 65 // specifically for the Redis integration, whereas ContextCacheSize() is an option that can be used 66 // for any data store type. 67 // 68 // If you do not set Config.BigSegments-- or if you pass a nil storeConfigurer to this function-- the 69 // Big Segments feature will be disabled, and any feature flags that reference a Big Segment will 70 // behave as if the evaluation context was not included in the segment. 71 func BigSegments( 72 storeConfigurer subsystems.ComponentConfigurer[subsystems.BigSegmentStore], 73 ) *BigSegmentsConfigurationBuilder { 74 return &BigSegmentsConfigurationBuilder{ 75 storeConfigurer: storeConfigurer, 76 config: ldstoreimpl.BigSegmentsConfigurationProperties{ 77 ContextCacheSize: DefaultBigSegmentsContextCacheSize, 78 ContextCacheTime: DefaultBigSegmentsContextCacheTime, 79 StatusPollInterval: DefaultBigSegmentsStatusPollInterval, 80 StaleAfter: DefaultBigSegmentsStaleAfter, 81 }, 82 } 83 } 84 85 // ContextCacheSize sets the maximum number of users whose Big Segment state will be cached by the SDK 86 // at any given time. The default value is [DefaultBigSegmentsContextCacheSize]. 87 // 88 // To reduce database traffic, the SDK maintains a least-recently-used cache by context key. When a feature 89 // flag that references a Big Segment is evaluated for some context that is not currently in the cache, the 90 // SDK queries the database for all Big Segment memberships of that context, and stores them together in a 91 // single cache entry. If the cache is full, the oldest entry is dropped. 92 // 93 // A higher value for ContextCacheSize means that database queries for Big Segments will be done less often 94 // for recently-referenced users, if the application has many users, at the cost of increased memory 95 // used by the cache. 96 // 97 // Cache entries can also expire based on the setting of [BigSegmentsConfigurationBuilder.ContextCacheTime]. 98 func (b *BigSegmentsConfigurationBuilder) ContextCacheSize( 99 contextCacheSize int, 100 ) *BigSegmentsConfigurationBuilder { 101 b.config.ContextCacheSize = contextCacheSize 102 return b 103 } 104 105 // ContextCacheTime sets the maximum length of time that the Big Segment state for an evaluation context will be 106 // cached by the SDK. The default value is [DefaultBigSegmentsContextCacheTime]. 107 // 108 // See [BigSegmentsConfigurationBuilder.ContextCacheSize] for more about this cache. A higher value for 109 // ContextCacheTime means that database queries for the Big Segment state of any given context will be done 110 // less often, but that changes to segment membership may not be detected as soon. 111 func (b *BigSegmentsConfigurationBuilder) ContextCacheTime( 112 contextCacheTime time.Duration, 113 ) *BigSegmentsConfigurationBuilder { 114 b.config.ContextCacheTime = contextCacheTime 115 return b 116 } 117 118 // StatusPollInterval sets the interval at which the SDK will poll the Big Segment store to make sure 119 // it is available and to determine how long ago it was updated. The default value is 120 // [DefaultBigSegmentsStatusPollInterval]. 121 func (b *BigSegmentsConfigurationBuilder) StatusPollInterval( 122 statusPollInterval time.Duration, 123 ) *BigSegmentsConfigurationBuilder { 124 if statusPollInterval <= 0 { 125 statusPollInterval = DefaultBigSegmentsStatusPollInterval 126 } 127 b.config.StatusPollInterval = statusPollInterval 128 return b 129 } 130 131 // StaleAfter sets the maximum length of time between updates of the Big Segments data before the data 132 // is considered out of date. The default value is [DefaultBigSegmentsStaleAfter]. 133 // 134 // Normally, the LaunchDarkly Relay Proxy updates a timestamp in the Big Segments store at intervals to 135 // confirm that it is still in sync with the LaunchDarkly data, even if there have been no changes to the 136 // data. If the timestamp falls behind the current time by the amount specified in StaleAfter, the SDK 137 // assumes that something is not working correctly in this process and that the data may not be accurate. 138 // 139 // While in a stale state, the SDK will still continue using the last known data, 140 // but LDClient.GetBigSegmentsStoreStatusProvider().GetStatus() will return true in its Stale property, 141 // and any [ldreason.EvaluationReason] generated from a feature flag that references a Big Segment will 142 // have an BigSegmentsStatus of [ldreason.BigSegmentsStale]. 143 func (b *BigSegmentsConfigurationBuilder) StaleAfter( 144 staleAfter time.Duration, 145 ) *BigSegmentsConfigurationBuilder { 146 b.config.StaleAfter = staleAfter 147 return b 148 } 149 150 // Build is called internally by the SDK. 151 func (b *BigSegmentsConfigurationBuilder) Build( 152 context subsystems.ClientContext, 153 ) (subsystems.BigSegmentsConfiguration, error) { 154 config := b.config 155 if b.storeConfigurer != nil { 156 store, err := b.storeConfigurer.Build(context) 157 if err != nil { 158 return nil, err 159 } 160 config.Store = store 161 } 162 return config, nil 163 } 164