All notable changes to the LaunchDarkly C server-side SDK will be documented in this file. This project adheres to Semantic Versioning.
- Changed the internal abstractions used for feature stores and updated the implementations to improve performance and reduce memory usage.
- Fixed an issue preventing the proper generation of debug events.
- Testing: refactored cmake project tests to remove unnecessary boilerplate.
- Bumped c-sdk-common dependency, introducing experimental APIs. Such APIs are subject to change or removal, and carry no guarantees.
- Fixed flag evaluation to report error when flag data is malformed (variation out of bounds).
- Fixed use-after-free in situation where a prerequisite flag has a NULL off-variation.
- Fixed
LDAllFlagsState
handling of malformed flags, and fixed JSON serialization to omit details properly.
- Fixed support for CMake versions 3.11 through 3.13, which require an explicit LIBRARY DESTINATION path when installing the SDK's target.
- Fixed ldserverapi shared library symbol visibility: undocumented symbols previously exposed by 3rd party dependencies are now hidden.
- Fixed an issue where the SDK was erroneously logging errors when evaluating flags which have an
offVariation
ofnull
or when theoffVariation
was not specified.
- Fixed bug in cmake configuration causing build failures on some platforms due to omission of position-independent code flag.
- Fixed build error on platforms where char is unsigned by default.
- Added CMake minimum version table to README.
- Added 3rd-party dependency table to README.
- Updated CMake project configuration to support find_package.
- After installation, it should now be possible to call
find_package(ldserverapi [version] REQUIRED)
followed bytarget_link_libraries(app ldserverapi::ldserverapi)
. - Note: find_package support does not extend to the Redis integration at this time.
- Please see the README for updated instructions.
- Added cmake PROJECT_VERSION variable which reflects the SDK's version.
- Fixed behavior of patch event handling to properly ignore unrecognized paths.
- Fixed generation of ldserverapi static library release artifacts, which would cause undefined symbol errors during linking.
- Added section to README.md with basic CMake integration instructions.
- The SDK previously vendored & patched a set of 3rd-party dependencies. These dependencies are now obtained via CMake's
FetchContent
API, similar togoogletest
. This required a CMake version bump from3.10
to3.11
.
- Removed most 3rd-party dependencies in
third-party
subdirectory. - Removed unused
base64
dependency.
- Null user attributes should never result in a rule match.
debugEventsUntilDate
property of flags obtained viaLDAllFlagsState
API no longer overflows due to millisecond-precision timestamping.
- Updated language in changelog related to Relay Proxy.
- Updated c-sdk-common dependency.
- Users with empty keys should not generate identify events.
- Removed redundant index event that was generated after an identify event.
- Fixed handling of per-user private attributes in SDK contract tests.
-
Added
integrations/test_data.h
. Test Data is a new way to inject feature flag data programmatically into the SDK for testing — either with fixed values for each flag, or with targets and/or rules that can return different values for different users. -
Added
integrations/file_data.h
. File Data is a new way to inject feature flag data via an external resource.
- Fixed bug in
LDAllFlagsState
where invalid flags were included in the output. - Fixed
LDConfigSetSendEvents
to properly disable analytic events when set to false. As part of this change, public functionsLDClientTrack
,LDClientTrackMetric
,LDClientAlias
, andLDClientIdentify
now return true when analytic events are disabled. - Fixed JSON serialization of time values to remove fractional millisecond component.
- Added
LDVersion()
, equivalent toLD_SDK_VERSION
. Useful when wrapping the SDK with a higher level language that cannot access theLD_SDK_VERSION
symbol. - Added
LDAllFlagsState
API for fetching flag values and details. This API is commonly used to bootstrap the client-side Javascript SDK.
- Deprecated
LDAllFlags
in favor ofLDAllFlagsState
. Please invokeLDAllFlagsState()
followed byLDAllFlagsStateToValuesMap()
for equivalent behavior.
- Changed CircleCI macOS executors to Gen2 resource class.
- Swapped CircleCI
helgrind
test fordrd
because of false positives within curl dependency.
- Fixed
LDJSONVariation
to allow for returning a flag of any JSON-representable type (previously would return an error if the expected flag type was not object or array.) - Fixed all
LDVariation
variants to returnhasVariation = false
withinLDDetails
when caller requests wrong flag type. - Fixed handling of base/stream URIs set by
LDConfigSet[Base/Stream]URI
with an unintentional trailing slash. - Fixed double-free bug within
LDStoreInitialized
.
- Updated CI with dedicated valgrind & helgrind jobs
- Added internal-only JSON helpers.
- Various grammar & spelling issues
- Removed unused internal headers
- Fixed comment spelling issues
- Updated spelling in an error log message (
checkPrequisites failed
->checkPrerequisites failed
)
- Fixed Windows CI build by updating PCRE download URL to new host
- Updated the build process to produce release artifacts for Windows.
- Updated unit tests to use GoogleTest.
- In cases where there was a malformed feature flag
LDAllFlags
would return null instead of all of the valid flags. - When a malformed feature flag was evaluated events would not be generated for that flag.
- Refactored parsing logic to provide better error messages and be more reliable.
- The SDK now supports the ability to control the proportion of traffic allocation to an experiment. This works in conjunction with a new platform feature now available to early access customers.
- Removed stray imports of stdbool.h
- Removed stray imports of stdbool.h
- Corrected rollout bucketing behavior when bucketing by a user attribute that does not exist.
- Fixed handling of flag rollout bucketing by a specific user attribute.
- Now building with -Werror on Linux and macOS
- Refactored to reduce code duplication between c-client and c-server
- Improved c89 compatibility
- Added clang-format
- A race condition inside the in memory cache when utilizing an external data store. Thanks @lcapaldo
- An instance of using the incorrect enum
LD_ERROR
instead ofLD_LOG_ERROR
withLD_LOG
- Resolved many build warnings (that do not impact semantics)
- Added the
LDClientAlias
function. This can be used to associate two user objects for analytics purposes with an alias event.
- Vendored Findhiredis to ease building the Redis integration
- Added code coverage reporting functionality to CMake
- Increased unit test coverage
- Added ability to target secondary key
- Internal assertions that should of been API assertions
- A memory leak related to every delivery
- Empty summary events being sent when other events were also being sent
- A leak of custom attributes if the attributes were replaced after already being set
- Fixed inverted defensive check in LDClientIsOffline
- Fixed stream read timeout handling
- LDBasicLoggerThreadSafeInitialize used to setup LDBasicLoggerThreadSafe
- LDBasicLoggerThreadSafe a thread safe alternative to LDBasicLogger
- LDBasicLoggerThreadSafeShutdown to cleanup LDBasicLoggerThreadSafe resources
- OSX artifacts are now generated with Xcode 9.4.1
- All helgrind concurrency warnings
- Marked LDBasicLogger as deprecated
- Added extra public headers to the
ldserversdk
target to fix Redis usage when embedding the cmake project - Fixed generation of full fidelity evaluation events for the LaunchDarkly experimentation feature
- Set the "Accept" header to "text/event-stream" for streaming connections.
usleep(3)
settingerrno
toEINTR
is no longer considered a fatal error.
- Cap usage of usleep(3) at 999999 usec which is required on certain platforms
- When an error occurs with usleep(3) print errno and not the status code
- LDConfigSetWrapperInfo which is used to inform the LaunchDarkly backend of an SDK wrappers name and version. Currently used in our Lua server-side SDK.
Version 2.0.0
brings many changes, however they are primarily focused on edge cases and internal details. For most customers, this release will be a drop-in replacement and will not require any changes in your SDK usage. When using the SDK, you should either install the SDK configured for your desired location with cmake --build . --target install
or use it as a CMake sub-project with the ldserverapi
target. The internal organization of files is not part of the API and may change in future releases.
- Added the capability to remove all assertions at compile time. This is controlled with the compile time definition
LAUNCHDARKLY_USE_ASSERT
.
- Fixed handling of large time values to fix overflow issues on certain systems: For example 32 bit builds and Windows.
- Waiting until timeout on streaming mode initialization.
- Made CMake more hygienic with target based compilation options.
- Fixed many miscellaneous warnings. Now the SDK is much closer to ANSI compatibility.
- Disabled certain unneeded warnings on Windows.
- By default all API operations now use defensive checks instead of assertions by default. This can be controlled based on preference with the compile time definition
LAUNCHDARKLY_DEFENSIVE
. - The
LDStringVariation
andLDJSONVariation
functions now acceptNULL
as fallback values. - Binary releases are now archives which contain both the headers, and binary, for each platform. These can be extracted and used directly.
- All
bool
values in the public API now useLDBoolean
. This value is a number containing either zero or one. It is currently achar
, however this should be considered an opaque detail. This is part of ANSI C compatibility progress. - Switched to usage of
PTHREAD_MUTEX_ERRORCHECK
on POSIX. This is controlled with the compile time definitionLAUNCHDARKLY_CONCURRENCY_UNSAFE
. - Optimized internals to reduce locking, and switch certain reader/writer locks to mutexes, based on usage pattern.
- Detangled headers reducing complexity.
- Added a mock HTTP server used for integration testing.
- Added stricter compilation options than the exiting
-Wextra
. - Greatly simplified internal event generation logic.
- Increased error checking around many system operations.
- Standardized polling retry behavior. It now simply waits until the next poll interval.
- Standardized event delivery retry behavior. It now retries delivery after one second, a single time.
- Standardized streaming retry behavior. It now correctly follows exponential back-off, changed how status codes are interpreted, and resets back-off after 60 seconds of being successfully connected.
- Added support for utilizing external feature stores. See the new
launchdarkly/store.h
file for details on implementing a store. You can configure usage of a specific store withLDConfigSetFeatureStoreBackend
. - Added support for Redis as an external feature store. To build add
-D REDIS_STORE=ON
to your cmake build. This will require the hiredis library to be installed on your system. - Added LaunchDarkly daemon mode configurable with
LDConfigSetUseLDD
for use with the Relay Proxy. To learn more, read Using daemon mode. - Added a code coverage reporting system. To build with code coverage add
-D COVERAGE=ON
to your cmake build. Run the tests, then build thecoverage
target. This will generate an HTML report.
- The SDK now specifies a uniquely identifiable request header when sending events to LaunchDarkly to ensure that events are only processed once, even if the SDK sends them two times due to a failed initial attempt.
- Change how time is handled on OSX to support old OSX versions.
- Added
LDClientTrackMetric
which is an extended version ofLDClientTrack
but with an extra associated metric value.
- Corrected
LDReasonToJSON
encoding of theRULE_MATCH
case.
- Undefined behavior associated with branching on an uninitialized variable when parsing server time headers
- Updated CMAKE header search to include
/usr/local/include
for OSX Mojave
- LRU caching to prevent users being indexed multiple times
- The server HTTP response time parsing logic
- Memory leak when evaluating flags with prerequisites
- Completed Doxygen coverage
- The header files have been reorganized. Now include "launchdarkly/api.h".
- Windows support
- Networking retry timing jitter
- Analytics
debugEventsUntilDate
support
- Initial public API
- OSX / Linux builds
- Windows support
- Networking retry timing jitter
- Analytics
debugEventsUntilDate
support