Documentation

Overview

Package interfaces contains interfaces that allow customization of LaunchDarkly components, and interfaces to other advanced SDK features.

Most applications will not need to refer to these types. You will use them if you are creating a plug-in component, such as a database integration, or if you use advanced SDK features.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BasicConfiguration

type BasicConfiguration struct {
	// SDKKey is the configured SDK key.
	SDKKey string

	// Offline is true if the client was configured to be completely offline.
	Offline bool
}

BasicConfiguration contains the most basic properties of the SDK client that are available to all SDK component factories.

type ClientContext

type ClientContext interface {
	// GetBasicConfiguration returns the SDK's basic global properties.
	GetBasic() BasicConfiguration
	// GetHTTP returns the configured HTTPConfiguration.
	GetHTTP() HTTPConfiguration
	// GetLogging returns the configured LoggingConfiguration.
	GetLogging() LoggingConfiguration
}

ClientContext provides context information from LDClient when creating other components.

This is passed as a parameter to the factory methods for implementations of DataStore, DataSource, etc. The actual implementation type may contain other properties that are only relevant to the built-in SDK components and are therefore not part of the public interface; this allows the SDK to add its own context information as needed without disturbing the public API.

type DataSource

type DataSource interface {
	io.Closer

	// IsInitialized returns true if the data source has successfully initialized at some point.
	//
	// Once this is true, it should remain true even if a problem occurs later.
	IsInitialized() bool

	// Start tells the data source to begin initializing. It should not try to make any connections
	// or do any other significant activity until Start is called.
	//
	// The data source should close the closeWhenReady channel if and when it has either successfully
	// initialized for the first time, or determined that initialization cannot ever succeed.
	Start(closeWhenReady chan<- struct{})
}

DataSource describes the interface for an object that receives feature flag data.

type DataSourceErrorInfo

type DataSourceErrorInfo struct {
	// Kind is the general category of the error. It will always be one of the DataSourceErrorKind
	// constants such as DataSourceErrorKindNetworkError, or "" if there have not been any errors.
	Kind DataSourceErrorKind

	// StatusCode is the HTTP status code if the error was DataSourceErrorKindErrorResponse, or zero
	// otherwise.
	StatusCode int

	// Message is any any additional human-readable information relevant to the error. The format of
	// this message is subject to change and should not be relied on programmatically.
	Message string

	// Time is the date/time that the error occurred.
	Time time.Time
}

DataSourceErrorInfo is a description of an error condition that the data source encountered.

See DataSourceStatusProvider.

func (DataSourceErrorInfo) String

func (e DataSourceErrorInfo) String() string

String returns a simple string representation of the error.

type DataSourceErrorKind

type DataSourceErrorKind string

DataSourceErrorKind is any of the allowable values for DataSourceErrorInfo.Kind.

See DataSourceStatusProvider.

const (
	// DataSourceErrorKindUnknown indicates an unexpected error, such as an uncaught exception,
	// further described by DataSourceErrorInfo.Message.
	DataSourceErrorKindUnknown DataSourceErrorKind = "UNKNOWN"

	// DataSourceErrorKindNetworkError represents an I/O error such as a dropped connection.
	DataSourceErrorKindNetworkError DataSourceErrorKind = "NETWORK_ERROR"

	// DataSourceErrorKindErrorResponse means the LaunchDarkly service returned an HTTP response
	// with an error status, available in DataSourceErrorInfo.StatusCode.
	DataSourceErrorKindErrorResponse DataSourceErrorKind = "ERROR_RESPONSE"

	// DataSourceErrorKindInvalidData means the SDK received malformed data from the LaunchDarkly
	// service.
	DataSourceErrorKindInvalidData DataSourceErrorKind = "INVALID_DATA"

	// DataSourceErrorKindStoreError means the data source itself is working, but when it tried
	// to put an update into the data store, the data store failed (so the SDK may not have the
	// latest data).
	//
	// Data source implementations do not need to report this kind of error; it will be
	// automatically reported by the SDK whenever one of the update methods of DataSourceUpdates
	// encounters a failure.
	DataSourceErrorKindStoreError DataSourceErrorKind = "STORE_ERROR"
)

type DataSourceFactory

type DataSourceFactory interface {
	// CreateDataSource is called by the SDK to create the implementation instance.
	//
	// This happens only when MakeClient or MakeCustomClient is called. The implementation instance
	// is then tied to the life cycle of the LDClient, so it will receive a Close() call when the
	// client is closed.
	//
	// If the factory returns an error, creation of the LDClient fails.
	//
	// The dataSourceUpdates parameter is an object that the DataSource can use to push status
	// updates into the SDK. It should always call dataSourceUpdates.UpdateStatus to report when
	// it is working correctly or when it encounters an error.
	CreateDataSource(
		context ClientContext,
		dataSourceUpdates DataSourceUpdates,
	) (DataSource, error)
}

DataSourceFactory is a factory that creates some implementation of DataSource.

type DataSourceState

type DataSourceState string

DataSourceState is any of the allowable values for DataSourceStatus.State.

See DataSourceStatusProvider.

const (
	// DataSourceStateInitializing is the initial state of the data source when the SDK is being
	// initialized.
	//
	// If it encounters an error that requires it to retry initialization, the state will remain at
	// Initializing until it either succeeds and becomes DataSourceStateValid, or permanently fails and
	// becomes DataSourceStateOff.
	DataSourceStateInitializing DataSourceState = "INITIALIZING"

	// DataSourceStateValid indicates that the data source is currently operational and has not had
	// any problems since the last time it received data.
	//
	// In streaming mode, this means that there is currently an open stream connection and that at least
	// one initial message has been received on the stream. In polling mode, it means that the last poll
	// request succeeded.
	DataSourceStateValid DataSourceState = "VALID"

	// DataSourceStateInterrupted indicates that the data source encountered an error that it will
	// attempt to recover from.
	//
	// In streaming mode, this means that the stream connection failed, or had to be dropped due to some
	// other error, and will be retried after a backoff delay. In polling mode, it means that the last poll
	// request failed, and a new poll request will be made after the configured polling interval.
	DataSourceStateInterrupted DataSourceState = "INTERRUPTED"

	// DataSourceStateOff indicates that the data source has been permanently shut down.
	//
	// This could be because it encountered an unrecoverable error (for instance, the LaunchDarkly service
	// rejected the SDK key; an invalid SDK key will never become valid), or because the SDK client was
	// explicitly shut down.
	DataSourceStateOff DataSourceState = "OFF"
)

type DataSourceStatus

type DataSourceStatus struct {
	// State represents the overall current state of the data source. It will always be one of the
	// DataSourceState constants such as DataSourceStateValid.
	State DataSourceState

	// StateSince is the date/time that the value of State most recently changed.
	//
	// The meaning of this depends on the current State:
	//
	// - For DataSourceStateInitializing, it is the time that the SDK started initializing.
	//
	// - For DataSourceStateValid, it is the time that the data source most recently entered a valid
	// state, after previously having been either Initializing or Interrupted.
	//
	// - For DataSourceStateInterrupted, it is the time that the data source most recently entered an
	// error state, after previously having been Valid.
	//
	// - For DataSourceStateOff, it is the time that the data source encountered an unrecoverable error
	// or that the SDK was explicitly shut down.
	StateSince time.Time

	// LastError is information about the last error that the data source encountered, if any.
	//
	// This property should be updated whenever the data source encounters a problem, even if it does
	// not cause State to change. For instance, if a stream connection fails and the
	// state changes to DataSourceStateInterrupted, and then subsequent attempts to restart the
	// connection also fail, the state will remain Interrupted but the error information
	// will be updated each time-- and the last error will still be reported in this property even if
	// the state later becomes Valid.
	//
	// If no error has ever occurred, this field will be an empty DataSourceErrorInfo{}.
	LastError DataSourceErrorInfo
}

DataSourceStatus is information about the data source's status and the last status change.

See DataSourceStatusProvider.

func (DataSourceStatus) String

func (e DataSourceStatus) String() string

String returns a simple string representation of the status.

type DataSourceStatusProvider

type DataSourceStatusProvider interface {
	// GetStatus returns the current status of the data source.
	//
	// All of the built-in data source implementations are guaranteed to update this status whenever they
	// successfully initialize, encounter an error, or recover after an error.
	GetStatus() DataSourceStatus

	// AddStatusListener subscribes for notifications of status changes. The returned channel will receive a
	// new DataSourceStatus value for any change in status.
	//
	// The listener will be notified whenever any property of the status has changed. See DataSourceStatus for
	// an explanation of the meaning of each property and what could cause it to change.
	//
	// It is the caller's responsibility to consume values from the channel. Allowing values to accumulate in
	// the channel can cause an SDK goroutine to be blocked. If you no longer need the channel, call
	// RemoveStatusListener.
	AddStatusListener() <-chan DataSourceStatus

	// RemoveStatusListener unsubscribes from notifications of status changes. The specified channel must be
	// one that was previously returned by AddStatusListener(); otherwise, the method has no effect.
	RemoveStatusListener(listener <-chan DataSourceStatus)

	// WaitFor is a synchronous method for waiting for a desired connection state.
	//
	// If the current state is already desiredState when this method is called, it immediately returns.
	// Otherwise, it blocks until 1. the state has become desiredState, 2. the state has become
	// DataSourceStateOff (since that is a permanent condition), or 3. the specified timeout elapses.
	//
	// A scenario in which this might be useful is if you want to create the LDClient without waiting
	// for it to initialize, and then wait for initialization at a later time or on a different goroutine:
	//
	//     // create the client but do not wait
	//     client = ld.MakeCustomClient(sdkKey, config, 0)
	//
	//     // later, possibly on another goroutine:
	//     inited := client.GetDataSourceStatusProvider().WaitFor(DataSourceStateValid, 10 * time.Second)
	//     if !inited {
	//         // do whatever is appropriate if initialization has timed out
	//     }
	WaitFor(desiredState DataSourceState, timeout time.Duration) bool
}

DataSourceStatusProvider is an interface for querying the status of a DataSource. The data source is the component that receives updates to feature flag data; normally this is a streaming connection, but it could be polling or file data depending on your configuration.

An implementation of this interface is returned by LDClient.GetDataSourceStatusProvider(). Application code never needs to implement this interface.

There are three ways to interact with the data source status. One is to simply get the current status; if its State property is DataSourceStateValid, then the SDK is able to receive feature flag updates.

status := client.GetDataSourceStatusProvider().GetStatus()
isValid = status.State == interfaces.DataSourceStateValid

Second, you can use AddStatusListener to get a channel that provides a status update whenever the connection has an error or starts working again.

statusCh := client.GetDataSourceStatusProvider().AddStatusListener()
go func() {
    for newStatus := range statusCh {
        log.Printf("data source status is now: %+v", newStatus)
    }
}()

Third, you can use WaitFor to block until the data source has the desired status. For instance, if you did not want to wait for a connection when you originally created the client, you could set the timeout to zero so that the connection happens in the background. Then, when you need to do something that requires a valid connection (possibly on another goroutine), you can wait until it is valid.

client, _ := ld.MakeCustomClient(sdkKey, config, 0)

// later...
inited := client.GetDataSourceStatusProvider().WaitFor(interfaces.DataSourceStateValid, 10 * time.Second)
if !inited {
    // do whatever is appropriate if initialization has timed out
}

type DataSourceUpdates

type DataSourceUpdates interface {
	// Init overwrites the current contents of the data store with a set of items for each collection.
	//
	// If the underlying data store returns an error during this operation, the SDK will log it,
	// and set the data source state to DataSourceStateInterrupted with an error of
	// DataSourceErrorKindStoreError. It will not return the error to the data source, but will
	// return false to indicate that the operation failed.
	Init(allData []ldstoretypes.Collection) bool

	// Upsert updates or inserts an item in the specified collection. For updates, the object will only be
	// updated if the existing version is less than the new version.
	//
	// To mark an item as deleted, pass an ItemDescriptor with a nil Item and a nonzero version
	// number. Deletions must be versioned so that they do not overwrite a later update in case updates
	// are received out of order.
	//
	// If the underlying data store returns an error during this operation, the SDK will log it,
	// and set the data source state to DataSourceStateInterrupted with an error of
	// DataSourceErrorKindStoreError. It will not return the error to the data source, but will
	// return false to indicate that the operation failed.
	Upsert(kind ldstoretypes.DataKind, key string, item ldstoretypes.ItemDescriptor) bool

	// UpdateStatus informs the SDK of a change in the data source's status.
	//
	// Data source implementations should use this method if they have any concept of being in a valid
	// state, a temporarily disconnected state, or a permanently stopped state.
	//
	// If newState is different from the previous state, and/or newError is non-empty, the SDK
	// will start returning the new status (adding a timestamp for the change) from
	// DataSourceStatusProvider.GetStatus(), and will trigger status change events to any
	// registered listeners.
	//
	// A special case is that if newState is DataSourceStateInterrupted, but the previous state was
	// but the previous state was DataSourceStateInitializing, the state will remain at Initializing
	// because Interrupted is only meaningful after a successful startup.
	UpdateStatus(newState DataSourceState, newError DataSourceErrorInfo)

	// GetDataStoreStatusProvider returns an object that provides status tracking for the data store, if
	// applicable.
	//
	// This may be useful if the data source needs to be aware of storage problems that might require it
	// to take some special action: for instance, if a database outage may have caused some data to be
	// lost and therefore the data should be re-requested from LaunchDarkly.
	GetDataStoreStatusProvider() DataStoreStatusProvider
}

DataSourceUpdates is an interface that a data source implementation will use to push data into the SDK.

Application code does not need to use this type. It is for data source implementations.

The data source interacts with this object, rather than manipulating the data store directly, so that the SDK can perform any other necessary operations that must happen when data is updated.

type DataStore

type DataStore interface {
	io.Closer

	// Init overwrites the store's contents with a set of items for each collection.
	//
	// All previous data should be discarded, regardless of versioning.
	//
	// The update should be done atomically. If it cannot be done atomically, then the store
	// must first add or update each item in the same order that they are given in the input
	// data, and then delete any previously stored items that were not in the input data.
	Init(allData []ldstoretypes.Collection) error

	// Get retrieves an item from the specified collection, if available.
	//
	// If the specified key does not exist in the collection, it should return an ItemDescriptor
	// whose Version is -1.
	//
	// If the item has been deleted and the store contains a placeholder, it should return an
	// ItemDescriptor whose Version is the version of the placeholder, and whose Item is nil.
	Get(kind ldstoretypes.DataKind, key string) (ldstoretypes.ItemDescriptor, error)

	// GetAll retrieves all items from the specified collection.
	//
	// If the store contains placeholders for deleted items, it should include them in the results,
	// not filter them out.
	GetAll(kind ldstoretypes.DataKind) ([]ldstoretypes.KeyedItemDescriptor, error)

	// Upsert updates or inserts an item in the specified collection. For updates, the object will only be
	// updated if the existing version is less than the new version.
	//
	// The SDK may pass an ItemDescriptor whose Item is nil, to represent a placeholder for a deleted
	// item. In that case, assuming the version is greater than any existing version of that item, the
	// store should retain that placeholder rather than simply not storing anything.
	//
	// The method returns true if the item was updated, or false if it was not updated because the store
	// contains an equal or greater version.
	Upsert(kind ldstoretypes.DataKind, key string, item ldstoretypes.ItemDescriptor) (bool, error)

	// IsInitialized returns true if the data store contains a data set, meaning that Init has been
	// called at least once.
	//
	// In a shared data store, it should be able to detect this even if Init was called in a
	// different process: that is, the test should be based on looking at what is in the data store.
	// Once this has been determined to be true, it can continue to return true without having to
	// check the store again; this method should be as fast as possible since it may be called during
	// feature flag evaluations.
	IsInitialized() bool

	// IsStatusMonitoringEnabled returns true if this data store implementation supports status
	// monitoring.
	//
	// This is normally only true for persistent data stores created with ldcomponents.PersistentDataStore(),
	// but it could also be true for any custom DataStore implementation that makes use of the
	// statusUpdater parameter provided to the DataStoreFactory. Returning true means that the store
	// guarantees that if it ever enters an invalid state (that is, an operation has failed or it knows
	// that operations cannot succeed at the moment), it will publish a status update, and will then
	// publish another status update once it has returned to a valid state.
	//
	// The same value will be returned from DataStoreStatusProvider.IsStatusMonitoringEnabled().
	IsStatusMonitoringEnabled() bool
}

DataStore is an interface for a data store that holds feature flags and related data received by the SDK.

Ordinarily, the only implementations of this interface are the default in-memory implementation, which holds references to actual SDK data model objects, and the persistent data store implementation that delegates to a PersistentDataStore.

type DataStoreFactory

type DataStoreFactory interface {
	// CreateDataStore is called by the SDK to create the implementation instance.
	//
	// This happens only when MakeClient or MakeCustomClient is called. The implementation instance
	// is then tied to the life cycle of the LDClient, so it will receive a Close() call when the
	// client is closed.
	//
	// If the factory returns an error, creation of the LDClient fails.
	CreateDataStore(context ClientContext, dataStoreUpdates DataStoreUpdates) (DataStore, error)
}

DataStoreFactory is a factory that creates some implementation of DataStore.

type DataStoreStatus

type DataStoreStatus struct {
	// Available is true if the SDK believes the data store is now available.
	//
	// This property is normally true. If the SDK receives an exception while trying to query or update the
	// data store, then it sets this property to false (notifying listeners, if any) and polls the store at
	// intervals until a query succeeds. Once it succeeds, it sets the property back to true (again
	// notifying listeners).
	Available bool

	// NeedsRefresh is true if the store may be out of date due to a previous outage, so the SDK should
	// attempt to refresh all feature flag data and rewrite it to the store.
	//
	// This property is not meaningful to application code.
	NeedsRefresh bool
}

DataStoreStatus contains information about the status of a data store, provided by DataStoreStatusProvider.

type DataStoreStatusProvider

type DataStoreStatusProvider interface {
	// GetStatus returns the current status of the store.
	//
	// This is only meaningful for persistent stores, or any other DataStore implementation that makes use of
	// the reporting mechanism that is provided by DataStoreUpdates. For the default in-memory store, the
	// status will always be reported as "available".
	GetStatus() DataStoreStatus

	// Indicates whether the current data store implementation supports status monitoring.
	//
	// This is normally true for all persistent data stores, and false for the default in-memory store. A true
	// value means that any listeners added with AddStatusListener() can expect to be notified if there is
	// there is any error in storing data, and then notified again when the error condition is resolved. A
	// false value means that the status is not meaningful and listeners should not expect to be notified.
	IsStatusMonitoringEnabled() bool

	// AddStatusListener subscribes for notifications of status changes. The returned channel will receive a
	// new DataStoreStatus value for any change in status.
	//
	// Applications may wish to know if there is an outage in a persistent data store, since that could mean
	// that flag evaluations are unable to get the flag data from the store (unless it is currently cached) and
	// therefore might return default values.
	//
	// If the SDK receives an exception while trying to query or update the data store, then it publishes a
	// DataStoreStatus where Available is false, to indicate that the store appears to be offline, and begins
	// polling the store at intervals until a query succeeds. Once it succeeds, it publishes a new status where
	// Available is true.
	//
	// If the data store implementation does not support status tracking, such as if you are using the default
	// in-memory store rather than a persistent store, it will return a channel that never receives values.
	//
	// It is the caller's responsibility to consume values from the channel. Allowing values to accumulate in
	// the channel can cause an SDK goroutine to be blocked. If you no longer need the channel, call
	// RemoveStatusListener.
	AddStatusListener() <-chan DataStoreStatus

	// RemoveStatusListener unsubscribes from notifications of status changes. The specified channel must be
	// one that was previously returned by AddStatusListener(); otherwise, the method has no effect.
	RemoveStatusListener(<-chan DataStoreStatus)
}

DataStoreStatusProvider is an interface for querying the status of a persistent data store.

An implementation of this interface is returned by LDClient.GetDataStoreStatusProvider(). Application code should not implement this interface.

There are two ways to interact with the data store status. One is to simply get the current status; if its Available property is true, then the store is working normally.

status := client.GetDataStoreStatusProvider().GetStatus()
isValid = status.Available

Second, you can use AddStatusListener to get a channel that provides a status update whenever the data store has an error or starts working again.

statusCh := client.GetDataStoreStatusProvider().AddStatusListener()
go func() {
    for newStatus := range statusCh {
        log.Printf("data store Available is %t", newStatus.Available)
    }
}()

type DataStoreUpdates

type DataStoreUpdates interface {
	// UpdateStatus informs the SDK of a change in the data store's operational status.
	//
	// This is what makes the status monitoring mechanisms in DataStoreStatusProvider work.
	UpdateStatus(newStatus DataStoreStatus)
}

DataStoreUpdates is an interface that a data store implementation can use to report information back to the SDK.

Application code does not need to use this type. It is for data store implementations.

The DataStoreFactory receives an implementation of this interface and can pass it to the data store that it creates, if desired.

type DiagnosticDescription

type DiagnosticDescription interface {
	// DescribeConfiguration should return a JSON value or ldvalue.Null().
	//
	// For custom components, this must be a string value that describes the basic nature of this component
	// implementation (e.g. "Redis"). Built-in LaunchDarkly components may instead return a JSON object
	// containing multiple properties specific to the LaunchDarkly diagnostic schema.
	DescribeConfiguration() ldvalue.Value
}

DiagnosticDescription is an optional interface for components to describe their own configuration.

The SDK uses a simplified JSON representation of its configuration when recording diagnostics data. Any component type that implements DataStoreFactory, DataSourceFactory, etc. may choose to contribute values to this representation, although the SDK may or may not use them.

type EventProcessorFactory

type EventProcessorFactory interface {
	// CreateEventProcessor is called by the SDK to create the implementation instance.
	//
	// This happens only when MakeClient or MakeCustomClient is called. The implementation instance
	// is then tied to the life cycle of the LDClient, so it will receive a Close() call when the
	// client is closed.
	//
	// If the factory returns an error, creation of the LDClient fails.
	CreateEventProcessor(context ClientContext) (ldevents.EventProcessor, error)
}

EventProcessorFactory is a factory that creates some implementation of EventProcessor.

The EventProcessor component is responsible for computing and sending analytics events. Applications will normally use one of two implementations: ldcomponents.SendEvents(), which enables events and provides builder options for configuring them, or ldcomponents.NoEvents(), which disables events.

The interface and its standard implementation are defined in the go-sdk-events package (which is in a separate repository because it is also used by other LaunchDarkly components) and applications normally do not need to interact with it directly, except for testing purposes or if an alternate event storage mechanism is needed.

type FlagChangeEvent

type FlagChangeEvent struct {
	// Key is the key of the feature flag whose configuration has changed.
	//
	// The specified flag may have been modified directly, or this may be an indirect change due to a change
	// in some other flag that is a prerequisite for this flag, or a user segment that is referenced in the
	// flag's rules.
	Key string
}

FlagChangeEvent is a parameter type used with FlagTracker.AddFlagChangeListener().

This is not an analytics event to be sent to LaunchDarkly; it is a notification to the application.

type FlagTracker

type FlagTracker interface {
	// AddFlagChangeListener subscribes for notifications of feature flag changes in general.
	//
	// The returned channel will receive a new FlagChangeEvent value whenever the SDK receives any change to
	// any feature flag's configuration, or to a user segment that is referenced by a feature flag. If the
	// updated flag is used as a prerequisite for other flags, the SDK assumes that those flags may now
	// behave differently and sends flag change events for them as well.
	//
	// Note that this does not necessarily mean the flag's value has changed for any particular user, only that
	// some part of the flag configuration was changed so that it may return a different value than it
	// previously returned for some user. If you want to track flag value changes, use
	// AddFlagValueChangeListener instead.
	//
	// Change events only work if the SDK is actually connecting to LaunchDarkly (or using the file data source).
	// If the SDK is only reading flags from a database (ldcomponents.ExternalUpdatesOnly) then it cannot
	// know when there is a change, because flags are read on an as-needed basis.
	//
	// It is the caller's responsibility to consume values from the channel. Allowing values to accumulate in
	// the channel can cause an SDK goroutine to be blocked.
	AddFlagChangeListener() <-chan FlagChangeEvent

	// RemoveFlagChangeListener unsubscribes from notifications of feature flag changes. The specified channel
	// must be one that was previously returned by AddFlagChangeListener(); otherwise, the method has no effect.
	RemoveFlagChangeListener(listener <-chan FlagChangeEvent)

	// AddFlagValueChangeListener subscribes for notifications of changes in a specific feature flag's value
	// for a specific set of user properties.
	//
	// When you call this method, it first immediately evaluates the feature flag. It then starts listening
	// for feature flag configuration changes (using the same mechanism as AddFlagChangeListener), and whenever
	// the specified feature flag changes, it re-evaluates the flag for the same user. It then pushes a new
	// FlagValueChangeEvent to the channel if and only if the resulting value has changed.
	//
	// All feature flag evaluations require an instance of lduser.User. If the feature flag you are tracking
	// tracking does not have any user targeting rules, you must still pass a dummy user such as
	// lduser.NewUser("for-global-flags"). If you do not want the user to appear on your dashboard, use
	// the Anonymous property: lduser.NewUserBuilder("for-global-flags").Anonymous(true).Build().
	//
	// The defaultValue parameter is used if the flag cannot be evaluated; it is the same as the corresponding
	// parameter in LDClient.JSONVariation().
	AddFlagValueChangeListener(flagKey string, user lduser.User, defaultValue ldvalue.Value) <-chan FlagValueChangeEvent

	// RemoveFlagValueChangeListener unsubscribes from notifications of feature flag value changes. The
	// specified channel must be one that was previously returned by AddFlagValueChangeListener(); otherwise,
	// the method has no effect.
	RemoveFlagValueChangeListener(listener <-chan FlagValueChangeEvent)
}

FlagTracker is an interface for tracking changes in feature flag configurations.

An implementation of this interface is returned by LDClient.GetFlagTracker(). Application code never needs to implement this interface.

type FlagValueChangeEvent

type FlagValueChangeEvent struct {
	// Key is the key of the feature flag whose configuration has changed.
	//
	// The specified flag may have been modified directly, or this may be an indirect change due to a change
	// in some other flag that is a prerequisite for this flag, or a user segment that is referenced in the
	// flag's rules.
	Key string

	// OldValue is the last known value of the flag for the specified user prior to the update.
	//
	// Since flag values can be of any JSON data type, this is represented as ldvalue.Value. That type has
	// methods for converting to a primitive Java type such as Value.BoolValue().
	//
	// If the flag did not exist before or could not be evaluated, this will be whatever value was
	// specified as the default with AddFlagValueChangeListener().
	OldValue ldvalue.Value

	// NewValue is the new value of the flag for the specified user.
	//
	// Since flag values can be of any JSON data type, this is represented as ldvalue.Value. That type has
	// methods for converting to a primitive Java type such Value.BoolValue().
	//
	// If the flag could not be evaluated or was deleted, this will be whatever value was specified as
	// the default with AddFlagValueChangeListener().
	NewValue ldvalue.Value
}

FlagValueChangeEvent is a parameter type used with FlagTracker.AddFlagValueChangeListener().

This is not an analytics event to be sent to LaunchDarkly; it is a notification to the application.

type HTTPConfiguration

type HTTPConfiguration interface {
	// GetDefaultHeaders returns the basic headers that should be added to all HTTP requests from
	// SDK components to LaunchDarkly services, based on the current SDK configuration.
	GetDefaultHeaders() http.Header

	// CreateHTTPClient returns a new HTTP client instance based on the SDK configuration.
	CreateHTTPClient() *http.Client
}

HTTPConfiguration encapsulates top-level HTTP configuration that applies to all SDK components.

See ldcomponents.HTTPConfigurationBuilder for more details on these properties.

type HTTPConfigurationFactory

type HTTPConfigurationFactory interface {
	// CreateHTTPConfiguration is called internally by the SDK to obtain the configuration.
	//
	// This happens only when MakeClient or MakeCustomClient is called. If the factory returns
	// an error, creation of the LDClient fails.
	CreateHTTPConfiguration(basicConfig BasicConfiguration) (HTTPConfiguration, error)
}

HTTPConfigurationFactory is an interface for a factory that creates an HTTPConfiguration.

type LDClientEvaluations

type LDClientEvaluations interface {
	// BoolVariation returns the value of a boolean feature flag for a given user.
	//
	// Returns defaultVal if there is an error, if the flag doesn't exist, or the feature is turned off and
	// has no off variation.
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#variation
	BoolVariation(key string, user lduser.User, defaultVal bool) (bool, error)

	// BoolVariationDetail is the same as BoolVariation, but also returns further information about how
	// the value was calculated. The "reason" data will also be included in analytics events.
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#variationdetail
	BoolVariationDetail(key string, user lduser.User, defaultVal bool) (bool, ldreason.EvaluationDetail, error)

	// IntVariation returns the value of a feature flag (whose variations are integers) for the given user.
	//
	// Returns defaultVal if there is an error, if the flag doesn't exist, or the feature is turned off and
	// has no off variation.
	//
	// If the flag variation has a numeric value that is not an integer, it is rounded toward zero (truncated).
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#variation
	IntVariation(key string, user lduser.User, defaultVal int) (int, error)

	// IntVariationDetail is the same as IntVariation, but also returns further information about how
	// the value was calculated. The "reason" data will also be included in analytics events.
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#variationdetail
	IntVariationDetail(key string, user lduser.User, defaultVal int) (int, ldreason.EvaluationDetail, error)

	// Float64Variation returns the value of a feature flag (whose variations are floats) for the given user.
	//
	// Returns defaultVal if there is an error, if the flag doesn't exist, or the feature is turned off and
	// has no off variation.
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#variation
	Float64Variation(key string, user lduser.User, defaultVal float64) (float64, error)

	// Float64VariationDetail is the same as Float64Variation, but also returns further information about how
	// the value was calculated. The "reason" data will also be included in analytics events.
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#variationdetail
	Float64VariationDetail(key string, user lduser.User, defaultVal float64) (float64, ldreason.EvaluationDetail, error)

	// StringVariation returns the value of a feature flag (whose variations are strings) for the given user.
	//
	// Returns defaultVal if there is an error, if the flag doesn't exist, or the feature is turned off and has
	// no off variation.
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#variation
	StringVariation(key string, user lduser.User, defaultVal string) (string, error)

	// StringVariationDetail is the same as StringVariation, but also returns further information about how
	// the value was calculated. The "reason" data will also be included in analytics events.
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#variationdetail
	StringVariationDetail(key string, user lduser.User, defaultVal string) (string, ldreason.EvaluationDetail, error)

	// JSONVariation returns the value of a feature flag for the given user, allowing the value to be
	// of any JSON type.
	//
	// The value is returned as an ldvalue.Value, which can be inspected or converted to other types using
	// Value methods such as GetType() and BoolValue(). The defaultVal parameter also uses this type. For
	// instance, if the values for this flag are JSON arrays:
	//
	//     defaultValAsArray := ldvalue.BuildArray().
	//         Add(ldvalue.String("defaultFirstItem")).
	//         Add(ldvalue.String("defaultSecondItem")).
	//         Build()
	//     result, err := client.JSONVariation(flagKey, user, defaultValAsArray)
	//     firstItemAsString := result.GetByIndex(0).StringValue() // "defaultFirstItem", etc.
	//
	// You can also use unparsed json.RawMessage values:
	//
	//     defaultValAsRawJSON := ldvalue.Raw(json.RawMessage(`{"things":[1,2,3]}`))
	//     result, err := client.JSONVariation(flagKey, user, defaultValAsJSON
	//     resultAsRawJSON := result.AsRaw()
	//
	// Returns defaultVal if there is an error, if the flag doesn't exist, or the feature is turned off.
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#variation
	JSONVariation(key string, user lduser.User, defaultVal ldvalue.Value) (ldvalue.Value, error)

	// JSONVariationDetail is the same as JSONVariation, but also returns further information about how
	// the value was calculated. The "reason" data will also be included in analytics events.
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#variationdetail
	JSONVariationDetail(key string, user lduser.User, defaultVal ldvalue.Value) (
		ldvalue.Value, ldreason.EvaluationDetail, error)

	// AllFlagsState returns an object that encapsulates the state of all feature flags for a given user.
	// This includes the flag values, and also metadata that can be used on the front end.
	//
	// The most common use case for this method is to bootstrap a set of client-side feature flags from a
	// back-end service.
	//
	// You may pass any combination of flagstate.ClientSideOnly, flagstate.WithReasons, and
	// flagstate.DetailsOnlyForTrackedFlags as optional parameters to control what data is included.
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#all-flags
	AllFlagsState(user lduser.User, options ...flagstate.Option) flagstate.AllFlags
}

LDClientEvaluations defines the basic feature flag evaluation methods implemented by LDClient.

type LDClientEvents

type LDClientEvents interface {
	// Identify reports details about a user.
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#identify
	Identify(user lduser.User) error

	// TrackEvent reports that a user has performed an event.
	//
	// The eventName parameter is defined by the application and will be shown in analytics reports;
	// it normally corresponds to the event name of a metric that you have created through the
	// LaunchDarkly dashboard. If you want to associate additional data with this event, use TrackData
	// or TrackMetric.
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#track
	TrackEvent(eventName string, user lduser.User) error

	// TrackData reports that a user has performed an event, and associates it with custom data.
	//
	// The eventName parameter is defined by the application and will be shown in analytics reports;
	// it normally corresponds to the event name of a metric that you have created through the
	// LaunchDarkly dashboard.
	//
	// The data parameter is a value of any JSON type, represented with the ldvalue.Value type, that
	// will be sent with the event. If no such value is needed, use ldvalue.Null() (or call TrackEvent
	// instead). To send a numeric value for experimentation, use TrackMetric.
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#track
	TrackData(eventName string, user lduser.User, data ldvalue.Value) error

	// TrackMetric reports that a user has performed an event, and associates it with a numeric value.
	// This value is used by the LaunchDarkly experimentation feature in numeric custom metrics, and will also
	// be returned as part of the custom event for Data Export.
	//
	// The eventName parameter is defined by the application and will be shown in analytics reports;
	// it normally corresponds to the event name of a metric that you have created through the
	// LaunchDarkly dashboard.
	//
	// The data parameter is a value of any JSON type, represented with the ldvalue.Value type, that
	// will be sent with the event. If no such value is needed, use ldvalue.Null().
	//
	// For more information, see the Reference Guide: https://docs.launchdarkly.com/sdk/server-side/go#track
	TrackMetric(eventName string, user lduser.User, metricValue float64, data ldvalue.Value) error
}

LDClientEvents defines the methods implemented by LDClient that are specifically for generating analytics events. Events may also be generated as a side effect of the methods in LDClientEvaluations.

type LDClientInterface

type LDClientInterface interface {
	LDClientEvaluations
	LDClientEvents

	// WithEventsDisabled returns a decorator for the client that implements the same basic operations
	// but will not generate any analytics events.
	//
	// If events were already disabled, this is just the same object. Otherwise, it is an object whose
	// Variation methods use the same LDClient to evaluate feature flags, but without generating any
	// events, and whose Identify/Track/Custom methods do nothing. Neither evaluation counts nor user
	// properties will be sent to LaunchDarkly for any operations done with this object.
	//
	// You can use this to suppress events within some particular area of your code where you do not want
	// evaluations to affect your dashboard statistics, or do not want to incur the overhead of processing
	// the events.
	//
	// Note that if the original client configuration already had events disabled
	// (config.Events = ldcomponents.NoEvents()), you cannot re-enable them with this method. It is only
	// useful for temporarily disabling events on a client that had them enabled, or re-enabling them on
	// an LDClientInterface that was the result of WithEventsDisabled(true).
	//
	//     // Assuming you did not disable events when creating the client,
	//     // this evaluation generates an event:
	//     value, err := client.BoolVariation("flagkey1", user, false)
	//
	//     // Now we want to do some evaluations without events
	//     tempClient := client.WithEventsDisabled(true)
	//     value, err = tempClient.BoolVariation("flagkey2", user, false)
	//     value, err = tempClient.BoolVariation("flagkey3", user, false)
	WithEventsDisabled(eventsDisabled bool) LDClientInterface
}

LDClientInterface defines the basic SDK client operations implemented by LDClient.

This includes all methods for evaluating a feature flag or generating analytics events, as defined by LDEvaluations and LDEvents. It does not include general control operations like Flush(), Close(), or GetDataSourceStatusProvider().

type LoggingConfiguration

type LoggingConfiguration interface {
	// GetLoggers returns the configured ldlog.Loggers instance.
	GetLoggers() ldlog.Loggers

	// GetLogDataSourceOutageAsErrorAfter returns the time threshold, if any, after which the SDK
	// will log a data source outage at Error level instead of Warn level. See
	// LoggingConfigurationBuilderLogDataSourceOutageAsErrorAfter().
	GetLogDataSourceOutageAsErrorAfter() time.Duration

	// IsLogEvaluationErrors returns true if evaluation errors should be logged.
	IsLogEvaluationErrors() bool

	// IsLogUserKeyInErrors returns true if user keys may be included in logging.
	IsLogUserKeyInErrors() bool
}

LoggingConfiguration encapsulates the SDK's general logging configuration.

See ldcomponents.LoggingConfigurationBuilder for more details on these properties.

type LoggingConfigurationFactory

type LoggingConfigurationFactory interface {
	// CreateLoggingConfiguration is called internally by the SDK to obtain the configuration.
	//
	// This happens only when MakeClient or MakeCustomClient is called. If the factory returns
	// an error, creation of the LDClient fails.
	CreateLoggingConfiguration(basicConfig BasicConfiguration) (LoggingConfiguration, error)
}

LoggingConfigurationFactory is an interface for a factory that creates a LoggingConfiguration.

type PersistentDataStore

type PersistentDataStore interface {
	io.Closer

	// Init overwrites the store's contents with a set of items for each collection.
	//
	// All previous data should be discarded, regardless of versioning.
	//
	// The update should be done atomically. If it cannot be done atomically, then the store
	// must first add or update each item in the same order that they are given in the input
	// data, and then delete any previously stored items that were not in the input data.
	Init(allData []ldstoretypes.SerializedCollection) error

	// Get retrieves an item from the specified collection, if available.
	//
	// If the specified key does not exist in the collection, it should return a SerializedItemDescriptor
	// with a Version of -1 and an Item of nil.
	//
	// If the item has been deleted and the store contains a placeholder, it should return that
	// placeholder rather than filtering it out.
	Get(kind ldstoretypes.DataKind, key string) (ldstoretypes.SerializedItemDescriptor, error)

	// GetAll retrieves all items from the specified collection.
	//
	// If the store contains placeholders for deleted items, it should include them in the results,
	// not filter them out.
	GetAll(kind ldstoretypes.DataKind) ([]ldstoretypes.KeyedSerializedItemDescriptor, error)

	// Upsert updates or inserts an item in the specified collection. For updates, the object will only be
	// updated if the existing version is less than the new version.
	//
	// The SDK may pass a SerializedItemDescriptor that represents a placeholder for a deleted item. In
	// that case, assuming the version is greater than any existing version of that item, the store should
	// retain that placeholder rather than simply not storing anything.
	//
	// The method returns the updated item if the update was successful; or, if the update was not
	// successful because the store contained an equal or higher version, it returns the item that is
	// in the store.
	Upsert(kind ldstoretypes.DataKind, key string, item ldstoretypes.SerializedItemDescriptor) (bool, error)

	// IsInitialized returns true if the data store contains a data set, meaning that Init has been
	// called at least once.
	//
	// In a shared data store, it should be able to detect this even if Init was called in a
	// different process: that is, the test should be based on looking at what is in the data store.
	// Once this has been determined to be true, it can continue to return true without having to
	// check the store again; this method should be as fast as possible since it may be called during
	// feature flag evaluations.
	IsInitialized() bool

	// IsStoreAvailable tests whether the data store seems to be functioning normally.
	//
	// This should not be a detailed test of different kinds of operations, but just the smallest possible
	// operation to determine whether (for instance) we can reach the database.
	//
	// Whenever one of the store's other methods returns an error, the SDK will assume that it may have
	// become unavailable (e.g. the database connection was lost). The SDK will then call
	// IsStoreAvailable() at intervals until it returns true.
	IsStoreAvailable() bool
}

PersistentDataStore is an interface for a data store that holds feature flags and related data in a serialized form.

This interface should be used for database integrations, or any other data store implementation that stores data in some external service. The SDK will provide its own caching layer on top of the persistent data store; the data store implementation should not provide caching, but simply do every query or update that the SDK tells it to do.

Implementations must be safe for concurrent access from multiple goroutines.

Error handling is defined as follows: if any data store operation encounters a database error, or is otherwise unable to complete its task, it should return an error value to make the SDK aware of The SDK will log the exception and will assume that the data store is now in a non-operational non-operational state; the SDK will then start polling IsStoreAvailable() to determine when the store has started working again.

Whenever a new implementation of this interface is written, it should have unit tests that use testhelpers.storetest.PersistentDataStoreTestSuite. This ensures that all of the interface methods are exercised consistently in various scenarios that might be encountered in real SDK usage.

type PersistentDataStoreFactory

type PersistentDataStoreFactory interface {
	// CreateDataStore is called by the SDK to create the implementation instance.
	//
	// This happens only when MakeClient or MakeCustomClient is called. The implementation instance
	// is then tied to the life cycle of the LDClient, so it will receive a Close() call when the
	// client is closed.
	//
	// If the factory returns an error, creation of the LDClient fails.
	CreatePersistentDataStore(context ClientContext) (PersistentDataStore, error)
}

PersistentDataStoreFactory is an interface for a factory that creates some implementation of a persistent data store.

This interface is implemented by database integrations. Usage is described in ldcomponents.PersistentDataStore().

Directories

Path Synopsis
flagstate Package flagstate contains the data types used by the LDClient.AllFlagsState() method.
ldstoretypes Package ldstoretypes contains types that are only needed when implementing custom components.