...

Source file src/github.com/launchdarkly/go-server-sdk/v6/ldcomponents/persistent_data_store_builder.go

Documentation: github.com/launchdarkly/go-server-sdk/v6/ldcomponents

     1  package ldcomponents
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/launchdarkly/go-sdk-common/v3/ldvalue"
     7  	"github.com/launchdarkly/go-server-sdk/v6/internal/datastore"
     8  	"github.com/launchdarkly/go-server-sdk/v6/subsystems"
     9  )
    10  
    11  // PersistentDataStoreDefaultCacheTime is the default amount of time that recently read or updated items
    12  // will be cached in memory, if you use [PersistentDataStore]. You can specify otherwise with
    13  // [PersistentDataStoreBuilder.CacheTime].
    14  const PersistentDataStoreDefaultCacheTime = 15 * time.Second
    15  
    16  // PersistentDataStore returns a configuration builder for some implementation of a persistent data store.
    17  //
    18  // The return value of this function should be stored in the DataStore field of
    19  // [github.com/launchdarkly/go-server-sdk/v6.Config].
    20  //
    21  // This method is used in conjunction with another configuration builder object provided by specific
    22  // packages such as the Redis integration. Each LaunchDarkly Go SDK database integration has a
    23  // DataStore() method that returns a configuration builder, with builder methods for options that
    24  // are specific to that database. The SDK also provides some universal behaviors for all persistent
    25  // data stores, such as caching; [PersistentDataStoreBuilder] provides methods to configure those
    26  // behaviors. For instance, in this example, URL() is an option that is specific to the Redis
    27  // integration, whereas CacheSeconds is not specific to Redis:
    28  //
    29  //	config := ld.Config{
    30  //	    DataStore: ldcomponents.PersistentDataStore(
    31  //	        ldredis.DataStore().URL("redis://my-redis-host"),
    32  //	    ).CacheSeconds(15),
    33  //	}
    34  //
    35  // See PersistentDataStoreBuilder for more on how this method is used.
    36  //
    37  // For more information on the available persistent data store implementations, see the reference
    38  // guide on "Persistent data stores": https://docs.launchdarkly.com/sdk/concepts/data-stores
    39  func PersistentDataStore(
    40  	persistentDataStoreFactory subsystems.ComponentConfigurer[subsystems.PersistentDataStore],
    41  ) *PersistentDataStoreBuilder {
    42  	return &PersistentDataStoreBuilder{
    43  		persistentDataStoreFactory: persistentDataStoreFactory,
    44  		cacheTTL:                   PersistentDataStoreDefaultCacheTime,
    45  	}
    46  }
    47  
    48  // PersistentDataStoreBuilder is a configurable factory for a persistent data store.
    49  //
    50  // Each LaunchDarkly Go SDK database integration has its own configuration builder, with builder methods
    51  // for options that are specific to that database. The SDK also provides some universal behaviors for all
    52  // persistent data stores, such as caching; PersistentDataStoreBuilder provides methods to configure those
    53  // behaviors. For instance, in this example, URL() is an option that is specific to the Redis
    54  // integration, whereas CacheSeconds is not specific to Redis:
    55  //
    56  //	config := ld.Config{
    57  //	    DataStore: ldcomponents.PersistentDataStore(
    58  //	        ldredis.DataStore().URL("redis://my-redis-host"),
    59  //	    ).CacheSeconds(15),
    60  //	}
    61  type PersistentDataStoreBuilder struct {
    62  	persistentDataStoreFactory subsystems.ComponentConfigurer[subsystems.PersistentDataStore]
    63  	cacheTTL                   time.Duration
    64  }
    65  
    66  // CacheTime specifies the cache TTL. Items will be evicted from the cache after this amount of time
    67  // from the time when they were originally cached.
    68  //
    69  // If the value is zero, caching is disabled (equivalent to [PersistentDataStoreBuilder.NoCaching]).
    70  //
    71  // If the value is negative, data is cached forever (equivalent to [PersistentDataStoreBuilder.CacheForever]).
    72  func (b *PersistentDataStoreBuilder) CacheTime(cacheTime time.Duration) *PersistentDataStoreBuilder {
    73  	b.cacheTTL = cacheTime
    74  	return b
    75  }
    76  
    77  // CacheSeconds is a shortcut for calling [PersistentDataStoreBuilder.CacheTime] with a duration in seconds.
    78  func (b *PersistentDataStoreBuilder) CacheSeconds(cacheSeconds int) *PersistentDataStoreBuilder {
    79  	return b.CacheTime(time.Duration(cacheSeconds) * time.Second)
    80  }
    81  
    82  // CacheForever specifies that the in-memory cache should never expire. In this mode, data will be
    83  // written to both the underlying persistent store and the cache, but will only ever be read from the
    84  // persistent store if the SDK is restarted.
    85  //
    86  // Use this mode with caution: it means that in a scenario where multiple processes are sharing
    87  // the database, and the current process loses connectivity to LaunchDarkly while other processes
    88  // are still receiving updates and writing them to the database, the current process will have
    89  // stale data.
    90  func (b *PersistentDataStoreBuilder) CacheForever() *PersistentDataStoreBuilder {
    91  	return b.CacheTime(-1 * time.Millisecond)
    92  }
    93  
    94  // NoCaching specifies that the SDK should not use an in-memory cache for the persistent data store.
    95  // This means that every feature flag evaluation will trigger a data store query.
    96  func (b *PersistentDataStoreBuilder) NoCaching() *PersistentDataStoreBuilder {
    97  	return b.CacheTime(0)
    98  }
    99  
   100  // Build is called internally by the SDK.
   101  func (b *PersistentDataStoreBuilder) Build(clientContext subsystems.ClientContext) (subsystems.DataStore, error) {
   102  	core, err := b.persistentDataStoreFactory.Build(clientContext)
   103  	if err != nil {
   104  		return nil, err
   105  	}
   106  	return datastore.NewPersistentDataStoreWrapper(core, clientContext.GetDataStoreUpdateSink(), b.cacheTTL,
   107  		clientContext.GetLogging().Loggers), nil
   108  }
   109  
   110  // DescribeConfiguration is used internally by the SDK to inspect the configuration.
   111  func (b *PersistentDataStoreBuilder) DescribeConfiguration(context subsystems.ClientContext) ldvalue.Value {
   112  	if dd, ok := b.persistentDataStoreFactory.(subsystems.DiagnosticDescription); ok {
   113  		return dd.DescribeConfiguration(context)
   114  	}
   115  	return ldvalue.String("custom")
   116  }
   117  

View as plain text