Skip to content
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

Building error when added as a dependency #155

Closed
camillof opened this issue Apr 23, 2020 · 20 comments
Closed

Building error when added as a dependency #155

camillof opened this issue Apr 23, 2020 · 20 comments

Comments

@camillof
Copy link

camillof commented Apr 23, 2020

Describe the bug
When adding this gem as a dependency to another gem, causes the gem to raise an error when building it.

To reproduce

  1. Add launchdarkly-server-sdk as a dependency to your gem
spec.add_dependency "launchdarkly-server-sdk", "~> 5.7"
  1. Try to build your gem

Expected behavior
I expect my gem to be built without errors.

Logs

current directory: /Users/camillo/Desktop/WyeProjects/TRR/dfs-scripts/dist/DFS/gems/launchdarkly-server-sdk-5.6.2/ext
/Users/camillo/.rvm/rubies/ruby-2.6.3/bin/ruby mkrf_conf.rb

current directory: /Users/camillo/Desktop/WyeProjects/TRR/dfs-scripts/dist/DFS/gems/launchdarkly-server-sdk-5.6.2/ext
rake RUBYARCHDIR\=/Users/camillo/Desktop/WyeProjects/TRR/dfs-scripts/dist/DFS/extensions/x86_64-darwin-18/2.6.0/launchdarkly-server-sdk-5.6.2 RUBYLIBDIR\=/Users/camillo/Desktop/WyeProjects/TRR/dfs-scripts/dist/DFS/extensions/x86_64-darwin-18/2.6.0/launchdarkly-server-sdk-5.6.2
/Users/camillo/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/bundler/rubygems_integration.rb:462:in `block in replace_bin_path': can't find executable rake for gem rake. rake is not currently included in the bundle, perhaps you meant to add it to your Gemfile? (Gem::Exception)
	from /Users/camillo/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/bundler/rubygems_integration.rb:482:in `block in replace_bin_path'
	from /Users/camillo/.rvm/gems/ruby-2.6.3/bin/rake:23:in `<main>'
	from /Users/camillo/.rvm/gems/ruby-2.6.3/bin/ruby_executable_hooks:24:in `eval'
	from /Users/camillo/.rvm/gems/ruby-2.6.3/bin/ruby_executable_hooks:24:in `<main>'

rake failed, exit code 1

SDK version
5.7.2

Language version, developer tools
ruby-2.6.3 [ x86_64 ]

OS/platform
MacOS Catalina 10.15

Additional context
This problem seems to be solved if you add rake as a dependency into your gem too, but shouldn't this be a ruby-server-sdk dependency instead?

@eli-darkly
Copy link
Contributor

That's odd; I'm not sure why it would expect rake to be present at all. Our SDK did previously have a rake dependency but it was removed since we no longer use Rake in the build. We'll look into this.

@camillof
Copy link
Author

camillof commented Apr 24, 2020 via email

@eli-darkly
Copy link
Contributor

eli-darkly commented Apr 24, 2020

Sorry if I'm misunderstanding something basic, but if Rake is required to build your own gem, then why would you need it to be provided as a transitive dependency by the Ruby SDK? Our gem is already built.

@camillof
Copy link
Author

No, rake is not required to build my own gem. I have been building my gem without it for a while.

But, if I add the Ruby SDK as a dependency, I couldn't find another way to get it working than adding also rake as a dependency to my gem too, which is not the expected behavior.

@camillof
Copy link
Author

camillof commented Apr 24, 2020

Seems like you have an implicit rake dependency here when using

spec.extensions    = 'ext/mkrf_conf.rb'

As it uses rake when building it
https://github.com/launchdarkly/ruby-server-sdk/blob/master/launchdarkly-server-sdk.gemspec#L22

@eli-darkly
Copy link
Contributor

Ahh, thanks, that's definitely it.

@eli-darkly
Copy link
Contributor

Well... hmm. I thought I understood the issue, but I am having trouble reproducing it.

In an environment where rake is not installed, I created a minimal gemspec that included spec.add_dependency "launchdarkly-server-sdk", "5.7.2". I then did a gem build. It worked fine.

Since the purpose of the logic in ext/mkrf_conf.rb (which I don't think we really need) was to check for the presence of openssl... does your Ruby installation include openssl, either compiled in or as a gem? Mine does, and it would take a bit longer to set up one that doesn't. I'm not sure what other differences there might be between my test case and yours.

If you could provide an example of your gemspec with any sensitive info removed, and the build command you're using, that might help.

@camillof
Copy link
Author

Hi, I created a dummy gem to demostrate this error, you can clone it from here: https://github.com/camillof/example_gem

Thank you for your time!

@eli-darkly
Copy link
Contributor

Thanks - I was able to reproduce a failure with that code. I'm not sure what the crucial difference was between that and my other test code, but this should work to test the fix.

I think the fix we will go with is just to completely remove the logic that was in ext/mkrf_conf.rb. Its purpose was to prevent installing the gem in an environment that doesn't have openssl, but that would now be a very rare condition since openssl is bundled in all modern Ruby versions/

@camillof
Copy link
Author

Yes, it's weird, because if I try to bundle and install the gem from the terminal it works fine, but not through the create_gem script, maybe some dependency is not loading?

I look forward to your fix results 🙌

@eli-darkly
Copy link
Contributor

@camillof I have a change that as far as I can tell resolves the issue, but I'd like to be double sure, so if you have a chance: could you please try your build again with the LaunchDarkly SDK version changed to "5.7.3.pre.beta.2"? That's a prerelease version that I've pushed containing the change.

@camillof
Copy link
Author

camillof commented Apr 27, 2020

🚀 it worked!
Thank you very much!

PS: I'm now having an issue with a dependency, ld-eventsource, which also depends on socketry which is a bit outdated, using hitimes 1.3.1 which had a major bump to 2.0 fixing a loading paths issue
But that's for another ticket in another repo, so thank you for helping me with this one.

@eli-darkly
Copy link
Contributor

Hmm, well, if the ld-eventsource dependency issue is straightforward then we could try to get it into the same upcoming patch release of the SDK, but I'm not sure that it is. We do not have a good alternative to using socketry yet as far as I know. I'm unclear on what the actual problem is that you're running into.

@camillof
Copy link
Author

camillof commented Apr 27, 2020

/usr/local/DFS/gems/hitimes-1.3.1/lib/hitimes.rb:56:in `<top (required)>': Unable to find binary extension, was hitimes installed correctly? The following paths were tried. (LoadError)
/Users/camillo/hitimes/2.6/hitimes : incompatible library version - /usr/local/DFS/gems/hitimes-1.3.1/lib/hitimes/2.6/hitimes.bundle
/Users/camillo/hitimes/hitimes : cannot load such file -- hitimes/hitimes
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /usr/local/DFS/gems/socketry-0.5.1/lib/socketry.rb:10:in `<top (required)>'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /usr/local/DFS/gems/ld-eventsource-1.0.3/lib/ld-eventsource/impl/streaming_http.rb:5:in `<top (required)>'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /usr/local/DFS/gems/ld-eventsource-1.0.3/lib/ld-eventsource/client.rb:3:in `<top (required)>'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /usr/local/DFS/gems/ld-eventsource-1.0.3/lib/ld-eventsource.rb:1:in `<top (required)>'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /usr/local/DFS/gems/launchdarkly-server-sdk-5.7.3.pre.beta.2/lib/ldclient-rb/stream.rb:3:in `<top (required)>'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /usr/local/DFS/gems/launchdarkly-server-sdk-5.7.3.pre.beta.2/lib/ldclient-rb.rb:20:in `<top (required)>'

This is the error I'm getting when requiring the ldclient-rb (I can't even require hitimes directly in my code if gem version is < 2.0). It's solved if I replace all the code inside hitimes installed library with the latest one.
But yeah, it is not that straightforward, as socketry is locked on hitimes ~> 1.2.

This issue may provide further information: socketry/socketry#29

@eli-darkly
Copy link
Contributor

That's unfortunate. We may need to fork it. IIRC the only reason we use Socketry is that we need to be able to enforce read timeouts on a streaming connection, but that is a crucial requirement.

@eli-darkly
Copy link
Contributor

The original issue (not including the socketry/hitimes issue) is fixed in the 5.7.3 release, and I'm deleting the prerelease test version. Thanks for catching this.

@eli-darkly
Copy link
Contributor

eli-darkly commented Apr 28, 2020

@camillof I've filed the hitimes issue here and I'll also open an issue in this repo pointing to that, so if anyone else runs into it they'll see that it's known.

Out of curiosity, are you using TruffleRuby at all (which was mentioned in the hitimes release notes regarding that loading problem), or what is your runtime environment? I know that in your original issue description you just said Ruby 2.6.3, but I presume it is not just a vanilla 2.6.3 distribution because we test with that all the time.

@camillof
Copy link
Author

Thanks a lot @eli-darkly 🙌, I'll keep an eye on that issue.

We're not using TruffleRuby at all, our environment is a Mac OS pkg that is delivered to our users, and inside that pkg we embed our gem (which has dependencies on other gems), that's why our gem is built and installed every time we create a new pkg. In that build was when we got the original rake error. Now we are getting this hitimes error at runtime level, after the user install the pkg and try to run our gem. Does that answer your question?

In the meantime, we are going to use the LaunchDarkly REST API.

@eli-darkly
Copy link
Contributor

We're not using TruffleRuby at all, our environment is a Mac OS pkg that is delivered to our users, and inside that pkg we embed our gem (which has dependencies on other gems), that's why our gem is built and installed every time we create a new pkg. In that build was when we got the original rake error. Now we are getting this hitimes error at runtime level, after the user install the pkg and try to run our gem. Does that answer your question?

Well, it's mysterious, but it does tell me that the issue isn't limited to any particular runtimes as what I saw in the hitimes repo seemed to suggest. I wish I knew how to reproduce it, but if we can either update or get rid of the hitimes dependency I presume that will fix it.

our environment is a Mac OS pkg that is delivered to our users, and inside that pkg we embed our gem (which has dependencies on other gems), that's why our gem is built and installed every time we create a new pkg

I'm glad you mentioned this since I wasn't sure about the intended deployment. If this is code that's going to run on an individual user's machine, we would highly recommend not using any of the server-side SDKs, for reasons that are discussed here. Since there isn't a Ruby client-side SDK at present, directly calling a REST endpoint— one of the ones used by client-side SDKs, that evaluates the flags for you rather than returning the flag configurations— would be the way to go. That is not part of the REST AP that is documented here— I'll find you the relevant docs.

@camillof
Copy link
Author

I'm glad you mentioned this since I wasn't sure about the intended deployment. If this is code that's going to run on an individual user's machine, we would highly recommend not using any of the server-side SDKs, for reasons that are discussed here. Since there isn't a Ruby client-side SDK at present, directly calling a REST endpoint— one of the ones used by client-side SDKs, that evaluates the flags for you rather than returning the flag configurations— would be the way to go. That is not part of the REST AP that is documented here— I'll find you the relevant docs.

Wow, we really missed that point. It would be really helpful if you find that "client rest endpoint" documentation. I'm trying to figure it out from the javascript SDK repo but it is not that easy.

LaunchDarklyReleaseBot added a commit that referenced this issue Mar 18, 2022
* fix doc comments

* add YARD config so our docs show up correctly everywhere

* don't need markup-provider option

* rm obsolete proxy param

* remove net-http-persistent

* fix concurrent-ruby usage that breaks on Windows

* add pipeline and clean up with with rm_rf instead of rm

* fix highlight blocks

* Hr/azure3 (#103)

* Add Consul and Redis services to Windows.
* Enable Consul and Redis testing

* add dynamo (#104)

* add experimentation event overrides for rules and fallthrough

* warn & don't send event if identify or track has no valid user

* include user in prereq flag events

* rm unnecessary logic

* more factory methods

* update readme to refer to docs

* add Ruby 2.6.2 to CI

* fix missing require for net/http

* stringify built-in user attributes in events, and secondary key for evals

* make const names consistent

* support metric value with track()

* update method description

* applying markdown templates and updating repository url references

* Cleaning up markdown files

* allow skipping database tests

* Updating the package name (#115)

* update package name

* missed one

* revert module entry point name change

* bump ld-eventsource version for stream logging fix

* use YAML.safe_load

* add unit test and temporarily revert fix to demonstrate failure

* restore fix

* add comment about not using FileDataSource in production

* drop events if inbox is full

* update doc comment for track with metric_value

* don't let user fall outside of last bucket in rollout

* refactor evaluation logic and move it out of the main namespace

* comments

* fix type coercion behavior

* make type coercion behavior consistent with earlier versions for now

* whitespace

* break up Evaluator tests further

* make EvaluationReason an immutable class

* FrozenError doesn't exist in older Ruby, use more general RuntimeError

* precompute evaluation reasons when we receive a flag

* rm unused

* rename FeatureStore to DataStore

* remove references to UpdateProcessor (now DataSource)

* add event payload ID header

* (6.0) drop support for old Ruby versions

* add Ruby version constraint to gemspec

* remove Rake dependency

* update ld-eventsource to 1.0.2 which doesn't have Rake dependency

* implement diagnostic events in Ruby (#130)

* update ruby-eventsource to 1.0.3 for backoff bug

* fix incorrect initialization of EventProcessor

* remove install-time openssl check that breaks if you don't have rake

* treat comparison with wrong data type as a non-match, not an exception (#134)

* fail fast for nil SDK key when appropriate

* tolerate nil value for user.custom (#137)

* Only shutdown the Redis pool if it is owned by the SDK (#158)

* Only shutdown a Redis pool created by SDK

* Make pool shutdown behavior an option

* improve doc comment

* remove support for indirect/patch and indirect/put (#138)

* update to json 2.3.1 (#139)

* update json dep to 2.3.x to fix CVE

* add publication of API docs on GitHub Pages (#143)

* try fixing release metadata

* update the default base url (#144)

* revert renames of feature_store & update_processor

* [ch92483] Use http gem and add socket factory support (#142)

* update dependencies and add CI for ruby 3 (#141)

* reference eventsource 2.0 in gemspec

* add 5.x releasable branch for releaser

* use Ruby 2.6.6 in releases

* Removed the guides link

* [ch99757] add alias method (#147)

* don't send event for nil user evaluation

* remove lockfile (#148)

* rm redundant nil check

* Experiment Allocation Changes (#150)

* WIP - from sam's pairing session

* starting sdk changes

* adding tests and making sure everything works

* adding more tests

* removing the singleton for fallthrough

* Revert "removing the singleton for fallthrough"

This reverts commit dff7adbb809ecc63118d0fbff9742a88a039c679.

* taking a different approach to keep things immutable

* adding tests for untracked

* remove unnecessary comment

* making sure to return two values in all code paths

Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>

* Use camelCase for JSON property names (#151)

The in_experiment attribute was added to reasons as part of #150 but it doesn't appear to be received in events. I think that's because it's sending it in JSON as "in_experiment" rather than "inExperiment" as we expect to parse it.

* fixing ruby logic causing ih failures (#152)

* fixing ruby logic

* adding missing spec

* Apply suggestions from code review

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* pr tweaks

* making spec language consistent

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* add log warning for missing user key (#153)

* add log warnings for nil/empty user key

* rm warning for empty string key

* fix test

* diagnostic events should respect HTTPS_PROXY (#154)

* minor test simplification (#155)

* allow higher minor versions of json and http gems

* allow v5.x of http gem (#157)

* use Bundler 2.2.10 + modernize CI config (#158)

* enable verbose rspec output

* fix socket factory tests

* restore log suppression

* Replacing deprecated circleci image usage (#159)

* use Releaser v2 config (#161)

* Updates docs URLs

* Update lib/ldclient-rb/ldclient.rb

Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>

* remove reliance on git in gemspec (#163)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504 (#164)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504

* comment phrasing

* Start work on flag builder.

* Add user targeting and rule builder

* Add datasource implementation

* Convert the current_flags hash to use symbols instead of strings as keys

* Fix typo on FlagRuleBuilder copy constructor

* minor refactoring of impl; Added use of new Clause struct instead of Hash in FlagRuleBuilder; Moved TestData.factory out of Impl namespace and renamed Impl to TestDataImpl

* Add the doc comments

* (big segments 1) add public config/interface/reason types (#167)

* Cleanup docstrings to be YARD docs

* Added Util.is_bool helper function to clean up the check for whether an object is a boolean; Removed the DeepCopyHash/DeepCopyArray objects in favor of deep_copy_hash and deep_copy_array functions

* Move public classes out of Impl namespace. Most of it is in public namespace except for the data source now.

* Move require of concurrent/atomics to the correct module

* (big segments 2) implement Big Segments evaluation & status APIs (#168)

* improve CONTRIBUTING.md with notes on code organization

* add note about doc comments

* Cleanup YARD warnings and cleanup docs

* Address PR feedback: Move is_bool back to Impl namespace to avoid confusion; Remove unnecessary nil check on variations in build function; fixup comments

* (big segments 3) implement Redis & DynamoDB big segment stores (#169)

* add missing import

* fix stale calculation

* fix big segments user hash algorithm to use SHA256

* improve & refactor client/evaluation tests

* more cleanup/DRY

* add use_preconfigured_flag and use_preconfigured_segment to TestData (#173)

* always cache big segment query result even if it's nil

* comments

* add test for cache expiration

* use TestData in our own tests (#174)

* use TestData in our own tests

* fix test

* replace LaunchDarkly::FileDataSource with LaunchDarkly::Integrations::FileData

* update ruby-eventsource version for recent SSE fixes

* Bump bundler version (#184)

* Add ability to to set initial reconnect delay (#183)

* Treat secondary as a built-in attribute (#180)

* all_flags_state is invalid if store isn't initialized (#182)

* identify should not emit events if user key is "" (#181)

* Account for traffic allocation on all flags (#185)

* Add contract tests (#178)

* Fix string interpolation in log message (#187)

* Default opts to empty hash when creating persistent feature store (#186)

* Remove Hakiri badge from README (#188)

Hakiri was sunset on January 31st, 2022 at which time our badge stopped
working.

* detect http/https proxy env vars when creating HTTP clients

* rever accidental change

Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: Harpo roeder <hroeder@launchdarkly.com>
Co-authored-by: hroederld <46500128+hroederld@users.noreply.github.com>
Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: Jacob Smith <jacob@jacobsmith.io>
Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: Kerrie Martinez <kyee@launchdarkly.com>
Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>
Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>
Co-authored-by: Matthew M. Keeler <keelerm84@gmail.com>
Co-authored-by: Ben Levy <benjaminlevy007@gmail.com>
Co-authored-by: Ben Levy <ben@foxhound.systems>
Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>
LaunchDarklyReleaseBot added a commit that referenced this issue Jun 15, 2022
* rm obsolete proxy param

* remove net-http-persistent

* fix concurrent-ruby usage that breaks on Windows

* add pipeline and clean up with with rm_rf instead of rm

* fix highlight blocks

* Hr/azure3 (#103)

* Add Consul and Redis services to Windows.
* Enable Consul and Redis testing

* add dynamo (#104)

* add experimentation event overrides for rules and fallthrough

* warn & don't send event if identify or track has no valid user

* include user in prereq flag events

* rm unnecessary logic

* more factory methods

* update readme to refer to docs

* add Ruby 2.6.2 to CI

* fix missing require for net/http

* stringify built-in user attributes in events, and secondary key for evals

* make const names consistent

* support metric value with track()

* update method description

* applying markdown templates and updating repository url references

* Cleaning up markdown files

* allow skipping database tests

* Updating the package name (#115)

* update package name

* missed one

* revert module entry point name change

* bump ld-eventsource version for stream logging fix

* use YAML.safe_load

* add unit test and temporarily revert fix to demonstrate failure

* restore fix

* add comment about not using FileDataSource in production

* drop events if inbox is full

* update doc comment for track with metric_value

* don't let user fall outside of last bucket in rollout

* refactor evaluation logic and move it out of the main namespace

* comments

* fix type coercion behavior

* make type coercion behavior consistent with earlier versions for now

* whitespace

* break up Evaluator tests further

* make EvaluationReason an immutable class

* FrozenError doesn't exist in older Ruby, use more general RuntimeError

* precompute evaluation reasons when we receive a flag

* rm unused

* rename FeatureStore to DataStore

* remove references to UpdateProcessor (now DataSource)

* add event payload ID header

* (6.0) drop support for old Ruby versions

* add Ruby version constraint to gemspec

* remove Rake dependency

* update ld-eventsource to 1.0.2 which doesn't have Rake dependency

* implement diagnostic events in Ruby (#130)

* update ruby-eventsource to 1.0.3 for backoff bug

* fix incorrect initialization of EventProcessor

* remove install-time openssl check that breaks if you don't have rake

* treat comparison with wrong data type as a non-match, not an exception (#134)

* fail fast for nil SDK key when appropriate

* tolerate nil value for user.custom (#137)

* Only shutdown the Redis pool if it is owned by the SDK (#158)

* Only shutdown a Redis pool created by SDK

* Make pool shutdown behavior an option

* improve doc comment

* remove support for indirect/patch and indirect/put (#138)

* update to json 2.3.1 (#139)

* update json dep to 2.3.x to fix CVE

* add publication of API docs on GitHub Pages (#143)

* try fixing release metadata

* update the default base url (#144)

* revert renames of feature_store & update_processor

* [ch92483] Use http gem and add socket factory support (#142)

* update dependencies and add CI for ruby 3 (#141)

* reference eventsource 2.0 in gemspec

* add 5.x releasable branch for releaser

* use Ruby 2.6.6 in releases

* Removed the guides link

* [ch99757] add alias method (#147)

* don't send event for nil user evaluation

* remove lockfile (#148)

* rm redundant nil check

* Experiment Allocation Changes (#150)

* WIP - from sam's pairing session

* starting sdk changes

* adding tests and making sure everything works

* adding more tests

* removing the singleton for fallthrough

* Revert "removing the singleton for fallthrough"

This reverts commit dff7adbb809ecc63118d0fbff9742a88a039c679.

* taking a different approach to keep things immutable

* adding tests for untracked

* remove unnecessary comment

* making sure to return two values in all code paths

Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>

* Use camelCase for JSON property names (#151)

The in_experiment attribute was added to reasons as part of #150 but it doesn't appear to be received in events. I think that's because it's sending it in JSON as "in_experiment" rather than "inExperiment" as we expect to parse it.

* fixing ruby logic causing ih failures (#152)

* fixing ruby logic

* adding missing spec

* Apply suggestions from code review

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* pr tweaks

* making spec language consistent

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* add log warning for missing user key (#153)

* add log warnings for nil/empty user key

* rm warning for empty string key

* fix test

* diagnostic events should respect HTTPS_PROXY (#154)

* minor test simplification (#155)

* allow higher minor versions of json and http gems

* allow v5.x of http gem (#157)

* use Bundler 2.2.10 + modernize CI config (#158)

* enable verbose rspec output

* fix socket factory tests

* restore log suppression

* Replacing deprecated circleci image usage (#159)

* use Releaser v2 config (#161)

* Updates docs URLs

* Update lib/ldclient-rb/ldclient.rb

Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>

* remove reliance on git in gemspec (#163)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504 (#164)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504

* comment phrasing

* Start work on flag builder.

* Add user targeting and rule builder

* Add datasource implementation

* Convert the current_flags hash to use symbols instead of strings as keys

* Fix typo on FlagRuleBuilder copy constructor

* minor refactoring of impl; Added use of new Clause struct instead of Hash in FlagRuleBuilder; Moved TestData.factory out of Impl namespace and renamed Impl to TestDataImpl

* Add the doc comments

* (big segments 1) add public config/interface/reason types (#167)

* Cleanup docstrings to be YARD docs

* Added Util.is_bool helper function to clean up the check for whether an object is a boolean; Removed the DeepCopyHash/DeepCopyArray objects in favor of deep_copy_hash and deep_copy_array functions

* Move public classes out of Impl namespace. Most of it is in public namespace except for the data source now.

* Move require of concurrent/atomics to the correct module

* (big segments 2) implement Big Segments evaluation & status APIs (#168)

* improve CONTRIBUTING.md with notes on code organization

* add note about doc comments

* Cleanup YARD warnings and cleanup docs

* Address PR feedback: Move is_bool back to Impl namespace to avoid confusion; Remove unnecessary nil check on variations in build function; fixup comments

* (big segments 3) implement Redis & DynamoDB big segment stores (#169)

* add missing import

* fix stale calculation

* fix big segments user hash algorithm to use SHA256

* improve & refactor client/evaluation tests

* more cleanup/DRY

* add use_preconfigured_flag and use_preconfigured_segment to TestData (#173)

* always cache big segment query result even if it's nil

* comments

* add test for cache expiration

* use TestData in our own tests (#174)

* use TestData in our own tests

* fix test

* replace LaunchDarkly::FileDataSource with LaunchDarkly::Integrations::FileData

* update ruby-eventsource version for recent SSE fixes

* Bump bundler version (#184)

* Add ability to to set initial reconnect delay (#183)

* Treat secondary as a built-in attribute (#180)

* all_flags_state is invalid if store isn't initialized (#182)

* identify should not emit events if user key is "" (#181)

* Account for traffic allocation on all flags (#185)

* Add contract tests (#178)

* Fix string interpolation in log message (#187)

* Default opts to empty hash when creating persistent feature store (#186)

* Remove Hakiri badge from README (#188)

Hakiri was sunset on January 31st, 2022 at which time our badge stopped
working.

* detect http/https proxy env vars when creating HTTP clients

* rever accidental change

* fix nil safety in test service config

* master -> main (#190)

* master -> main

* update ruby-eventsource version for parsing efficiency fix

Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: Harpo roeder <hroeder@launchdarkly.com>
Co-authored-by: hroederld <46500128+hroederld@users.noreply.github.com>
Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: Jacob Smith <jacob@jacobsmith.io>
Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: Kerrie Martinez <kyee@launchdarkly.com>
Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>
Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>
Co-authored-by: Matthew M. Keeler <keelerm84@gmail.com>
Co-authored-by: Ben Levy <benjaminlevy007@gmail.com>
Co-authored-by: Ben Levy <ben@foxhound.systems>
Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>
LaunchDarklyReleaseBot added a commit that referenced this issue Jun 30, 2022
* remove net-http-persistent

* fix concurrent-ruby usage that breaks on Windows

* add pipeline and clean up with with rm_rf instead of rm

* fix highlight blocks

* Hr/azure3 (#103)

* Add Consul and Redis services to Windows.
* Enable Consul and Redis testing

* add dynamo (#104)

* add experimentation event overrides for rules and fallthrough

* warn & don't send event if identify or track has no valid user

* include user in prereq flag events

* rm unnecessary logic

* more factory methods

* update readme to refer to docs

* add Ruby 2.6.2 to CI

* fix missing require for net/http

* stringify built-in user attributes in events, and secondary key for evals

* make const names consistent

* support metric value with track()

* update method description

* applying markdown templates and updating repository url references

* Cleaning up markdown files

* allow skipping database tests

* Updating the package name (#115)

* update package name

* missed one

* revert module entry point name change

* bump ld-eventsource version for stream logging fix

* use YAML.safe_load

* add unit test and temporarily revert fix to demonstrate failure

* restore fix

* add comment about not using FileDataSource in production

* drop events if inbox is full

* update doc comment for track with metric_value

* don't let user fall outside of last bucket in rollout

* refactor evaluation logic and move it out of the main namespace

* comments

* fix type coercion behavior

* make type coercion behavior consistent with earlier versions for now

* whitespace

* break up Evaluator tests further

* make EvaluationReason an immutable class

* FrozenError doesn't exist in older Ruby, use more general RuntimeError

* precompute evaluation reasons when we receive a flag

* rm unused

* rename FeatureStore to DataStore

* remove references to UpdateProcessor (now DataSource)

* add event payload ID header

* (6.0) drop support for old Ruby versions

* add Ruby version constraint to gemspec

* remove Rake dependency

* update ld-eventsource to 1.0.2 which doesn't have Rake dependency

* implement diagnostic events in Ruby (#130)

* update ruby-eventsource to 1.0.3 for backoff bug

* fix incorrect initialization of EventProcessor

* remove install-time openssl check that breaks if you don't have rake

* treat comparison with wrong data type as a non-match, not an exception (#134)

* fail fast for nil SDK key when appropriate

* tolerate nil value for user.custom (#137)

* Only shutdown the Redis pool if it is owned by the SDK (#158)

* Only shutdown a Redis pool created by SDK

* Make pool shutdown behavior an option

* improve doc comment

* remove support for indirect/patch and indirect/put (#138)

* update to json 2.3.1 (#139)

* update json dep to 2.3.x to fix CVE

* add publication of API docs on GitHub Pages (#143)

* try fixing release metadata

* update the default base url (#144)

* revert renames of feature_store & update_processor

* [ch92483] Use http gem and add socket factory support (#142)

* update dependencies and add CI for ruby 3 (#141)

* reference eventsource 2.0 in gemspec

* add 5.x releasable branch for releaser

* use Ruby 2.6.6 in releases

* Removed the guides link

* [ch99757] add alias method (#147)

* don't send event for nil user evaluation

* remove lockfile (#148)

* rm redundant nil check

* Experiment Allocation Changes (#150)

* WIP - from sam's pairing session

* starting sdk changes

* adding tests and making sure everything works

* adding more tests

* removing the singleton for fallthrough

* Revert "removing the singleton for fallthrough"

This reverts commit dff7adbb809ecc63118d0fbff9742a88a039c679.

* taking a different approach to keep things immutable

* adding tests for untracked

* remove unnecessary comment

* making sure to return two values in all code paths

Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>

* Use camelCase for JSON property names (#151)

The in_experiment attribute was added to reasons as part of #150 but it doesn't appear to be received in events. I think that's because it's sending it in JSON as "in_experiment" rather than "inExperiment" as we expect to parse it.

* fixing ruby logic causing ih failures (#152)

* fixing ruby logic

* adding missing spec

* Apply suggestions from code review

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* pr tweaks

* making spec language consistent

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* add log warning for missing user key (#153)

* add log warnings for nil/empty user key

* rm warning for empty string key

* fix test

* diagnostic events should respect HTTPS_PROXY (#154)

* minor test simplification (#155)

* allow higher minor versions of json and http gems

* allow v5.x of http gem (#157)

* use Bundler 2.2.10 + modernize CI config (#158)

* enable verbose rspec output

* fix socket factory tests

* restore log suppression

* Replacing deprecated circleci image usage (#159)

* use Releaser v2 config (#161)

* Updates docs URLs

* Update lib/ldclient-rb/ldclient.rb

Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>

* remove reliance on git in gemspec (#163)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504 (#164)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504

* comment phrasing

* Start work on flag builder.

* Add user targeting and rule builder

* Add datasource implementation

* Convert the current_flags hash to use symbols instead of strings as keys

* Fix typo on FlagRuleBuilder copy constructor

* minor refactoring of impl; Added use of new Clause struct instead of Hash in FlagRuleBuilder; Moved TestData.factory out of Impl namespace and renamed Impl to TestDataImpl

* Add the doc comments

* (big segments 1) add public config/interface/reason types (#167)

* Cleanup docstrings to be YARD docs

* Added Util.is_bool helper function to clean up the check for whether an object is a boolean; Removed the DeepCopyHash/DeepCopyArray objects in favor of deep_copy_hash and deep_copy_array functions

* Move public classes out of Impl namespace. Most of it is in public namespace except for the data source now.

* Move require of concurrent/atomics to the correct module

* (big segments 2) implement Big Segments evaluation & status APIs (#168)

* improve CONTRIBUTING.md with notes on code organization

* add note about doc comments

* Cleanup YARD warnings and cleanup docs

* Address PR feedback: Move is_bool back to Impl namespace to avoid confusion; Remove unnecessary nil check on variations in build function; fixup comments

* (big segments 3) implement Redis & DynamoDB big segment stores (#169)

* add missing import

* fix stale calculation

* fix big segments user hash algorithm to use SHA256

* improve & refactor client/evaluation tests

* more cleanup/DRY

* add use_preconfigured_flag and use_preconfigured_segment to TestData (#173)

* always cache big segment query result even if it's nil

* comments

* add test for cache expiration

* use TestData in our own tests (#174)

* use TestData in our own tests

* fix test

* replace LaunchDarkly::FileDataSource with LaunchDarkly::Integrations::FileData

* update ruby-eventsource version for recent SSE fixes

* Bump bundler version (#184)

* Add ability to to set initial reconnect delay (#183)

* Treat secondary as a built-in attribute (#180)

* all_flags_state is invalid if store isn't initialized (#182)

* identify should not emit events if user key is "" (#181)

* Account for traffic allocation on all flags (#185)

* Add contract tests (#178)

* Fix string interpolation in log message (#187)

* Default opts to empty hash when creating persistent feature store (#186)

* Remove Hakiri badge from README (#188)

Hakiri was sunset on January 31st, 2022 at which time our badge stopped
working.

* detect http/https proxy env vars when creating HTTP clients

* rever accidental change

* fix nil safety in test service config

* master -> main (#190)

* master -> main

* update ruby-eventsource version for parsing efficiency fix

* miscellaneous optimizations for event processing (#193)

Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: Harpo roeder <hroeder@launchdarkly.com>
Co-authored-by: hroederld <46500128+hroederld@users.noreply.github.com>
Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: Jacob Smith <jacob@jacobsmith.io>
Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: Kerrie Martinez <kyee@launchdarkly.com>
Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>
Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>
Co-authored-by: Matthew M. Keeler <keelerm84@gmail.com>
Co-authored-by: Ben Levy <benjaminlevy007@gmail.com>
Co-authored-by: Ben Levy <ben@foxhound.systems>
Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>
eli-darkly added a commit that referenced this issue Sep 7, 2022
* Hr/azure3 (#103)

* Add Consul and Redis services to Windows.
* Enable Consul and Redis testing

* add dynamo (#104)

* add experimentation event overrides for rules and fallthrough

* warn & don't send event if identify or track has no valid user

* include user in prereq flag events

* rm unnecessary logic

* more factory methods

* update readme to refer to docs

* add Ruby 2.6.2 to CI

* fix missing require for net/http

* stringify built-in user attributes in events, and secondary key for evals

* make const names consistent

* support metric value with track()

* update method description

* applying markdown templates and updating repository url references

* Cleaning up markdown files

* allow skipping database tests

* Updating the package name (#115)

* update package name

* missed one

* revert module entry point name change

* bump ld-eventsource version for stream logging fix

* use YAML.safe_load

* add unit test and temporarily revert fix to demonstrate failure

* restore fix

* add comment about not using FileDataSource in production

* drop events if inbox is full

* update doc comment for track with metric_value

* don't let user fall outside of last bucket in rollout

* refactor evaluation logic and move it out of the main namespace

* comments

* fix type coercion behavior

* make type coercion behavior consistent with earlier versions for now

* whitespace

* break up Evaluator tests further

* make EvaluationReason an immutable class

* FrozenError doesn't exist in older Ruby, use more general RuntimeError

* precompute evaluation reasons when we receive a flag

* rm unused

* rename FeatureStore to DataStore

* remove references to UpdateProcessor (now DataSource)

* add event payload ID header

* (6.0) drop support for old Ruby versions

* add Ruby version constraint to gemspec

* remove Rake dependency

* update ld-eventsource to 1.0.2 which doesn't have Rake dependency

* implement diagnostic events in Ruby (#130)

* update ruby-eventsource to 1.0.3 for backoff bug

* fix incorrect initialization of EventProcessor

* remove install-time openssl check that breaks if you don't have rake

* treat comparison with wrong data type as a non-match, not an exception (#134)

* fail fast for nil SDK key when appropriate

* tolerate nil value for user.custom (#137)

* Only shutdown the Redis pool if it is owned by the SDK (#158)

* Only shutdown a Redis pool created by SDK

* Make pool shutdown behavior an option

* improve doc comment

* remove support for indirect/patch and indirect/put (#138)

* update to json 2.3.1 (#139)

* update json dep to 2.3.x to fix CVE

* add publication of API docs on GitHub Pages (#143)

* try fixing release metadata

* update the default base url (#144)

* revert renames of feature_store & update_processor

* [ch92483] Use http gem and add socket factory support (#142)

* update dependencies and add CI for ruby 3 (#141)

* reference eventsource 2.0 in gemspec

* add 5.x releasable branch for releaser

* use Ruby 2.6.6 in releases

* Removed the guides link

* [ch99757] add alias method (#147)

* don't send event for nil user evaluation

* remove lockfile (#148)

* rm redundant nil check

* Experiment Allocation Changes (#150)

* WIP - from sam's pairing session

* starting sdk changes

* adding tests and making sure everything works

* adding more tests

* removing the singleton for fallthrough

* Revert "removing the singleton for fallthrough"

This reverts commit dff7adbb809ecc63118d0fbff9742a88a039c679.

* taking a different approach to keep things immutable

* adding tests for untracked

* remove unnecessary comment

* making sure to return two values in all code paths

Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>

* Use camelCase for JSON property names (#151)

The in_experiment attribute was added to reasons as part of #150 but it doesn't appear to be received in events. I think that's because it's sending it in JSON as "in_experiment" rather than "inExperiment" as we expect to parse it.

* fixing ruby logic causing ih failures (#152)

* fixing ruby logic

* adding missing spec

* Apply suggestions from code review

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* pr tweaks

* making spec language consistent

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* add log warning for missing user key (#153)

* add log warnings for nil/empty user key

* rm warning for empty string key

* fix test

* diagnostic events should respect HTTPS_PROXY (#154)

* minor test simplification (#155)

* allow higher minor versions of json and http gems

* allow v5.x of http gem (#157)

* use Bundler 2.2.10 + modernize CI config (#158)

* enable verbose rspec output

* fix socket factory tests

* restore log suppression

* Replacing deprecated circleci image usage (#159)

* use Releaser v2 config (#161)

* Updates docs URLs

* Update lib/ldclient-rb/ldclient.rb

Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>

* remove reliance on git in gemspec (#163)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504 (#164)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504

* comment phrasing

* Start work on flag builder.

* Add user targeting and rule builder

* Add datasource implementation

* Convert the current_flags hash to use symbols instead of strings as keys

* Fix typo on FlagRuleBuilder copy constructor

* minor refactoring of impl; Added use of new Clause struct instead of Hash in FlagRuleBuilder; Moved TestData.factory out of Impl namespace and renamed Impl to TestDataImpl

* Add the doc comments

* (big segments 1) add public config/interface/reason types (#167)

* Cleanup docstrings to be YARD docs

* Added Util.is_bool helper function to clean up the check for whether an object is a boolean; Removed the DeepCopyHash/DeepCopyArray objects in favor of deep_copy_hash and deep_copy_array functions

* Move public classes out of Impl namespace. Most of it is in public namespace except for the data source now.

* Move require of concurrent/atomics to the correct module

* (big segments 2) implement Big Segments evaluation & status APIs (#168)

* improve CONTRIBUTING.md with notes on code organization

* add note about doc comments

* Cleanup YARD warnings and cleanup docs

* Address PR feedback: Move is_bool back to Impl namespace to avoid confusion; Remove unnecessary nil check on variations in build function; fixup comments

* (big segments 3) implement Redis & DynamoDB big segment stores (#169)

* add missing import

* fix stale calculation

* fix big segments user hash algorithm to use SHA256

* improve & refactor client/evaluation tests

* more cleanup/DRY

* add use_preconfigured_flag and use_preconfigured_segment to TestData (#173)

* always cache big segment query result even if it's nil

* comments

* add test for cache expiration

* use TestData in our own tests (#174)

* use TestData in our own tests

* fix test

* replace LaunchDarkly::FileDataSource with LaunchDarkly::Integrations::FileData

* update ruby-eventsource version for recent SSE fixes

* Bump bundler version (#184)

* Add ability to to set initial reconnect delay (#183)

* Treat secondary as a built-in attribute (#180)

* all_flags_state is invalid if store isn't initialized (#182)

* identify should not emit events if user key is "" (#181)

* Account for traffic allocation on all flags (#185)

* Add contract tests (#178)

* Fix string interpolation in log message (#187)

* Default opts to empty hash when creating persistent feature store (#186)

* Remove Hakiri badge from README (#188)

Hakiri was sunset on January 31st, 2022 at which time our badge stopped
working.

* detect http/https proxy env vars when creating HTTP clients

* rever accidental change

* fix nil safety in test service config

* master -> main (#190)

* master -> main

* update ruby-eventsource version for parsing efficiency fix

* miscellaneous optimizations for event processing (#193)

* Add polling support for contract test service (#198)

* Add windows tests in circleci (#199)

At some point in the past, we were experimenting with using Azure to
verify Window builds. Now that CircleCI supports Windows, we should keep
everything on a single CI provider.

* Add application info support (#194)

* reuse EvaluationDetail instances by precomputing results

Co-authored-by: hroederld <46500128+hroederld@users.noreply.github.com>
Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: Jacob Smith <jacob@jacobsmith.io>
Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: hroederld <hroeder@launchdarkly.com>
Co-authored-by: Kerrie Martinez <kyee@launchdarkly.com>
Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>
Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>
Co-authored-by: Matthew M. Keeler <keelerm84@gmail.com>
Co-authored-by: Ben Levy <benjaminlevy007@gmail.com>
Co-authored-by: Ben Levy <ben@foxhound.systems>
Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>
Co-authored-by: Louis Chan <lchan@launchdarkly.com>
LaunchDarklyReleaseBot added a commit that referenced this issue Dec 30, 2022
* don't let user fall outside of last bucket in rollout

* refactor evaluation logic and move it out of the main namespace

* comments

* fix type coercion behavior

* make type coercion behavior consistent with earlier versions for now

* whitespace

* break up Evaluator tests further

* make EvaluationReason an immutable class

* FrozenError doesn't exist in older Ruby, use more general RuntimeError

* precompute evaluation reasons when we receive a flag

* rm unused

* rename FeatureStore to DataStore

* remove references to UpdateProcessor (now DataSource)

* add event payload ID header

* (6.0) drop support for old Ruby versions

* add Ruby version constraint to gemspec

* remove Rake dependency

* update ld-eventsource to 1.0.2 which doesn't have Rake dependency

* implement diagnostic events in Ruby (#130)

* update ruby-eventsource to 1.0.3 for backoff bug

* fix incorrect initialization of EventProcessor

* remove install-time openssl check that breaks if you don't have rake

* treat comparison with wrong data type as a non-match, not an exception (#134)

* fail fast for nil SDK key when appropriate

* tolerate nil value for user.custom (#137)

* Only shutdown the Redis pool if it is owned by the SDK (#158)

* Only shutdown a Redis pool created by SDK

* Make pool shutdown behavior an option

* improve doc comment

* remove support for indirect/patch and indirect/put (#138)

* update to json 2.3.1 (#139)

* update json dep to 2.3.x to fix CVE

* add publication of API docs on GitHub Pages (#143)

* try fixing release metadata

* update the default base url (#144)

* revert renames of feature_store & update_processor

* [ch92483] Use http gem and add socket factory support (#142)

* update dependencies and add CI for ruby 3 (#141)

* reference eventsource 2.0 in gemspec

* add 5.x releasable branch for releaser

* use Ruby 2.6.6 in releases

* Removed the guides link

* [ch99757] add alias method (#147)

* don't send event for nil user evaluation

* remove lockfile (#148)

* rm redundant nil check

* Experiment Allocation Changes (#150)

* WIP - from sam's pairing session

* starting sdk changes

* adding tests and making sure everything works

* adding more tests

* removing the singleton for fallthrough

* Revert "removing the singleton for fallthrough"

This reverts commit dff7adbb809ecc63118d0fbff9742a88a039c679.

* taking a different approach to keep things immutable

* adding tests for untracked

* remove unnecessary comment

* making sure to return two values in all code paths

Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>

* Use camelCase for JSON property names (#151)

The in_experiment attribute was added to reasons as part of #150 but it doesn't appear to be received in events. I think that's because it's sending it in JSON as "in_experiment" rather than "inExperiment" as we expect to parse it.

* fixing ruby logic causing ih failures (#152)

* fixing ruby logic

* adding missing spec

* Apply suggestions from code review

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* pr tweaks

* making spec language consistent

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* add log warning for missing user key (#153)

* add log warnings for nil/empty user key

* rm warning for empty string key

* fix test

* diagnostic events should respect HTTPS_PROXY (#154)

* minor test simplification (#155)

* allow higher minor versions of json and http gems

* allow v5.x of http gem (#157)

* use Bundler 2.2.10 + modernize CI config (#158)

* enable verbose rspec output

* fix socket factory tests

* restore log suppression

* Replacing deprecated circleci image usage (#159)

* use Releaser v2 config (#161)

* Updates docs URLs

* Update lib/ldclient-rb/ldclient.rb

Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>

* remove reliance on git in gemspec (#163)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504 (#164)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504

* comment phrasing

* Start work on flag builder.

* Add user targeting and rule builder

* Add datasource implementation

* Convert the current_flags hash to use symbols instead of strings as keys

* Fix typo on FlagRuleBuilder copy constructor

* minor refactoring of impl; Added use of new Clause struct instead of Hash in FlagRuleBuilder; Moved TestData.factory out of Impl namespace and renamed Impl to TestDataImpl

* Add the doc comments

* (big segments 1) add public config/interface/reason types (#167)

* Cleanup docstrings to be YARD docs

* Added Util.is_bool helper function to clean up the check for whether an object is a boolean; Removed the DeepCopyHash/DeepCopyArray objects in favor of deep_copy_hash and deep_copy_array functions

* Move public classes out of Impl namespace. Most of it is in public namespace except for the data source now.

* Move require of concurrent/atomics to the correct module

* (big segments 2) implement Big Segments evaluation & status APIs (#168)

* improve CONTRIBUTING.md with notes on code organization

* add note about doc comments

* Cleanup YARD warnings and cleanup docs

* Address PR feedback: Move is_bool back to Impl namespace to avoid confusion; Remove unnecessary nil check on variations in build function; fixup comments

* (big segments 3) implement Redis & DynamoDB big segment stores (#169)

* add missing import

* fix stale calculation

* fix big segments user hash algorithm to use SHA256

* improve & refactor client/evaluation tests

* more cleanup/DRY

* add use_preconfigured_flag and use_preconfigured_segment to TestData (#173)

* always cache big segment query result even if it's nil

* comments

* add test for cache expiration

* use TestData in our own tests (#174)

* use TestData in our own tests

* fix test

* replace LaunchDarkly::FileDataSource with LaunchDarkly::Integrations::FileData

* update ruby-eventsource version for recent SSE fixes

* Bump bundler version (#184)

* Add ability to to set initial reconnect delay (#183)

* Treat secondary as a built-in attribute (#180)

* all_flags_state is invalid if store isn't initialized (#182)

* identify should not emit events if user key is "" (#181)

* Account for traffic allocation on all flags (#185)

* Add contract tests (#178)

* Fix string interpolation in log message (#187)

* Default opts to empty hash when creating persistent feature store (#186)

* Remove Hakiri badge from README (#188)

Hakiri was sunset on January 31st, 2022 at which time our badge stopped
working.

* detect http/https proxy env vars when creating HTTP clients

* rever accidental change

* fix nil safety in test service config

* master -> main (#190)

* master -> main

* update ruby-eventsource version for parsing efficiency fix

* miscellaneous optimizations for event processing (#193)

* Drop support for EOL ruby versions (#196)

Ruby 2.5 was EOL 2021-04-05

As of June 27th, 2022, the latest jRuby is Ruby 2.6 compatible.

* Remove alias support (#195)

* Add polling support for contract test service (#198)

* Update rubocop and enable in CI (#197)

Several of the Rubocop cop definitions have been renamed or moved to
entirely other gems. This brings the configuration up to date with the
latest naming conventions.

* Add windows tests in circleci (#199)

At some point in the past, we were experimenting with using Azure to
verify Window builds. Now that CircleCI supports Windows, we should keep
everything on a single CI provider.

* Add application info support (#194)

* reuse EvaluationDetail instances by precomputing results

* rubocop reformatting

* add super constructor calls

* disable rubocop Rails rules and fix some remaining syntax offenses

* fix super calls

* Add big segment support to contract tests (#201)

* Initial creation of LDContext (#206)

This introduces the initial structure and usage of the LDContext class.

Instances of this class are expected to be created through static
factory methods:

```ruby
LaunchDarkly::LDContext.create({...})
LaunchDarkly::LDContext.create_multi([...])
```

This class is not completed yet. Rather, this initial commit is focused
on the creation patterns and the most basic operations. Subsequent
commits will continue fleshing out this class and its operation.

The `get_value` method will see significant changes as we introduce
attribute reference support. Its current more simplistic implementation
exists only to serve some interim unit tests.

* Add reference based value retrieval (#207)

This commit introduces the References type used for targeting complex
attributes in the new LDContexts.

References are expected to be created through static factory methods:

```ruby
LaunchDarkly::Reference.create("/a/b")
LaunchDarkly::Reference.create_literal("/a/b")
```

These references can be used to retrieve values from an existing
LDContext

```ruby
ref = LaunchDarkly::Reference.create("/a/b")
result = context.get_value_for_reference(ref)
```

* Basic changes to use contexts in evaluations instead of users (#208)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

This replaces `LDUser` with `LDContext` in the parameters for
evaluations, and makes the minimum necessary adjustments to allow
evaluations to keep working as before as long as the context kind is
"user". None of the new behavior defined in the U2C spec is implemented
yet.

Generation of evaluation events is temporarily disabled because the
event logic hasn't been updated yet.

U2C contract tests for evaluations are partially enabled; a lot of
functionality is still missing, but all the tests that only cover
previously-existing evaluation behavior are passing.

[pr]: launchdarkly/php-server-sdk-private#103

* Support ContextKind in Clauses (#209)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

The main features of this commit are:

- introduction of `individual_context` and `individual_context_count`
  methods 
- context kind matching in clauses

[pr]: launchdarkly/php-server-sdk-private#108

* Support included / excluded contexts in segments (#210)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

Segments are now able to provide `includedContext` and `excludedContext`
properties which can target values within a specific context kind.

```json
{
    "includedContexts": [
        {
            "contextKind": "org",
            "values": ["orgkey1", "orgkey2"]
        }
    ]
}
```

[pr]: launchdarkly/php-server-sdk-private#111

* Add contextKind support for rollouts & experiements (#211)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

[pr]: launchdarkly/php-server-sdk-private#110

* Style and test matcher improvements (#212)

This commit enables several rubocop rules that were previously disabled.
Once enabled, `rubocop -A` was run to automatically apply these fixes.

There are a couple of additional changes that were made by hand:

- I added the rubocop and rubocop-performance gems as dev packages. This
  should help address the original installation issue we ran into when I
  introduced these tools.

- By default, new rubocop rules are disabled. This was the default
  before, but if you don't explicitly set this value, each run generates
  a ton of warning noise. This quiets that down.

- Updates some LDContext tests to be more strict in their expectations
  of truth.

* Remove support for secondary attribute (#213)

As decided in the [spec], we are removing the special behavior of the
secondary attribute. Going forward, secondary will be treated like any
other attribute, and will no longer be included when determining the
bucket for a context.

[spec]:
https://launchdarkly.atlassian.net/wiki/spaces/ENG/pages/2165212563/Consistent+and+Transparent+Rollout+Behavior+Unifying+Percent+Rollout+and+Traffic+Allocation

* Remove deprecated APIs (#214)

Since the users to context change requires a version break, this is the
perfect time to remove previously deprecated bits of functionality. This
includes:

- Removing `update_processor*` config entries
- `FileDataSource` entry point
- `RedisFeatureStore` entry point
- `Redis::sadd?` warning in unit tests

* store data model with classes that aren't Hash

* lint

* remove [] override methods in places where we don't need them

* comments

* migrate some more of the model to be non-hash classes

* lint

* Anonymous cannot be nil in new context format (#216)

The legacy user format allowed anonymous to be missing or explicitly
provided but set to nil.

The new context format requires anonymous to either not be set, or if it
is explicitly set, it must be a boolean value.

* Tweak error message language and style (#217)

Our previous error messages suffered from a couple drawbacks:

- The messages were complete sentences, limiting our ability to compose
  error messages
- The messages were overly broad in many cases
- The messages unnecessarily required string interpolation that rarely
  provided much value

These new messages are more succinct and are written as small clauses
which can be used in conjunction with other error messages more easily.

* copyedit

Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>

* Implement prerequisite cycle detection (#219)

* Support attribute reference lookups (#215)

This adds support for slash-delimited paths in clause attributes,
bucketBy, etc. It does not do anything related to private attribute
redaction because none of the U2C event logic is implemented yet.

* Implement segment recursion and cycle detection (#220)

Clauses in segment rules are now allowed to reference segments. To
prevent an infinite recursion edge case, we implement a similar cycle
detection mechanism as used on prerequisites.

* Update event logic to support users to context change (#221)

* Add legacy user-type support to the contract tests (#222)

* Remove inline user configuration option (#223)

* Add context_ configuration options (#224)

These new context_ configuration options are meant to replace the
historic user_ options. If both are provided, the context_ variant will
take precedence.

* Add support for flag context targets (#225)

* Bump diplomat

* Bump redis

* Remove oga

* Bump connection_pool

* Favor set for faster target lookups (#228)

A few of our internal models maintain arrays of values. These arrays can
frequently be checked to see if they contain specific values.

Since set lookups are much faster than array lookups, this commit
changes the internal structure to a set for the values stored in Target
and SegmentTarget.

* Add secure mode hash to contract tests (#229)

* Update big segment support for users to context (#226)

To support the users to context change for big segments, this commit
makes the following changes:

- Introduces a new `Segment.unboundedContextKind` attribute. This will
default to `LDContext::KIND_DEFAULT` and is only referenced when
`Segment.unbounded` is true.

- With the creation of multi-kind contexts, a single evaluation may
result in multiple queries to the big segment store. This is reflected
in the changes to the `EvalResult` processing.

* Drop support for ruby 2.6 (#227)

Ruby 2.6 went EOL in March 2022. We originally didn't drop support for
it as doing so would require dropping support for jRuby as well.
However, jRuby recently released 9.4 which is Ruby 2.7+ compatible.

* Update remaining references from user to contexts (#231)

There are multiple places throughout the code where we are still
referencing users. I have tried to update all the places where a rename
seems reasonable or appropriate. There is still some work to do in the
test flag builders, but that will be done in a subsequent commit.

* Remove new relic integration (#233)

The new relic integration was removed many versions ago but a small
trace remained behind.

* Rename config option private_attribute_names (#234)

Co-authored-by: Eli Bishop <eli@launchdarkly.com>

* Update test data integration to support contexts (#232)

Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: Jacob Smith <jacob@jacobsmith.io>
Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: hroederld <hroeder@launchdarkly.com>
Co-authored-by: Kerrie Martinez <kyee@launchdarkly.com>
Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>
Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>
Co-authored-by: Matthew M. Keeler <keelerm84@gmail.com>
Co-authored-by: Ben Levy <benjaminlevy007@gmail.com>
Co-authored-by: Ben Levy <ben@foxhound.systems>
Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>
Co-authored-by: Louis Chan <lchan@launchdarkly.com>
LaunchDarklyReleaseBot added a commit that referenced this issue Jan 19, 2023
* don't let user fall outside of last bucket in rollout

* refactor evaluation logic and move it out of the main namespace

* comments

* fix type coercion behavior

* make type coercion behavior consistent with earlier versions for now

* whitespace

* break up Evaluator tests further

* make EvaluationReason an immutable class

* FrozenError doesn't exist in older Ruby, use more general RuntimeError

* precompute evaluation reasons when we receive a flag

* rm unused

* rename FeatureStore to DataStore

* remove references to UpdateProcessor (now DataSource)

* add event payload ID header

* (6.0) drop support for old Ruby versions

* add Ruby version constraint to gemspec

* remove Rake dependency

* update ld-eventsource to 1.0.2 which doesn't have Rake dependency

* implement diagnostic events in Ruby (#130)

* update ruby-eventsource to 1.0.3 for backoff bug

* fix incorrect initialization of EventProcessor

* remove install-time openssl check that breaks if you don't have rake

* treat comparison with wrong data type as a non-match, not an exception (#134)

* fail fast for nil SDK key when appropriate

* tolerate nil value for user.custom (#137)

* Only shutdown the Redis pool if it is owned by the SDK (#158)

* Only shutdown a Redis pool created by SDK

* Make pool shutdown behavior an option

* improve doc comment

* remove support for indirect/patch and indirect/put (#138)

* update to json 2.3.1 (#139)

* update json dep to 2.3.x to fix CVE

* add publication of API docs on GitHub Pages (#143)

* try fixing release metadata

* update the default base url (#144)

* revert renames of feature_store & update_processor

* [ch92483] Use http gem and add socket factory support (#142)

* update dependencies and add CI for ruby 3 (#141)

* reference eventsource 2.0 in gemspec

* add 5.x releasable branch for releaser

* use Ruby 2.6.6 in releases

* Removed the guides link

* [ch99757] add alias method (#147)

* don't send event for nil user evaluation

* remove lockfile (#148)

* rm redundant nil check

* Experiment Allocation Changes (#150)

* WIP - from sam's pairing session

* starting sdk changes

* adding tests and making sure everything works

* adding more tests

* removing the singleton for fallthrough

* Revert "removing the singleton for fallthrough"

This reverts commit dff7adbb809ecc63118d0fbff9742a88a039c679.

* taking a different approach to keep things immutable

* adding tests for untracked

* remove unnecessary comment

* making sure to return two values in all code paths

Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>

* Use camelCase for JSON property names (#151)

The in_experiment attribute was added to reasons as part of #150 but it doesn't appear to be received in events. I think that's because it's sending it in JSON as "in_experiment" rather than "inExperiment" as we expect to parse it.

* fixing ruby logic causing ih failures (#152)

* fixing ruby logic

* adding missing spec

* Apply suggestions from code review

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* pr tweaks

* making spec language consistent

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* add log warning for missing user key (#153)

* add log warnings for nil/empty user key

* rm warning for empty string key

* fix test

* diagnostic events should respect HTTPS_PROXY (#154)

* minor test simplification (#155)

* allow higher minor versions of json and http gems

* allow v5.x of http gem (#157)

* use Bundler 2.2.10 + modernize CI config (#158)

* enable verbose rspec output

* fix socket factory tests

* restore log suppression

* Replacing deprecated circleci image usage (#159)

* use Releaser v2 config (#161)

* Updates docs URLs

* Update lib/ldclient-rb/ldclient.rb

Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>

* remove reliance on git in gemspec (#163)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504 (#164)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504

* comment phrasing

* Start work on flag builder.

* Add user targeting and rule builder

* Add datasource implementation

* Convert the current_flags hash to use symbols instead of strings as keys

* Fix typo on FlagRuleBuilder copy constructor

* minor refactoring of impl; Added use of new Clause struct instead of Hash in FlagRuleBuilder; Moved TestData.factory out of Impl namespace and renamed Impl to TestDataImpl

* Add the doc comments

* (big segments 1) add public config/interface/reason types (#167)

* Cleanup docstrings to be YARD docs

* Added Util.is_bool helper function to clean up the check for whether an object is a boolean; Removed the DeepCopyHash/DeepCopyArray objects in favor of deep_copy_hash and deep_copy_array functions

* Move public classes out of Impl namespace. Most of it is in public namespace except for the data source now.

* Move require of concurrent/atomics to the correct module

* (big segments 2) implement Big Segments evaluation & status APIs (#168)

* improve CONTRIBUTING.md with notes on code organization

* add note about doc comments

* Cleanup YARD warnings and cleanup docs

* Address PR feedback: Move is_bool back to Impl namespace to avoid confusion; Remove unnecessary nil check on variations in build function; fixup comments

* (big segments 3) implement Redis & DynamoDB big segment stores (#169)

* add missing import

* fix stale calculation

* fix big segments user hash algorithm to use SHA256

* improve & refactor client/evaluation tests

* more cleanup/DRY

* add use_preconfigured_flag and use_preconfigured_segment to TestData (#173)

* always cache big segment query result even if it's nil

* comments

* add test for cache expiration

* use TestData in our own tests (#174)

* use TestData in our own tests

* fix test

* replace LaunchDarkly::FileDataSource with LaunchDarkly::Integrations::FileData

* update ruby-eventsource version for recent SSE fixes

* Bump bundler version (#184)

* Add ability to to set initial reconnect delay (#183)

* Treat secondary as a built-in attribute (#180)

* all_flags_state is invalid if store isn't initialized (#182)

* identify should not emit events if user key is "" (#181)

* Account for traffic allocation on all flags (#185)

* Add contract tests (#178)

* Fix string interpolation in log message (#187)

* Default opts to empty hash when creating persistent feature store (#186)

* Remove Hakiri badge from README (#188)

Hakiri was sunset on January 31st, 2022 at which time our badge stopped
working.

* detect http/https proxy env vars when creating HTTP clients

* rever accidental change

* fix nil safety in test service config

* master -> main (#190)

* master -> main

* update ruby-eventsource version for parsing efficiency fix

* miscellaneous optimizations for event processing (#193)

* Drop support for EOL ruby versions (#196)

Ruby 2.5 was EOL 2021-04-05

As of June 27th, 2022, the latest jRuby is Ruby 2.6 compatible.

* Remove alias support (#195)

* Add polling support for contract test service (#198)

* Update rubocop and enable in CI (#197)

Several of the Rubocop cop definitions have been renamed or moved to
entirely other gems. This brings the configuration up to date with the
latest naming conventions.

* Add windows tests in circleci (#199)

At some point in the past, we were experimenting with using Azure to
verify Window builds. Now that CircleCI supports Windows, we should keep
everything on a single CI provider.

* Add application info support (#194)

* reuse EvaluationDetail instances by precomputing results

* rubocop reformatting

* add super constructor calls

* disable rubocop Rails rules and fix some remaining syntax offenses

* fix super calls

* Add big segment support to contract tests (#201)

* Initial creation of LDContext (#206)

This introduces the initial structure and usage of the LDContext class.

Instances of this class are expected to be created through static
factory methods:

```ruby
LaunchDarkly::LDContext.create({...})
LaunchDarkly::LDContext.create_multi([...])
```

This class is not completed yet. Rather, this initial commit is focused
on the creation patterns and the most basic operations. Subsequent
commits will continue fleshing out this class and its operation.

The `get_value` method will see significant changes as we introduce
attribute reference support. Its current more simplistic implementation
exists only to serve some interim unit tests.

* Add reference based value retrieval (#207)

This commit introduces the References type used for targeting complex
attributes in the new LDContexts.

References are expected to be created through static factory methods:

```ruby
LaunchDarkly::Reference.create("/a/b")
LaunchDarkly::Reference.create_literal("/a/b")
```

These references can be used to retrieve values from an existing
LDContext

```ruby
ref = LaunchDarkly::Reference.create("/a/b")
result = context.get_value_for_reference(ref)
```

* Basic changes to use contexts in evaluations instead of users (#208)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

This replaces `LDUser` with `LDContext` in the parameters for
evaluations, and makes the minimum necessary adjustments to allow
evaluations to keep working as before as long as the context kind is
"user". None of the new behavior defined in the U2C spec is implemented
yet.

Generation of evaluation events is temporarily disabled because the
event logic hasn't been updated yet.

U2C contract tests for evaluations are partially enabled; a lot of
functionality is still missing, but all the tests that only cover
previously-existing evaluation behavior are passing.

[pr]: launchdarkly/php-server-sdk-private#103

* Support ContextKind in Clauses (#209)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

The main features of this commit are:

- introduction of `individual_context` and `individual_context_count`
  methods 
- context kind matching in clauses

[pr]: launchdarkly/php-server-sdk-private#108

* Support included / excluded contexts in segments (#210)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

Segments are now able to provide `includedContext` and `excludedContext`
properties which can target values within a specific context kind.

```json
{
    "includedContexts": [
        {
            "contextKind": "org",
            "values": ["orgkey1", "orgkey2"]
        }
    ]
}
```

[pr]: launchdarkly/php-server-sdk-private#111

* Add contextKind support for rollouts & experiements (#211)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

[pr]: launchdarkly/php-server-sdk-private#110

* Style and test matcher improvements (#212)

This commit enables several rubocop rules that were previously disabled.
Once enabled, `rubocop -A` was run to automatically apply these fixes.

There are a couple of additional changes that were made by hand:

- I added the rubocop and rubocop-performance gems as dev packages. This
  should help address the original installation issue we ran into when I
  introduced these tools.

- By default, new rubocop rules are disabled. This was the default
  before, but if you don't explicitly set this value, each run generates
  a ton of warning noise. This quiets that down.

- Updates some LDContext tests to be more strict in their expectations
  of truth.

* Remove support for secondary attribute (#213)

As decided in the [spec], we are removing the special behavior of the
secondary attribute. Going forward, secondary will be treated like any
other attribute, and will no longer be included when determining the
bucket for a context.

[spec]:
https://launchdarkly.atlassian.net/wiki/spaces/ENG/pages/2165212563/Consistent+and+Transparent+Rollout+Behavior+Unifying+Percent+Rollout+and+Traffic+Allocation

* Remove deprecated APIs (#214)

Since the users to context change requires a version break, this is the
perfect time to remove previously deprecated bits of functionality. This
includes:

- Removing `update_processor*` config entries
- `FileDataSource` entry point
- `RedisFeatureStore` entry point
- `Redis::sadd?` warning in unit tests

* store data model with classes that aren't Hash

* lint

* remove [] override methods in places where we don't need them

* comments

* migrate some more of the model to be non-hash classes

* lint

* Anonymous cannot be nil in new context format (#216)

The legacy user format allowed anonymous to be missing or explicitly
provided but set to nil.

The new context format requires anonymous to either not be set, or if it
is explicitly set, it must be a boolean value.

* Tweak error message language and style (#217)

Our previous error messages suffered from a couple drawbacks:

- The messages were complete sentences, limiting our ability to compose
  error messages
- The messages were overly broad in many cases
- The messages unnecessarily required string interpolation that rarely
  provided much value

These new messages are more succinct and are written as small clauses
which can be used in conjunction with other error messages more easily.

* copyedit

Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>

* Implement prerequisite cycle detection (#219)

* Support attribute reference lookups (#215)

This adds support for slash-delimited paths in clause attributes,
bucketBy, etc. It does not do anything related to private attribute
redaction because none of the U2C event logic is implemented yet.

* Implement segment recursion and cycle detection (#220)

Clauses in segment rules are now allowed to reference segments. To
prevent an infinite recursion edge case, we implement a similar cycle
detection mechanism as used on prerequisites.

* Update event logic to support users to context change (#221)

* Add legacy user-type support to the contract tests (#222)

* Remove inline user configuration option (#223)

* Add context_ configuration options (#224)

These new context_ configuration options are meant to replace the
historic user_ options. If both are provided, the context_ variant will
take precedence.

* Add support for flag context targets (#225)

* Bump diplomat

* Bump redis

* Remove oga

* Bump connection_pool

* Favor set for faster target lookups (#228)

A few of our internal models maintain arrays of values. These arrays can
frequently be checked to see if they contain specific values.

Since set lookups are much faster than array lookups, this commit
changes the internal structure to a set for the values stored in Target
and SegmentTarget.

* Add secure mode hash to contract tests (#229)

* Update big segment support for users to context (#226)

To support the users to context change for big segments, this commit
makes the following changes:

- Introduces a new `Segment.unboundedContextKind` attribute. This will
default to `LDContext::KIND_DEFAULT` and is only referenced when
`Segment.unbounded` is true.

- With the creation of multi-kind contexts, a single evaluation may
result in multiple queries to the big segment store. This is reflected
in the changes to the `EvalResult` processing.

* Drop support for ruby 2.6 (#227)

Ruby 2.6 went EOL in March 2022. We originally didn't drop support for
it as doing so would require dropping support for jRuby as well.
However, jRuby recently released 9.4 which is Ruby 2.7+ compatible.

* Update remaining references from user to contexts (#231)

There are multiple places throughout the code where we are still
referencing users. I have tried to update all the places where a rename
seems reasonable or appropriate. There is still some work to do in the
test flag builders, but that will be done in a subsequent commit.

* Remove new relic integration (#233)

The new relic integration was removed many versions ago but a small
trace remained behind.

* Rename config option private_attribute_names (#234)

Co-authored-by: Eli Bishop <eli@launchdarkly.com>

* Update test data integration to support contexts (#232)

* improve data model validation logging; allow missing/empty attribute for segmentMatch (#236)

Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: Jacob Smith <jacob@jacobsmith.io>
Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: hroederld <hroeder@launchdarkly.com>
Co-authored-by: Kerrie Martinez <kyee@launchdarkly.com>
Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>
Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>
Co-authored-by: Matthew M. Keeler <keelerm84@gmail.com>
Co-authored-by: Ben Levy <benjaminlevy007@gmail.com>
Co-authored-by: Ben Levy <ben@foxhound.systems>
Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>
Co-authored-by: Louis Chan <lchan@launchdarkly.com>
LaunchDarklyReleaseBot added a commit that referenced this issue Jan 27, 2023
* don't let user fall outside of last bucket in rollout

* refactor evaluation logic and move it out of the main namespace

* comments

* fix type coercion behavior

* make type coercion behavior consistent with earlier versions for now

* whitespace

* break up Evaluator tests further

* make EvaluationReason an immutable class

* FrozenError doesn't exist in older Ruby, use more general RuntimeError

* precompute evaluation reasons when we receive a flag

* rm unused

* rename FeatureStore to DataStore

* remove references to UpdateProcessor (now DataSource)

* add event payload ID header

* (6.0) drop support for old Ruby versions

* add Ruby version constraint to gemspec

* remove Rake dependency

* update ld-eventsource to 1.0.2 which doesn't have Rake dependency

* implement diagnostic events in Ruby (#130)

* update ruby-eventsource to 1.0.3 for backoff bug

* fix incorrect initialization of EventProcessor

* remove install-time openssl check that breaks if you don't have rake

* treat comparison with wrong data type as a non-match, not an exception (#134)

* fail fast for nil SDK key when appropriate

* tolerate nil value for user.custom (#137)

* Only shutdown the Redis pool if it is owned by the SDK (#158)

* Only shutdown a Redis pool created by SDK

* Make pool shutdown behavior an option

* improve doc comment

* remove support for indirect/patch and indirect/put (#138)

* update to json 2.3.1 (#139)

* update json dep to 2.3.x to fix CVE

* add publication of API docs on GitHub Pages (#143)

* try fixing release metadata

* update the default base url (#144)

* revert renames of feature_store & update_processor

* [ch92483] Use http gem and add socket factory support (#142)

* update dependencies and add CI for ruby 3 (#141)

* reference eventsource 2.0 in gemspec

* add 5.x releasable branch for releaser

* use Ruby 2.6.6 in releases

* Removed the guides link

* [ch99757] add alias method (#147)

* don't send event for nil user evaluation

* remove lockfile (#148)

* rm redundant nil check

* Experiment Allocation Changes (#150)

* WIP - from sam's pairing session

* starting sdk changes

* adding tests and making sure everything works

* adding more tests

* removing the singleton for fallthrough

* Revert "removing the singleton for fallthrough"

This reverts commit dff7adbb809ecc63118d0fbff9742a88a039c679.

* taking a different approach to keep things immutable

* adding tests for untracked

* remove unnecessary comment

* making sure to return two values in all code paths

Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>

* Use camelCase for JSON property names (#151)

The in_experiment attribute was added to reasons as part of #150 but it doesn't appear to be received in events. I think that's because it's sending it in JSON as "in_experiment" rather than "inExperiment" as we expect to parse it.

* fixing ruby logic causing ih failures (#152)

* fixing ruby logic

* adding missing spec

* Apply suggestions from code review

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* pr tweaks

* making spec language consistent

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* add log warning for missing user key (#153)

* add log warnings for nil/empty user key

* rm warning for empty string key

* fix test

* diagnostic events should respect HTTPS_PROXY (#154)

* minor test simplification (#155)

* allow higher minor versions of json and http gems

* allow v5.x of http gem (#157)

* use Bundler 2.2.10 + modernize CI config (#158)

* enable verbose rspec output

* fix socket factory tests

* restore log suppression

* Replacing deprecated circleci image usage (#159)

* use Releaser v2 config (#161)

* Updates docs URLs

* Update lib/ldclient-rb/ldclient.rb

Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>

* remove reliance on git in gemspec (#163)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504 (#164)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504

* comment phrasing

* Start work on flag builder.

* Add user targeting and rule builder

* Add datasource implementation

* Convert the current_flags hash to use symbols instead of strings as keys

* Fix typo on FlagRuleBuilder copy constructor

* minor refactoring of impl; Added use of new Clause struct instead of Hash in FlagRuleBuilder; Moved TestData.factory out of Impl namespace and renamed Impl to TestDataImpl

* Add the doc comments

* (big segments 1) add public config/interface/reason types (#167)

* Cleanup docstrings to be YARD docs

* Added Util.is_bool helper function to clean up the check for whether an object is a boolean; Removed the DeepCopyHash/DeepCopyArray objects in favor of deep_copy_hash and deep_copy_array functions

* Move public classes out of Impl namespace. Most of it is in public namespace except for the data source now.

* Move require of concurrent/atomics to the correct module

* (big segments 2) implement Big Segments evaluation & status APIs (#168)

* improve CONTRIBUTING.md with notes on code organization

* add note about doc comments

* Cleanup YARD warnings and cleanup docs

* Address PR feedback: Move is_bool back to Impl namespace to avoid confusion; Remove unnecessary nil check on variations in build function; fixup comments

* (big segments 3) implement Redis & DynamoDB big segment stores (#169)

* add missing import

* fix stale calculation

* fix big segments user hash algorithm to use SHA256

* improve & refactor client/evaluation tests

* more cleanup/DRY

* add use_preconfigured_flag and use_preconfigured_segment to TestData (#173)

* always cache big segment query result even if it's nil

* comments

* add test for cache expiration

* use TestData in our own tests (#174)

* use TestData in our own tests

* fix test

* replace LaunchDarkly::FileDataSource with LaunchDarkly::Integrations::FileData

* update ruby-eventsource version for recent SSE fixes

* Bump bundler version (#184)

* Add ability to to set initial reconnect delay (#183)

* Treat secondary as a built-in attribute (#180)

* all_flags_state is invalid if store isn't initialized (#182)

* identify should not emit events if user key is "" (#181)

* Account for traffic allocation on all flags (#185)

* Add contract tests (#178)

* Fix string interpolation in log message (#187)

* Default opts to empty hash when creating persistent feature store (#186)

* Remove Hakiri badge from README (#188)

Hakiri was sunset on January 31st, 2022 at which time our badge stopped
working.

* detect http/https proxy env vars when creating HTTP clients

* rever accidental change

* fix nil safety in test service config

* master -> main (#190)

* master -> main

* update ruby-eventsource version for parsing efficiency fix

* miscellaneous optimizations for event processing (#193)

* Drop support for EOL ruby versions (#196)

Ruby 2.5 was EOL 2021-04-05

As of June 27th, 2022, the latest jRuby is Ruby 2.6 compatible.

* Remove alias support (#195)

* Add polling support for contract test service (#198)

* Update rubocop and enable in CI (#197)

Several of the Rubocop cop definitions have been renamed or moved to
entirely other gems. This brings the configuration up to date with the
latest naming conventions.

* Add windows tests in circleci (#199)

At some point in the past, we were experimenting with using Azure to
verify Window builds. Now that CircleCI supports Windows, we should keep
everything on a single CI provider.

* Add application info support (#194)

* reuse EvaluationDetail instances by precomputing results

* rubocop reformatting

* add super constructor calls

* disable rubocop Rails rules and fix some remaining syntax offenses

* fix super calls

* Add big segment support to contract tests (#201)

* Initial creation of LDContext (#206)

This introduces the initial structure and usage of the LDContext class.

Instances of this class are expected to be created through static
factory methods:

```ruby
LaunchDarkly::LDContext.create({...})
LaunchDarkly::LDContext.create_multi([...])
```

This class is not completed yet. Rather, this initial commit is focused
on the creation patterns and the most basic operations. Subsequent
commits will continue fleshing out this class and its operation.

The `get_value` method will see significant changes as we introduce
attribute reference support. Its current more simplistic implementation
exists only to serve some interim unit tests.

* Add reference based value retrieval (#207)

This commit introduces the References type used for targeting complex
attributes in the new LDContexts.

References are expected to be created through static factory methods:

```ruby
LaunchDarkly::Reference.create("/a/b")
LaunchDarkly::Reference.create_literal("/a/b")
```

These references can be used to retrieve values from an existing
LDContext

```ruby
ref = LaunchDarkly::Reference.create("/a/b")
result = context.get_value_for_reference(ref)
```

* Basic changes to use contexts in evaluations instead of users (#208)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

This replaces `LDUser` with `LDContext` in the parameters for
evaluations, and makes the minimum necessary adjustments to allow
evaluations to keep working as before as long as the context kind is
"user". None of the new behavior defined in the U2C spec is implemented
yet.

Generation of evaluation events is temporarily disabled because the
event logic hasn't been updated yet.

U2C contract tests for evaluations are partially enabled; a lot of
functionality is still missing, but all the tests that only cover
previously-existing evaluation behavior are passing.

[pr]: launchdarkly/php-server-sdk-private#103

* Support ContextKind in Clauses (#209)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

The main features of this commit are:

- introduction of `individual_context` and `individual_context_count`
  methods 
- context kind matching in clauses

[pr]: launchdarkly/php-server-sdk-private#108

* Support included / excluded contexts in segments (#210)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

Segments are now able to provide `includedContext` and `excludedContext`
properties which can target values within a specific context kind.

```json
{
    "includedContexts": [
        {
            "contextKind": "org",
            "values": ["orgkey1", "orgkey2"]
        }
    ]
}
```

[pr]: launchdarkly/php-server-sdk-private#111

* Add contextKind support for rollouts & experiements (#211)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

[pr]: launchdarkly/php-server-sdk-private#110

* Style and test matcher improvements (#212)

This commit enables several rubocop rules that were previously disabled.
Once enabled, `rubocop -A` was run to automatically apply these fixes.

There are a couple of additional changes that were made by hand:

- I added the rubocop and rubocop-performance gems as dev packages. This
  should help address the original installation issue we ran into when I
  introduced these tools.

- By default, new rubocop rules are disabled. This was the default
  before, but if you don't explicitly set this value, each run generates
  a ton of warning noise. This quiets that down.

- Updates some LDContext tests to be more strict in their expectations
  of truth.

* Remove support for secondary attribute (#213)

As decided in the [spec], we are removing the special behavior of the
secondary attribute. Going forward, secondary will be treated like any
other attribute, and will no longer be included when determining the
bucket for a context.

[spec]:
https://launchdarkly.atlassian.net/wiki/spaces/ENG/pages/2165212563/Consistent+and+Transparent+Rollout+Behavior+Unifying+Percent+Rollout+and+Traffic+Allocation

* Remove deprecated APIs (#214)

Since the users to context change requires a version break, this is the
perfect time to remove previously deprecated bits of functionality. This
includes:

- Removing `update_processor*` config entries
- `FileDataSource` entry point
- `RedisFeatureStore` entry point
- `Redis::sadd?` warning in unit tests

* store data model with classes that aren't Hash

* lint

* remove [] override methods in places where we don't need them

* comments

* migrate some more of the model to be non-hash classes

* lint

* Anonymous cannot be nil in new context format (#216)

The legacy user format allowed anonymous to be missing or explicitly
provided but set to nil.

The new context format requires anonymous to either not be set, or if it
is explicitly set, it must be a boolean value.

* Tweak error message language and style (#217)

Our previous error messages suffered from a couple drawbacks:

- The messages were complete sentences, limiting our ability to compose
  error messages
- The messages were overly broad in many cases
- The messages unnecessarily required string interpolation that rarely
  provided much value

These new messages are more succinct and are written as small clauses
which can be used in conjunction with other error messages more easily.

* copyedit

Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>

* Implement prerequisite cycle detection (#219)

* Support attribute reference lookups (#215)

This adds support for slash-delimited paths in clause attributes,
bucketBy, etc. It does not do anything related to private attribute
redaction because none of the U2C event logic is implemented yet.

* Implement segment recursion and cycle detection (#220)

Clauses in segment rules are now allowed to reference segments. To
prevent an infinite recursion edge case, we implement a similar cycle
detection mechanism as used on prerequisites.

* Update event logic to support users to context change (#221)

* Add legacy user-type support to the contract tests (#222)

* Remove inline user configuration option (#223)

* Add context_ configuration options (#224)

These new context_ configuration options are meant to replace the
historic user_ options. If both are provided, the context_ variant will
take precedence.

* Add support for flag context targets (#225)

* Bump diplomat

* Bump redis

* Remove oga

* Bump connection_pool

* Favor set for faster target lookups (#228)

A few of our internal models maintain arrays of values. These arrays can
frequently be checked to see if they contain specific values.

Since set lookups are much faster than array lookups, this commit
changes the internal structure to a set for the values stored in Target
and SegmentTarget.

* Add secure mode hash to contract tests (#229)

* Update big segment support for users to context (#226)

To support the users to context change for big segments, this commit
makes the following changes:

- Introduces a new `Segment.unboundedContextKind` attribute. This will
default to `LDContext::KIND_DEFAULT` and is only referenced when
`Segment.unbounded` is true.

- With the creation of multi-kind contexts, a single evaluation may
result in multiple queries to the big segment store. This is reflected
in the changes to the `EvalResult` processing.

* Drop support for ruby 2.6 (#227)

Ruby 2.6 went EOL in March 2022. We originally didn't drop support for
it as doing so would require dropping support for jRuby as well.
However, jRuby recently released 9.4 which is Ruby 2.7+ compatible.

* Update remaining references from user to contexts (#231)

There are multiple places throughout the code where we are still
referencing users. I have tried to update all the places where a rename
seems reasonable or appropriate. There is still some work to do in the
test flag builders, but that will be done in a subsequent commit.

* Remove new relic integration (#233)

The new relic integration was removed many versions ago but a small
trace remained behind.

* Rename config option private_attribute_names (#234)

Co-authored-by: Eli Bishop <eli@launchdarkly.com>

* Update test data integration to support contexts (#232)

* improve data model validation logging; allow missing/empty attribute for segmentMatch (#236)

* Fix JSON serialization failure (#237)

When we introduced models for the flag and segment data, we added
to_json methods which proxy to the underlying to_json method provided by
the `json` gem.

We defined the method with a variadic parameter, but we failed to unpack
it when passing it on to the underlying implementation. This resulted in
a serialization failure which prevented the redis data store from
initializing.

---------

Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: Jacob Smith <jacob@jacobsmith.io>
Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: hroederld <hroeder@launchdarkly.com>
Co-authored-by: Kerrie Martinez <kyee@launchdarkly.com>
Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>
Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>
Co-authored-by: Matthew M. Keeler <keelerm84@gmail.com>
Co-authored-by: Ben Levy <benjaminlevy007@gmail.com>
Co-authored-by: Ben Levy <ben@foxhound.systems>
Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>
Co-authored-by: Louis Chan <lchan@launchdarkly.com>
LaunchDarklyReleaseBot added a commit that referenced this issue Mar 17, 2023
* don't let user fall outside of last bucket in rollout

* refactor evaluation logic and move it out of the main namespace

* comments

* fix type coercion behavior

* make type coercion behavior consistent with earlier versions for now

* whitespace

* break up Evaluator tests further

* make EvaluationReason an immutable class

* FrozenError doesn't exist in older Ruby, use more general RuntimeError

* precompute evaluation reasons when we receive a flag

* rm unused

* rename FeatureStore to DataStore

* remove references to UpdateProcessor (now DataSource)

* add event payload ID header

* (6.0) drop support for old Ruby versions

* add Ruby version constraint to gemspec

* remove Rake dependency

* update ld-eventsource to 1.0.2 which doesn't have Rake dependency

* implement diagnostic events in Ruby (#130)

* update ruby-eventsource to 1.0.3 for backoff bug

* fix incorrect initialization of EventProcessor

* remove install-time openssl check that breaks if you don't have rake

* treat comparison with wrong data type as a non-match, not an exception (#134)

* fail fast for nil SDK key when appropriate

* tolerate nil value for user.custom (#137)

* Only shutdown the Redis pool if it is owned by the SDK (#158)

* Only shutdown a Redis pool created by SDK

* Make pool shutdown behavior an option

* improve doc comment

* remove support for indirect/patch and indirect/put (#138)

* update to json 2.3.1 (#139)

* update json dep to 2.3.x to fix CVE

* add publication of API docs on GitHub Pages (#143)

* try fixing release metadata

* update the default base url (#144)

* revert renames of feature_store & update_processor

* [ch92483] Use http gem and add socket factory support (#142)

* update dependencies and add CI for ruby 3 (#141)

* reference eventsource 2.0 in gemspec

* add 5.x releasable branch for releaser

* use Ruby 2.6.6 in releases

* Removed the guides link

* [ch99757] add alias method (#147)

* don't send event for nil user evaluation

* remove lockfile (#148)

* rm redundant nil check

* Experiment Allocation Changes (#150)

* WIP - from sam's pairing session

* starting sdk changes

* adding tests and making sure everything works

* adding more tests

* removing the singleton for fallthrough

* Revert "removing the singleton for fallthrough"

This reverts commit dff7adbb809ecc63118d0fbff9742a88a039c679.

* taking a different approach to keep things immutable

* adding tests for untracked

* remove unnecessary comment

* making sure to return two values in all code paths

Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>

* Use camelCase for JSON property names (#151)

The in_experiment attribute was added to reasons as part of #150 but it doesn't appear to be received in events. I think that's because it's sending it in JSON as "in_experiment" rather than "inExperiment" as we expect to parse it.

* fixing ruby logic causing ih failures (#152)

* fixing ruby logic

* adding missing spec

* Apply suggestions from code review

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* pr tweaks

* making spec language consistent

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* add log warning for missing user key (#153)

* add log warnings for nil/empty user key

* rm warning for empty string key

* fix test

* diagnostic events should respect HTTPS_PROXY (#154)

* minor test simplification (#155)

* allow higher minor versions of json and http gems

* allow v5.x of http gem (#157)

* use Bundler 2.2.10 + modernize CI config (#158)

* enable verbose rspec output

* fix socket factory tests

* restore log suppression

* Replacing deprecated circleci image usage (#159)

* use Releaser v2 config (#161)

* Updates docs URLs

* Update lib/ldclient-rb/ldclient.rb

Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>

* remove reliance on git in gemspec (#163)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504 (#164)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504

* comment phrasing

* Start work on flag builder.

* Add user targeting and rule builder

* Add datasource implementation

* Convert the current_flags hash to use symbols instead of strings as keys

* Fix typo on FlagRuleBuilder copy constructor

* minor refactoring of impl; Added use of new Clause struct instead of Hash in FlagRuleBuilder; Moved TestData.factory out of Impl namespace and renamed Impl to TestDataImpl

* Add the doc comments

* (big segments 1) add public config/interface/reason types (#167)

* Cleanup docstrings to be YARD docs

* Added Util.is_bool helper function to clean up the check for whether an object is a boolean; Removed the DeepCopyHash/DeepCopyArray objects in favor of deep_copy_hash and deep_copy_array functions

* Move public classes out of Impl namespace. Most of it is in public namespace except for the data source now.

* Move require of concurrent/atomics to the correct module

* (big segments 2) implement Big Segments evaluation & status APIs (#168)

* improve CONTRIBUTING.md with notes on code organization

* add note about doc comments

* Cleanup YARD warnings and cleanup docs

* Address PR feedback: Move is_bool back to Impl namespace to avoid confusion; Remove unnecessary nil check on variations in build function; fixup comments

* (big segments 3) implement Redis & DynamoDB big segment stores (#169)

* add missing import

* fix stale calculation

* fix big segments user hash algorithm to use SHA256

* improve & refactor client/evaluation tests

* more cleanup/DRY

* add use_preconfigured_flag and use_preconfigured_segment to TestData (#173)

* always cache big segment query result even if it's nil

* comments

* add test for cache expiration

* use TestData in our own tests (#174)

* use TestData in our own tests

* fix test

* replace LaunchDarkly::FileDataSource with LaunchDarkly::Integrations::FileData

* update ruby-eventsource version for recent SSE fixes

* Bump bundler version (#184)

* Add ability to to set initial reconnect delay (#183)

* Treat secondary as a built-in attribute (#180)

* all_flags_state is invalid if store isn't initialized (#182)

* identify should not emit events if user key is "" (#181)

* Account for traffic allocation on all flags (#185)

* Add contract tests (#178)

* Fix string interpolation in log message (#187)

* Default opts to empty hash when creating persistent feature store (#186)

* Remove Hakiri badge from README (#188)

Hakiri was sunset on January 31st, 2022 at which time our badge stopped
working.

* detect http/https proxy env vars when creating HTTP clients

* rever accidental change

* fix nil safety in test service config

* master -> main (#190)

* master -> main

* update ruby-eventsource version for parsing efficiency fix

* miscellaneous optimizations for event processing (#193)

* Drop support for EOL ruby versions (#196)

Ruby 2.5 was EOL 2021-04-05

As of June 27th, 2022, the latest jRuby is Ruby 2.6 compatible.

* Remove alias support (#195)

* Add polling support for contract test service (#198)

* Update rubocop and enable in CI (#197)

Several of the Rubocop cop definitions have been renamed or moved to
entirely other gems. This brings the configuration up to date with the
latest naming conventions.

* Add windows tests in circleci (#199)

At some point in the past, we were experimenting with using Azure to
verify Window builds. Now that CircleCI supports Windows, we should keep
everything on a single CI provider.

* Add application info support (#194)

* reuse EvaluationDetail instances by precomputing results

* rubocop reformatting

* add super constructor calls

* disable rubocop Rails rules and fix some remaining syntax offenses

* fix super calls

* Add big segment support to contract tests (#201)

* Initial creation of LDContext (#206)

This introduces the initial structure and usage of the LDContext class.

Instances of this class are expected to be created through static
factory methods:

```ruby
LaunchDarkly::LDContext.create({...})
LaunchDarkly::LDContext.create_multi([...])
```

This class is not completed yet. Rather, this initial commit is focused
on the creation patterns and the most basic operations. Subsequent
commits will continue fleshing out this class and its operation.

The `get_value` method will see significant changes as we introduce
attribute reference support. Its current more simplistic implementation
exists only to serve some interim unit tests.

* Add reference based value retrieval (#207)

This commit introduces the References type used for targeting complex
attributes in the new LDContexts.

References are expected to be created through static factory methods:

```ruby
LaunchDarkly::Reference.create("/a/b")
LaunchDarkly::Reference.create_literal("/a/b")
```

These references can be used to retrieve values from an existing
LDContext

```ruby
ref = LaunchDarkly::Reference.create("/a/b")
result = context.get_value_for_reference(ref)
```

* Basic changes to use contexts in evaluations instead of users (#208)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

This replaces `LDUser` with `LDContext` in the parameters for
evaluations, and makes the minimum necessary adjustments to allow
evaluations to keep working as before as long as the context kind is
"user". None of the new behavior defined in the U2C spec is implemented
yet.

Generation of evaluation events is temporarily disabled because the
event logic hasn't been updated yet.

U2C contract tests for evaluations are partially enabled; a lot of
functionality is still missing, but all the tests that only cover
previously-existing evaluation behavior are passing.

[pr]: launchdarkly/php-server-sdk-private#103

* Support ContextKind in Clauses (#209)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

The main features of this commit are:

- introduction of `individual_context` and `individual_context_count`
  methods 
- context kind matching in clauses

[pr]: launchdarkly/php-server-sdk-private#108

* Support included / excluded contexts in segments (#210)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

Segments are now able to provide `includedContext` and `excludedContext`
properties which can target values within a specific context kind.

```json
{
    "includedContexts": [
        {
            "contextKind": "org",
            "values": ["orgkey1", "orgkey2"]
        }
    ]
}
```

[pr]: launchdarkly/php-server-sdk-private#111

* Add contextKind support for rollouts & experiements (#211)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

[pr]: launchdarkly/php-server-sdk-private#110

* Style and test matcher improvements (#212)

This commit enables several rubocop rules that were previously disabled.
Once enabled, `rubocop -A` was run to automatically apply these fixes.

There are a couple of additional changes that were made by hand:

- I added the rubocop and rubocop-performance gems as dev packages. This
  should help address the original installation issue we ran into when I
  introduced these tools.

- By default, new rubocop rules are disabled. This was the default
  before, but if you don't explicitly set this value, each run generates
  a ton of warning noise. This quiets that down.

- Updates some LDContext tests to be more strict in their expectations
  of truth.

* Remove support for secondary attribute (#213)

As decided in the [spec], we are removing the special behavior of the
secondary attribute. Going forward, secondary will be treated like any
other attribute, and will no longer be included when determining the
bucket for a context.

[spec]:
https://launchdarkly.atlassian.net/wiki/spaces/ENG/pages/2165212563/Consistent+and+Transparent+Rollout+Behavior+Unifying+Percent+Rollout+and+Traffic+Allocation

* Remove deprecated APIs (#214)

Since the users to context change requires a version break, this is the
perfect time to remove previously deprecated bits of functionality. This
includes:

- Removing `update_processor*` config entries
- `FileDataSource` entry point
- `RedisFeatureStore` entry point
- `Redis::sadd?` warning in unit tests

* store data model with classes that aren't Hash

* lint

* remove [] override methods in places where we don't need them

* comments

* migrate some more of the model to be non-hash classes

* lint

* Anonymous cannot be nil in new context format (#216)

The legacy user format allowed anonymous to be missing or explicitly
provided but set to nil.

The new context format requires anonymous to either not be set, or if it
is explicitly set, it must be a boolean value.

* Tweak error message language and style (#217)

Our previous error messages suffered from a couple drawbacks:

- The messages were complete sentences, limiting our ability to compose
  error messages
- The messages were overly broad in many cases
- The messages unnecessarily required string interpolation that rarely
  provided much value

These new messages are more succinct and are written as small clauses
which can be used in conjunction with other error messages more easily.

* copyedit

Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>

* Implement prerequisite cycle detection (#219)

* Support attribute reference lookups (#215)

This adds support for slash-delimited paths in clause attributes,
bucketBy, etc. It does not do anything related to private attribute
redaction because none of the U2C event logic is implemented yet.

* Implement segment recursion and cycle detection (#220)

Clauses in segment rules are now allowed to reference segments. To
prevent an infinite recursion edge case, we implement a similar cycle
detection mechanism as used on prerequisites.

* Update event logic to support users to context change (#221)

* Add legacy user-type support to the contract tests (#222)

* Remove inline user configuration option (#223)

* Add context_ configuration options (#224)

These new context_ configuration options are meant to replace the
historic user_ options. If both are provided, the context_ variant will
take precedence.

* Add support for flag context targets (#225)

* Bump diplomat

* Bump redis

* Remove oga

* Bump connection_pool

* Favor set for faster target lookups (#228)

A few of our internal models maintain arrays of values. These arrays can
frequently be checked to see if they contain specific values.

Since set lookups are much faster than array lookups, this commit
changes the internal structure to a set for the values stored in Target
and SegmentTarget.

* Add secure mode hash to contract tests (#229)

* Update big segment support for users to context (#226)

To support the users to context change for big segments, this commit
makes the following changes:

- Introduces a new `Segment.unboundedContextKind` attribute. This will
default to `LDContext::KIND_DEFAULT` and is only referenced when
`Segment.unbounded` is true.

- With the creation of multi-kind contexts, a single evaluation may
result in multiple queries to the big segment store. This is reflected
in the changes to the `EvalResult` processing.

* Drop support for ruby 2.6 (#227)

Ruby 2.6 went EOL in March 2022. We originally didn't drop support for
it as doing so would require dropping support for jRuby as well.
However, jRuby recently released 9.4 which is Ruby 2.7+ compatible.

* Update remaining references from user to contexts (#231)

There are multiple places throughout the code where we are still
referencing users. I have tried to update all the places where a rename
seems reasonable or appropriate. There is still some work to do in the
test flag builders, but that will be done in a subsequent commit.

* Remove new relic integration (#233)

The new relic integration was removed many versions ago but a small
trace remained behind.

* Rename config option private_attribute_names (#234)

Co-authored-by: Eli Bishop <eli@launchdarkly.com>

* Update test data integration to support contexts (#232)

* improve data model validation logging; allow missing/empty attribute for segmentMatch (#236)

* Fix JSON serialization failure (#237)

When we introduced models for the flag and segment data, we added
to_json methods which proxy to the underlying to_json method provided by
the `json` gem.

We defined the method with a variadic parameter, but we failed to unpack
it when passing it on to the underlying implementation. This resulted in
a serialization failure which prevented the redis data store from
initializing.

* fix: Bump eventsource to resolve header parsing (#239)

The underlying event source library had an issue where, in certain
environments, content-type header detection was failing.

This was resolved in v2.2.2 of the event source gem.

---------

Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: Jacob Smith <jacob@jacobsmith.io>
Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: hroederld <hroeder@launchdarkly.com>
Co-authored-by: Kerrie Martinez <kyee@launchdarkly.com>
Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>
Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>
Co-authored-by: Matthew M. Keeler <keelerm84@gmail.com>
Co-authored-by: Ben Levy <benjaminlevy007@gmail.com>
Co-authored-by: Ben Levy <ben@foxhound.systems>
Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>
Co-authored-by: Louis Chan <lchan@launchdarkly.com>
LaunchDarklyReleaseBot added a commit that referenced this issue Apr 3, 2023
* make type coercion behavior consistent with earlier versions for now

* whitespace

* break up Evaluator tests further

* make EvaluationReason an immutable class

* FrozenError doesn't exist in older Ruby, use more general RuntimeError

* precompute evaluation reasons when we receive a flag

* rm unused

* rename FeatureStore to DataStore

* remove references to UpdateProcessor (now DataSource)

* add event payload ID header

* (6.0) drop support for old Ruby versions

* add Ruby version constraint to gemspec

* remove Rake dependency

* update ld-eventsource to 1.0.2 which doesn't have Rake dependency

* implement diagnostic events in Ruby (#130)

* update ruby-eventsource to 1.0.3 for backoff bug

* fix incorrect initialization of EventProcessor

* remove install-time openssl check that breaks if you don't have rake

* treat comparison with wrong data type as a non-match, not an exception (#134)

* fail fast for nil SDK key when appropriate

* tolerate nil value for user.custom (#137)

* Only shutdown the Redis pool if it is owned by the SDK (#158)

* Only shutdown a Redis pool created by SDK

* Make pool shutdown behavior an option

* improve doc comment

* remove support for indirect/patch and indirect/put (#138)

* update to json 2.3.1 (#139)

* update json dep to 2.3.x to fix CVE

* add publication of API docs on GitHub Pages (#143)

* try fixing release metadata

* update the default base url (#144)

* revert renames of feature_store & update_processor

* [ch92483] Use http gem and add socket factory support (#142)

* update dependencies and add CI for ruby 3 (#141)

* reference eventsource 2.0 in gemspec

* add 5.x releasable branch for releaser

* use Ruby 2.6.6 in releases

* Removed the guides link

* [ch99757] add alias method (#147)

* don't send event for nil user evaluation

* remove lockfile (#148)

* rm redundant nil check

* Experiment Allocation Changes (#150)

* WIP - from sam's pairing session

* starting sdk changes

* adding tests and making sure everything works

* adding more tests

* removing the singleton for fallthrough

* Revert "removing the singleton for fallthrough"

This reverts commit dff7adbb809ecc63118d0fbff9742a88a039c679.

* taking a different approach to keep things immutable

* adding tests for untracked

* remove unnecessary comment

* making sure to return two values in all code paths

Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>

* Use camelCase for JSON property names (#151)

The in_experiment attribute was added to reasons as part of #150 but it doesn't appear to be received in events. I think that's because it's sending it in JSON as "in_experiment" rather than "inExperiment" as we expect to parse it.

* fixing ruby logic causing ih failures (#152)

* fixing ruby logic

* adding missing spec

* Apply suggestions from code review

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* pr tweaks

* making spec language consistent

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* add log warning for missing user key (#153)

* add log warnings for nil/empty user key

* rm warning for empty string key

* fix test

* diagnostic events should respect HTTPS_PROXY (#154)

* minor test simplification (#155)

* allow higher minor versions of json and http gems

* allow v5.x of http gem (#157)

* use Bundler 2.2.10 + modernize CI config (#158)

* enable verbose rspec output

* fix socket factory tests

* restore log suppression

* Replacing deprecated circleci image usage (#159)

* use Releaser v2 config (#161)

* Updates docs URLs

* Update lib/ldclient-rb/ldclient.rb

Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>

* remove reliance on git in gemspec (#163)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504 (#164)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504

* comment phrasing

* Start work on flag builder.

* Add user targeting and rule builder

* Add datasource implementation

* Convert the current_flags hash to use symbols instead of strings as keys

* Fix typo on FlagRuleBuilder copy constructor

* minor refactoring of impl; Added use of new Clause struct instead of Hash in FlagRuleBuilder; Moved TestData.factory out of Impl namespace and renamed Impl to TestDataImpl

* Add the doc comments

* (big segments 1) add public config/interface/reason types (#167)

* Cleanup docstrings to be YARD docs

* Added Util.is_bool helper function to clean up the check for whether an object is a boolean; Removed the DeepCopyHash/DeepCopyArray objects in favor of deep_copy_hash and deep_copy_array functions

* Move public classes out of Impl namespace. Most of it is in public namespace except for the data source now.

* Move require of concurrent/atomics to the correct module

* (big segments 2) implement Big Segments evaluation & status APIs (#168)

* improve CONTRIBUTING.md with notes on code organization

* add note about doc comments

* Cleanup YARD warnings and cleanup docs

* Address PR feedback: Move is_bool back to Impl namespace to avoid confusion; Remove unnecessary nil check on variations in build function; fixup comments

* (big segments 3) implement Redis & DynamoDB big segment stores (#169)

* add missing import

* fix stale calculation

* fix big segments user hash algorithm to use SHA256

* improve & refactor client/evaluation tests

* more cleanup/DRY

* add use_preconfigured_flag and use_preconfigured_segment to TestData (#173)

* always cache big segment query result even if it's nil

* comments

* add test for cache expiration

* use TestData in our own tests (#174)

* use TestData in our own tests

* fix test

* replace LaunchDarkly::FileDataSource with LaunchDarkly::Integrations::FileData

* update ruby-eventsource version for recent SSE fixes

* Bump bundler version (#184)

* Add ability to to set initial reconnect delay (#183)

* Treat secondary as a built-in attribute (#180)

* all_flags_state is invalid if store isn't initialized (#182)

* identify should not emit events if user key is "" (#181)

* Account for traffic allocation on all flags (#185)

* Add contract tests (#178)

* Fix string interpolation in log message (#187)

* Default opts to empty hash when creating persistent feature store (#186)

* Remove Hakiri badge from README (#188)

Hakiri was sunset on January 31st, 2022 at which time our badge stopped
working.

* detect http/https proxy env vars when creating HTTP clients

* rever accidental change

* fix nil safety in test service config

* master -> main (#190)

* master -> main

* update ruby-eventsource version for parsing efficiency fix

* miscellaneous optimizations for event processing (#193)

* Drop support for EOL ruby versions (#196)

Ruby 2.5 was EOL 2021-04-05

As of June 27th, 2022, the latest jRuby is Ruby 2.6 compatible.

* Remove alias support (#195)

* Add polling support for contract test service (#198)

* Update rubocop and enable in CI (#197)

Several of the Rubocop cop definitions have been renamed or moved to
entirely other gems. This brings the configuration up to date with the
latest naming conventions.

* Add windows tests in circleci (#199)

At some point in the past, we were experimenting with using Azure to
verify Window builds. Now that CircleCI supports Windows, we should keep
everything on a single CI provider.

* Add application info support (#194)

* reuse EvaluationDetail instances by precomputing results

* rubocop reformatting

* add super constructor calls

* disable rubocop Rails rules and fix some remaining syntax offenses

* fix super calls

* Add big segment support to contract tests (#201)

* Initial creation of LDContext (#206)

This introduces the initial structure and usage of the LDContext class.

Instances of this class are expected to be created through static
factory methods:

```ruby
LaunchDarkly::LDContext.create({...})
LaunchDarkly::LDContext.create_multi([...])
```

This class is not completed yet. Rather, this initial commit is focused
on the creation patterns and the most basic operations. Subsequent
commits will continue fleshing out this class and its operation.

The `get_value` method will see significant changes as we introduce
attribute reference support. Its current more simplistic implementation
exists only to serve some interim unit tests.

* Add reference based value retrieval (#207)

This commit introduces the References type used for targeting complex
attributes in the new LDContexts.

References are expected to be created through static factory methods:

```ruby
LaunchDarkly::Reference.create("/a/b")
LaunchDarkly::Reference.create_literal("/a/b")
```

These references can be used to retrieve values from an existing
LDContext

```ruby
ref = LaunchDarkly::Reference.create("/a/b")
result = context.get_value_for_reference(ref)
```

* Basic changes to use contexts in evaluations instead of users (#208)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

This replaces `LDUser` with `LDContext` in the parameters for
evaluations, and makes the minimum necessary adjustments to allow
evaluations to keep working as before as long as the context kind is
"user". None of the new behavior defined in the U2C spec is implemented
yet.

Generation of evaluation events is temporarily disabled because the
event logic hasn't been updated yet.

U2C contract tests for evaluations are partially enabled; a lot of
functionality is still missing, but all the tests that only cover
previously-existing evaluation behavior are passing.

[pr]: launchdarkly/php-server-sdk-private#103

* Support ContextKind in Clauses (#209)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

The main features of this commit are:

- introduction of `individual_context` and `individual_context_count`
  methods 
- context kind matching in clauses

[pr]: launchdarkly/php-server-sdk-private#108

* Support included / excluded contexts in segments (#210)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

Segments are now able to provide `includedContext` and `excludedContext`
properties which can target values within a specific context kind.

```json
{
    "includedContexts": [
        {
            "contextKind": "org",
            "values": ["orgkey1", "orgkey2"]
        }
    ]
}
```

[pr]: launchdarkly/php-server-sdk-private#111

* Add contextKind support for rollouts & experiements (#211)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

[pr]: launchdarkly/php-server-sdk-private#110

* Style and test matcher improvements (#212)

This commit enables several rubocop rules that were previously disabled.
Once enabled, `rubocop -A` was run to automatically apply these fixes.

There are a couple of additional changes that were made by hand:

- I added the rubocop and rubocop-performance gems as dev packages. This
  should help address the original installation issue we ran into when I
  introduced these tools.

- By default, new rubocop rules are disabled. This was the default
  before, but if you don't explicitly set this value, each run generates
  a ton of warning noise. This quiets that down.

- Updates some LDContext tests to be more strict in their expectations
  of truth.

* Remove support for secondary attribute (#213)

As decided in the [spec], we are removing the special behavior of the
secondary attribute. Going forward, secondary will be treated like any
other attribute, and will no longer be included when determining the
bucket for a context.

[spec]:
https://launchdarkly.atlassian.net/wiki/spaces/ENG/pages/2165212563/Consistent+and+Transparent+Rollout+Behavior+Unifying+Percent+Rollout+and+Traffic+Allocation

* Remove deprecated APIs (#214)

Since the users to context change requires a version break, this is the
perfect time to remove previously deprecated bits of functionality. This
includes:

- Removing `update_processor*` config entries
- `FileDataSource` entry point
- `RedisFeatureStore` entry point
- `Redis::sadd?` warning in unit tests

* store data model with classes that aren't Hash

* lint

* remove [] override methods in places where we don't need them

* comments

* migrate some more of the model to be non-hash classes

* lint

* Anonymous cannot be nil in new context format (#216)

The legacy user format allowed anonymous to be missing or explicitly
provided but set to nil.

The new context format requires anonymous to either not be set, or if it
is explicitly set, it must be a boolean value.

* Tweak error message language and style (#217)

Our previous error messages suffered from a couple drawbacks:

- The messages were complete sentences, limiting our ability to compose
  error messages
- The messages were overly broad in many cases
- The messages unnecessarily required string interpolation that rarely
  provided much value

These new messages are more succinct and are written as small clauses
which can be used in conjunction with other error messages more easily.

* copyedit

Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>

* Implement prerequisite cycle detection (#219)

* Support attribute reference lookups (#215)

This adds support for slash-delimited paths in clause attributes,
bucketBy, etc. It does not do anything related to private attribute
redaction because none of the U2C event logic is implemented yet.

* Implement segment recursion and cycle detection (#220)

Clauses in segment rules are now allowed to reference segments. To
prevent an infinite recursion edge case, we implement a similar cycle
detection mechanism as used on prerequisites.

* Update event logic to support users to context change (#221)

* Add legacy user-type support to the contract tests (#222)

* Remove inline user configuration option (#223)

* Add context_ configuration options (#224)

These new context_ configuration options are meant to replace the
historic user_ options. If both are provided, the context_ variant will
take precedence.

* Add support for flag context targets (#225)

* Bump diplomat

* Bump redis

* Remove oga

* Bump connection_pool

* Favor set for faster target lookups (#228)

A few of our internal models maintain arrays of values. These arrays can
frequently be checked to see if they contain specific values.

Since set lookups are much faster than array lookups, this commit
changes the internal structure to a set for the values stored in Target
and SegmentTarget.

* Add secure mode hash to contract tests (#229)

* Update big segment support for users to context (#226)

To support the users to context change for big segments, this commit
makes the following changes:

- Introduces a new `Segment.unboundedContextKind` attribute. This will
default to `LDContext::KIND_DEFAULT` and is only referenced when
`Segment.unbounded` is true.

- With the creation of multi-kind contexts, a single evaluation may
result in multiple queries to the big segment store. This is reflected
in the changes to the `EvalResult` processing.

* Drop support for ruby 2.6 (#227)

Ruby 2.6 went EOL in March 2022. We originally didn't drop support for
it as doing so would require dropping support for jRuby as well.
However, jRuby recently released 9.4 which is Ruby 2.7+ compatible.

* Update remaining references from user to contexts (#231)

There are multiple places throughout the code where we are still
referencing users. I have tried to update all the places where a rename
seems reasonable or appropriate. There is still some work to do in the
test flag builders, but that will be done in a subsequent commit.

* Remove new relic integration (#233)

The new relic integration was removed many versions ago but a small
trace remained behind.

* Rename config option private_attribute_names (#234)

Co-authored-by: Eli Bishop <eli@launchdarkly.com>

* Update test data integration to support contexts (#232)

* improve data model validation logging; allow missing/empty attribute for segmentMatch (#236)

* Fix JSON serialization failure (#237)

When we introduced models for the flag and segment data, we added
to_json methods which proxy to the underlying to_json method provided by
the `json` gem.

We defined the method with a variadic parameter, but we failed to unpack
it when passing it on to the underlying implementation. This resulted in
a serialization failure which prevented the redis data store from
initializing.

* fix: Bump eventsource to resolve header parsing (#239)

The underlying event source library had an issue where, in certain
environments, content-type header detection was failing.

This was resolved in v2.2.2 of the event source gem.

* Add key to error log for invalid context during variation call for easier debugging (#214)

---------

Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: Jacob Smith <jacob@jacobsmith.io>
Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: hroederld <hroeder@launchdarkly.com>
Co-authored-by: Kerrie Martinez <kyee@launchdarkly.com>
Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>
Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>
Co-authored-by: Matthew M. Keeler <keelerm84@gmail.com>
Co-authored-by: Ben Levy <benjaminlevy007@gmail.com>
Co-authored-by: Ben Levy <ben@foxhound.systems>
Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>
Co-authored-by: Louis Chan <lchan@launchdarkly.com>
Co-authored-by: Matt Hooks <46452201+matt-dutchie@users.noreply.github.com>
LaunchDarklyReleaseBot added a commit that referenced this issue Apr 13, 2023
* make EvaluationReason an immutable class

* FrozenError doesn't exist in older Ruby, use more general RuntimeError

* precompute evaluation reasons when we receive a flag

* rm unused

* rename FeatureStore to DataStore

* remove references to UpdateProcessor (now DataSource)

* add event payload ID header

* (6.0) drop support for old Ruby versions

* add Ruby version constraint to gemspec

* remove Rake dependency

* update ld-eventsource to 1.0.2 which doesn't have Rake dependency

* implement diagnostic events in Ruby (#130)

* update ruby-eventsource to 1.0.3 for backoff bug

* fix incorrect initialization of EventProcessor

* remove install-time openssl check that breaks if you don't have rake

* treat comparison with wrong data type as a non-match, not an exception (#134)

* fail fast for nil SDK key when appropriate

* tolerate nil value for user.custom (#137)

* Only shutdown the Redis pool if it is owned by the SDK (#158)

* Only shutdown a Redis pool created by SDK

* Make pool shutdown behavior an option

* improve doc comment

* remove support for indirect/patch and indirect/put (#138)

* update to json 2.3.1 (#139)

* update json dep to 2.3.x to fix CVE

* add publication of API docs on GitHub Pages (#143)

* try fixing release metadata

* update the default base url (#144)

* revert renames of feature_store & update_processor

* [ch92483] Use http gem and add socket factory support (#142)

* update dependencies and add CI for ruby 3 (#141)

* reference eventsource 2.0 in gemspec

* add 5.x releasable branch for releaser

* use Ruby 2.6.6 in releases

* Removed the guides link

* [ch99757] add alias method (#147)

* don't send event for nil user evaluation

* remove lockfile (#148)

* rm redundant nil check

* Experiment Allocation Changes (#150)

* WIP - from sam's pairing session

* starting sdk changes

* adding tests and making sure everything works

* adding more tests

* removing the singleton for fallthrough

* Revert "removing the singleton for fallthrough"

This reverts commit dff7adbb809ecc63118d0fbff9742a88a039c679.

* taking a different approach to keep things immutable

* adding tests for untracked

* remove unnecessary comment

* making sure to return two values in all code paths

Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>

* Use camelCase for JSON property names (#151)

The in_experiment attribute was added to reasons as part of #150 but it doesn't appear to be received in events. I think that's because it's sending it in JSON as "in_experiment" rather than "inExperiment" as we expect to parse it.

* fixing ruby logic causing ih failures (#152)

* fixing ruby logic

* adding missing spec

* Apply suggestions from code review

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* pr tweaks

* making spec language consistent

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* add log warning for missing user key (#153)

* add log warnings for nil/empty user key

* rm warning for empty string key

* fix test

* diagnostic events should respect HTTPS_PROXY (#154)

* minor test simplification (#155)

* allow higher minor versions of json and http gems

* allow v5.x of http gem (#157)

* use Bundler 2.2.10 + modernize CI config (#158)

* enable verbose rspec output

* fix socket factory tests

* restore log suppression

* Replacing deprecated circleci image usage (#159)

* use Releaser v2 config (#161)

* Updates docs URLs

* Update lib/ldclient-rb/ldclient.rb

Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>

* remove reliance on git in gemspec (#163)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504 (#164)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504

* comment phrasing

* Start work on flag builder.

* Add user targeting and rule builder

* Add datasource implementation

* Convert the current_flags hash to use symbols instead of strings as keys

* Fix typo on FlagRuleBuilder copy constructor

* minor refactoring of impl; Added use of new Clause struct instead of Hash in FlagRuleBuilder; Moved TestData.factory out of Impl namespace and renamed Impl to TestDataImpl

* Add the doc comments

* (big segments 1) add public config/interface/reason types (#167)

* Cleanup docstrings to be YARD docs

* Added Util.is_bool helper function to clean up the check for whether an object is a boolean; Removed the DeepCopyHash/DeepCopyArray objects in favor of deep_copy_hash and deep_copy_array functions

* Move public classes out of Impl namespace. Most of it is in public namespace except for the data source now.

* Move require of concurrent/atomics to the correct module

* (big segments 2) implement Big Segments evaluation & status APIs (#168)

* improve CONTRIBUTING.md with notes on code organization

* add note about doc comments

* Cleanup YARD warnings and cleanup docs

* Address PR feedback: Move is_bool back to Impl namespace to avoid confusion; Remove unnecessary nil check on variations in build function; fixup comments

* (big segments 3) implement Redis & DynamoDB big segment stores (#169)

* add missing import

* fix stale calculation

* fix big segments user hash algorithm to use SHA256

* improve & refactor client/evaluation tests

* more cleanup/DRY

* add use_preconfigured_flag and use_preconfigured_segment to TestData (#173)

* always cache big segment query result even if it's nil

* comments

* add test for cache expiration

* use TestData in our own tests (#174)

* use TestData in our own tests

* fix test

* replace LaunchDarkly::FileDataSource with LaunchDarkly::Integrations::FileData

* update ruby-eventsource version for recent SSE fixes

* Bump bundler version (#184)

* Add ability to to set initial reconnect delay (#183)

* Treat secondary as a built-in attribute (#180)

* all_flags_state is invalid if store isn't initialized (#182)

* identify should not emit events if user key is "" (#181)

* Account for traffic allocation on all flags (#185)

* Add contract tests (#178)

* Fix string interpolation in log message (#187)

* Default opts to empty hash when creating persistent feature store (#186)

* Remove Hakiri badge from README (#188)

Hakiri was sunset on January 31st, 2022 at which time our badge stopped
working.

* detect http/https proxy env vars when creating HTTP clients

* rever accidental change

* fix nil safety in test service config

* master -> main (#190)

* master -> main

* update ruby-eventsource version for parsing efficiency fix

* miscellaneous optimizations for event processing (#193)

* Drop support for EOL ruby versions (#196)

Ruby 2.5 was EOL 2021-04-05

As of June 27th, 2022, the latest jRuby is Ruby 2.6 compatible.

* Remove alias support (#195)

* Add polling support for contract test service (#198)

* Update rubocop and enable in CI (#197)

Several of the Rubocop cop definitions have been renamed or moved to
entirely other gems. This brings the configuration up to date with the
latest naming conventions.

* Add windows tests in circleci (#199)

At some point in the past, we were experimenting with using Azure to
verify Window builds. Now that CircleCI supports Windows, we should keep
everything on a single CI provider.

* Add application info support (#194)

* reuse EvaluationDetail instances by precomputing results

* rubocop reformatting

* add super constructor calls

* disable rubocop Rails rules and fix some remaining syntax offenses

* fix super calls

* Add big segment support to contract tests (#201)

* Initial creation of LDContext (#206)

This introduces the initial structure and usage of the LDContext class.

Instances of this class are expected to be created through static
factory methods:

```ruby
LaunchDarkly::LDContext.create({...})
LaunchDarkly::LDContext.create_multi([...])
```

This class is not completed yet. Rather, this initial commit is focused
on the creation patterns and the most basic operations. Subsequent
commits will continue fleshing out this class and its operation.

The `get_value` method will see significant changes as we introduce
attribute reference support. Its current more simplistic implementation
exists only to serve some interim unit tests.

* Add reference based value retrieval (#207)

This commit introduces the References type used for targeting complex
attributes in the new LDContexts.

References are expected to be created through static factory methods:

```ruby
LaunchDarkly::Reference.create("/a/b")
LaunchDarkly::Reference.create_literal("/a/b")
```

These references can be used to retrieve values from an existing
LDContext

```ruby
ref = LaunchDarkly::Reference.create("/a/b")
result = context.get_value_for_reference(ref)
```

* Basic changes to use contexts in evaluations instead of users (#208)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

This replaces `LDUser` with `LDContext` in the parameters for
evaluations, and makes the minimum necessary adjustments to allow
evaluations to keep working as before as long as the context kind is
"user". None of the new behavior defined in the U2C spec is implemented
yet.

Generation of evaluation events is temporarily disabled because the
event logic hasn't been updated yet.

U2C contract tests for evaluations are partially enabled; a lot of
functionality is still missing, but all the tests that only cover
previously-existing evaluation behavior are passing.

[pr]: launchdarkly/php-server-sdk-private#103

* Support ContextKind in Clauses (#209)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

The main features of this commit are:

- introduction of `individual_context` and `individual_context_count`
  methods 
- context kind matching in clauses

[pr]: launchdarkly/php-server-sdk-private#108

* Support included / excluded contexts in segments (#210)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

Segments are now able to provide `includedContext` and `excludedContext`
properties which can target values within a specific context kind.

```json
{
    "includedContexts": [
        {
            "contextKind": "org",
            "values": ["orgkey1", "orgkey2"]
        }
    ]
}
```

[pr]: launchdarkly/php-server-sdk-private#111

* Add contextKind support for rollouts & experiements (#211)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

[pr]: launchdarkly/php-server-sdk-private#110

* Style and test matcher improvements (#212)

This commit enables several rubocop rules that were previously disabled.
Once enabled, `rubocop -A` was run to automatically apply these fixes.

There are a couple of additional changes that were made by hand:

- I added the rubocop and rubocop-performance gems as dev packages. This
  should help address the original installation issue we ran into when I
  introduced these tools.

- By default, new rubocop rules are disabled. This was the default
  before, but if you don't explicitly set this value, each run generates
  a ton of warning noise. This quiets that down.

- Updates some LDContext tests to be more strict in their expectations
  of truth.

* Remove support for secondary attribute (#213)

As decided in the [spec], we are removing the special behavior of the
secondary attribute. Going forward, secondary will be treated like any
other attribute, and will no longer be included when determining the
bucket for a context.

[spec]:
https://launchdarkly.atlassian.net/wiki/spaces/ENG/pages/2165212563/Consistent+and+Transparent+Rollout+Behavior+Unifying+Percent+Rollout+and+Traffic+Allocation

* Remove deprecated APIs (#214)

Since the users to context change requires a version break, this is the
perfect time to remove previously deprecated bits of functionality. This
includes:

- Removing `update_processor*` config entries
- `FileDataSource` entry point
- `RedisFeatureStore` entry point
- `Redis::sadd?` warning in unit tests

* store data model with classes that aren't Hash

* lint

* remove [] override methods in places where we don't need them

* comments

* migrate some more of the model to be non-hash classes

* lint

* Anonymous cannot be nil in new context format (#216)

The legacy user format allowed anonymous to be missing or explicitly
provided but set to nil.

The new context format requires anonymous to either not be set, or if it
is explicitly set, it must be a boolean value.

* Tweak error message language and style (#217)

Our previous error messages suffered from a couple drawbacks:

- The messages were complete sentences, limiting our ability to compose
  error messages
- The messages were overly broad in many cases
- The messages unnecessarily required string interpolation that rarely
  provided much value

These new messages are more succinct and are written as small clauses
which can be used in conjunction with other error messages more easily.

* copyedit

Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>

* Implement prerequisite cycle detection (#219)

* Support attribute reference lookups (#215)

This adds support for slash-delimited paths in clause attributes,
bucketBy, etc. It does not do anything related to private attribute
redaction because none of the U2C event logic is implemented yet.

* Implement segment recursion and cycle detection (#220)

Clauses in segment rules are now allowed to reference segments. To
prevent an infinite recursion edge case, we implement a similar cycle
detection mechanism as used on prerequisites.

* Update event logic to support users to context change (#221)

* Add legacy user-type support to the contract tests (#222)

* Remove inline user configuration option (#223)

* Add context_ configuration options (#224)

These new context_ configuration options are meant to replace the
historic user_ options. If both are provided, the context_ variant will
take precedence.

* Add support for flag context targets (#225)

* Bump diplomat

* Bump redis

* Remove oga

* Bump connection_pool

* Favor set for faster target lookups (#228)

A few of our internal models maintain arrays of values. These arrays can
frequently be checked to see if they contain specific values.

Since set lookups are much faster than array lookups, this commit
changes the internal structure to a set for the values stored in Target
and SegmentTarget.

* Add secure mode hash to contract tests (#229)

* Update big segment support for users to context (#226)

To support the users to context change for big segments, this commit
makes the following changes:

- Introduces a new `Segment.unboundedContextKind` attribute. This will
default to `LDContext::KIND_DEFAULT` and is only referenced when
`Segment.unbounded` is true.

- With the creation of multi-kind contexts, a single evaluation may
result in multiple queries to the big segment store. This is reflected
in the changes to the `EvalResult` processing.

* Drop support for ruby 2.6 (#227)

Ruby 2.6 went EOL in March 2022. We originally didn't drop support for
it as doing so would require dropping support for jRuby as well.
However, jRuby recently released 9.4 which is Ruby 2.7+ compatible.

* Update remaining references from user to contexts (#231)

There are multiple places throughout the code where we are still
referencing users. I have tried to update all the places where a rename
seems reasonable or appropriate. There is still some work to do in the
test flag builders, but that will be done in a subsequent commit.

* Remove new relic integration (#233)

The new relic integration was removed many versions ago but a small
trace remained behind.

* Rename config option private_attribute_names (#234)

Co-authored-by: Eli Bishop <eli@launchdarkly.com>

* Update test data integration to support contexts (#232)

* improve data model validation logging; allow missing/empty attribute for segmentMatch (#236)

* Fix JSON serialization failure (#237)

When we introduced models for the flag and segment data, we added
to_json methods which proxy to the underlying to_json method provided by
the `json` gem.

We defined the method with a variadic parameter, but we failed to unpack
it when passing it on to the underlying implementation. This resulted in
a serialization failure which prevented the redis data store from
initializing.

* fix: Bump eventsource to resolve header parsing (#239)

The underlying event source library had an issue where, in certain
environments, content-type header detection was failing.

This was resolved in v2.2.2 of the event source gem.

* Add key to error log for invalid context during variation call for easier debugging (#214)

* feat: Add support for payload filtering (#238)

---------

Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: Jacob Smith <jacob@jacobsmith.io>
Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: hroederld <hroeder@launchdarkly.com>
Co-authored-by: Kerrie Martinez <kyee@launchdarkly.com>
Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>
Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>
Co-authored-by: Matthew M. Keeler <keelerm84@gmail.com>
Co-authored-by: Ben Levy <benjaminlevy007@gmail.com>
Co-authored-by: Ben Levy <ben@foxhound.systems>
Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>
Co-authored-by: Louis Chan <lchan@launchdarkly.com>
Co-authored-by: Matt Hooks <46452201+matt-dutchie@users.noreply.github.com>
LaunchDarklyReleaseBot added a commit that referenced this issue May 4, 2023
* add event payload ID header

* (6.0) drop support for old Ruby versions

* add Ruby version constraint to gemspec

* remove Rake dependency

* update ld-eventsource to 1.0.2 which doesn't have Rake dependency

* implement diagnostic events in Ruby (#130)

* update ruby-eventsource to 1.0.3 for backoff bug

* fix incorrect initialization of EventProcessor

* remove install-time openssl check that breaks if you don't have rake

* treat comparison with wrong data type as a non-match, not an exception (#134)

* fail fast for nil SDK key when appropriate

* tolerate nil value for user.custom (#137)

* Only shutdown the Redis pool if it is owned by the SDK (#158)

* Only shutdown a Redis pool created by SDK

* Make pool shutdown behavior an option

* improve doc comment

* remove support for indirect/patch and indirect/put (#138)

* update to json 2.3.1 (#139)

* update json dep to 2.3.x to fix CVE

* add publication of API docs on GitHub Pages (#143)

* try fixing release metadata

* update the default base url (#144)

* revert renames of feature_store & update_processor

* [ch92483] Use http gem and add socket factory support (#142)

* update dependencies and add CI for ruby 3 (#141)

* reference eventsource 2.0 in gemspec

* add 5.x releasable branch for releaser

* use Ruby 2.6.6 in releases

* Removed the guides link

* [ch99757] add alias method (#147)

* don't send event for nil user evaluation

* remove lockfile (#148)

* rm redundant nil check

* Experiment Allocation Changes (#150)

* WIP - from sam's pairing session

* starting sdk changes

* adding tests and making sure everything works

* adding more tests

* removing the singleton for fallthrough

* Revert "removing the singleton for fallthrough"

This reverts commit dff7adbb809ecc63118d0fbff9742a88a039c679.

* taking a different approach to keep things immutable

* adding tests for untracked

* remove unnecessary comment

* making sure to return two values in all code paths

Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>

* Use camelCase for JSON property names (#151)

The in_experiment attribute was added to reasons as part of #150 but it doesn't appear to be received in events. I think that's because it's sending it in JSON as "in_experiment" rather than "inExperiment" as we expect to parse it.

* fixing ruby logic causing ih failures (#152)

* fixing ruby logic

* adding missing spec

* Apply suggestions from code review

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* pr tweaks

* making spec language consistent

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* add log warning for missing user key (#153)

* add log warnings for nil/empty user key

* rm warning for empty string key

* fix test

* diagnostic events should respect HTTPS_PROXY (#154)

* minor test simplification (#155)

* allow higher minor versions of json and http gems

* allow v5.x of http gem (#157)

* use Bundler 2.2.10 + modernize CI config (#158)

* enable verbose rspec output

* fix socket factory tests

* restore log suppression

* Replacing deprecated circleci image usage (#159)

* use Releaser v2 config (#161)

* Updates docs URLs

* Update lib/ldclient-rb/ldclient.rb

Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>

* remove reliance on git in gemspec (#163)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504 (#164)

* use ruby-eventsource 2.1.1 for fix of sc-123850 and sc-125504

* comment phrasing

* Start work on flag builder.

* Add user targeting and rule builder

* Add datasource implementation

* Convert the current_flags hash to use symbols instead of strings as keys

* Fix typo on FlagRuleBuilder copy constructor

* minor refactoring of impl; Added use of new Clause struct instead of Hash in FlagRuleBuilder; Moved TestData.factory out of Impl namespace and renamed Impl to TestDataImpl

* Add the doc comments

* (big segments 1) add public config/interface/reason types (#167)

* Cleanup docstrings to be YARD docs

* Added Util.is_bool helper function to clean up the check for whether an object is a boolean; Removed the DeepCopyHash/DeepCopyArray objects in favor of deep_copy_hash and deep_copy_array functions

* Move public classes out of Impl namespace. Most of it is in public namespace except for the data source now.

* Move require of concurrent/atomics to the correct module

* (big segments 2) implement Big Segments evaluation & status APIs (#168)

* improve CONTRIBUTING.md with notes on code organization

* add note about doc comments

* Cleanup YARD warnings and cleanup docs

* Address PR feedback: Move is_bool back to Impl namespace to avoid confusion; Remove unnecessary nil check on variations in build function; fixup comments

* (big segments 3) implement Redis & DynamoDB big segment stores (#169)

* add missing import

* fix stale calculation

* fix big segments user hash algorithm to use SHA256

* improve & refactor client/evaluation tests

* more cleanup/DRY

* add use_preconfigured_flag and use_preconfigured_segment to TestData (#173)

* always cache big segment query result even if it's nil

* comments

* add test for cache expiration

* use TestData in our own tests (#174)

* use TestData in our own tests

* fix test

* replace LaunchDarkly::FileDataSource with LaunchDarkly::Integrations::FileData

* update ruby-eventsource version for recent SSE fixes

* Bump bundler version (#184)

* Add ability to to set initial reconnect delay (#183)

* Treat secondary as a built-in attribute (#180)

* all_flags_state is invalid if store isn't initialized (#182)

* identify should not emit events if user key is "" (#181)

* Account for traffic allocation on all flags (#185)

* Add contract tests (#178)

* Fix string interpolation in log message (#187)

* Default opts to empty hash when creating persistent feature store (#186)

* Remove Hakiri badge from README (#188)

Hakiri was sunset on January 31st, 2022 at which time our badge stopped
working.

* detect http/https proxy env vars when creating HTTP clients

* rever accidental change

* fix nil safety in test service config

* master -> main (#190)

* master -> main

* update ruby-eventsource version for parsing efficiency fix

* miscellaneous optimizations for event processing (#193)

* Drop support for EOL ruby versions (#196)

Ruby 2.5 was EOL 2021-04-05

As of June 27th, 2022, the latest jRuby is Ruby 2.6 compatible.

* Remove alias support (#195)

* Add polling support for contract test service (#198)

* Update rubocop and enable in CI (#197)

Several of the Rubocop cop definitions have been renamed or moved to
entirely other gems. This brings the configuration up to date with the
latest naming conventions.

* Add windows tests in circleci (#199)

At some point in the past, we were experimenting with using Azure to
verify Window builds. Now that CircleCI supports Windows, we should keep
everything on a single CI provider.

* Add application info support (#194)

* reuse EvaluationDetail instances by precomputing results

* rubocop reformatting

* add super constructor calls

* disable rubocop Rails rules and fix some remaining syntax offenses

* fix super calls

* Add big segment support to contract tests (#201)

* Initial creation of LDContext (#206)

This introduces the initial structure and usage of the LDContext class.

Instances of this class are expected to be created through static
factory methods:

```ruby
LaunchDarkly::LDContext.create({...})
LaunchDarkly::LDContext.create_multi([...])
```

This class is not completed yet. Rather, this initial commit is focused
on the creation patterns and the most basic operations. Subsequent
commits will continue fleshing out this class and its operation.

The `get_value` method will see significant changes as we introduce
attribute reference support. Its current more simplistic implementation
exists only to serve some interim unit tests.

* Add reference based value retrieval (#207)

This commit introduces the References type used for targeting complex
attributes in the new LDContexts.

References are expected to be created through static factory methods:

```ruby
LaunchDarkly::Reference.create("/a/b")
LaunchDarkly::Reference.create_literal("/a/b")
```

These references can be used to retrieve values from an existing
LDContext

```ruby
ref = LaunchDarkly::Reference.create("/a/b")
result = context.get_value_for_reference(ref)
```

* Basic changes to use contexts in evaluations instead of users (#208)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

This replaces `LDUser` with `LDContext` in the parameters for
evaluations, and makes the minimum necessary adjustments to allow
evaluations to keep working as before as long as the context kind is
"user". None of the new behavior defined in the U2C spec is implemented
yet.

Generation of evaluation events is temporarily disabled because the
event logic hasn't been updated yet.

U2C contract tests for evaluations are partially enabled; a lot of
functionality is still missing, but all the tests that only cover
previously-existing evaluation behavior are passing.

[pr]: launchdarkly/php-server-sdk-private#103

* Support ContextKind in Clauses (#209)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

The main features of this commit are:

- introduction of `individual_context` and `individual_context_count`
  methods 
- context kind matching in clauses

[pr]: launchdarkly/php-server-sdk-private#108

* Support included / excluded contexts in segments (#210)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

Segments are now able to provide `includedContext` and `excludedContext`
properties which can target values within a specific context kind.

```json
{
    "includedContexts": [
        {
            "contextKind": "org",
            "values": ["orgkey1", "orgkey2"]
        }
    ]
}
```

[pr]: launchdarkly/php-server-sdk-private#111

* Add contextKind support for rollouts & experiements (#211)

This commit follows the general approach of the [equivalent PHP SDK
PR][pr].

[pr]: launchdarkly/php-server-sdk-private#110

* Style and test matcher improvements (#212)

This commit enables several rubocop rules that were previously disabled.
Once enabled, `rubocop -A` was run to automatically apply these fixes.

There are a couple of additional changes that were made by hand:

- I added the rubocop and rubocop-performance gems as dev packages. This
  should help address the original installation issue we ran into when I
  introduced these tools.

- By default, new rubocop rules are disabled. This was the default
  before, but if you don't explicitly set this value, each run generates
  a ton of warning noise. This quiets that down.

- Updates some LDContext tests to be more strict in their expectations
  of truth.

* Remove support for secondary attribute (#213)

As decided in the [spec], we are removing the special behavior of the
secondary attribute. Going forward, secondary will be treated like any
other attribute, and will no longer be included when determining the
bucket for a context.

[spec]:
https://launchdarkly.atlassian.net/wiki/spaces/ENG/pages/2165212563/Consistent+and+Transparent+Rollout+Behavior+Unifying+Percent+Rollout+and+Traffic+Allocation

* Remove deprecated APIs (#214)

Since the users to context change requires a version break, this is the
perfect time to remove previously deprecated bits of functionality. This
includes:

- Removing `update_processor*` config entries
- `FileDataSource` entry point
- `RedisFeatureStore` entry point
- `Redis::sadd?` warning in unit tests

* store data model with classes that aren't Hash

* lint

* remove [] override methods in places where we don't need them

* comments

* migrate some more of the model to be non-hash classes

* lint

* Anonymous cannot be nil in new context format (#216)

The legacy user format allowed anonymous to be missing or explicitly
provided but set to nil.

The new context format requires anonymous to either not be set, or if it
is explicitly set, it must be a boolean value.

* Tweak error message language and style (#217)

Our previous error messages suffered from a couple drawbacks:

- The messages were complete sentences, limiting our ability to compose
  error messages
- The messages were overly broad in many cases
- The messages unnecessarily required string interpolation that rarely
  provided much value

These new messages are more succinct and are written as small clauses
which can be used in conjunction with other error messages more easily.

* copyedit

Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>

* Implement prerequisite cycle detection (#219)

* Support attribute reference lookups (#215)

This adds support for slash-delimited paths in clause attributes,
bucketBy, etc. It does not do anything related to private attribute
redaction because none of the U2C event logic is implemented yet.

* Implement segment recursion and cycle detection (#220)

Clauses in segment rules are now allowed to reference segments. To
prevent an infinite recursion edge case, we implement a similar cycle
detection mechanism as used on prerequisites.

* Update event logic to support users to context change (#221)

* Add legacy user-type support to the contract tests (#222)

* Remove inline user configuration option (#223)

* Add context_ configuration options (#224)

These new context_ configuration options are meant to replace the
historic user_ options. If both are provided, the context_ variant will
take precedence.

* Add support for flag context targets (#225)

* Bump diplomat

* Bump redis

* Remove oga

* Bump connection_pool

* Favor set for faster target lookups (#228)

A few of our internal models maintain arrays of values. These arrays can
frequently be checked to see if they contain specific values.

Since set lookups are much faster than array lookups, this commit
changes the internal structure to a set for the values stored in Target
and SegmentTarget.

* Add secure mode hash to contract tests (#229)

* Update big segment support for users to context (#226)

To support the users to context change for big segments, this commit
makes the following changes:

- Introduces a new `Segment.unboundedContextKind` attribute. This will
default to `LDContext::KIND_DEFAULT` and is only referenced when
`Segment.unbounded` is true.

- With the creation of multi-kind contexts, a single evaluation may
result in multiple queries to the big segment store. This is reflected
in the changes to the `EvalResult` processing.

* Drop support for ruby 2.6 (#227)

Ruby 2.6 went EOL in March 2022. We originally didn't drop support for
it as doing so would require dropping support for jRuby as well.
However, jRuby recently released 9.4 which is Ruby 2.7+ compatible.

* Update remaining references from user to contexts (#231)

There are multiple places throughout the code where we are still
referencing users. I have tried to update all the places where a rename
seems reasonable or appropriate. There is still some work to do in the
test flag builders, but that will be done in a subsequent commit.

* Remove new relic integration (#233)

The new relic integration was removed many versions ago but a small
trace remained behind.

* Rename config option private_attribute_names (#234)

Co-authored-by: Eli Bishop <eli@launchdarkly.com>

* Update test data integration to support contexts (#232)

* improve data model validation logging; allow missing/empty attribute for segmentMatch (#236)

* Fix JSON serialization failure (#237)

When we introduced models for the flag and segment data, we added
to_json methods which proxy to the underlying to_json method provided by
the `json` gem.

We defined the method with a variadic parameter, but we failed to unpack
it when passing it on to the underlying implementation. This resulted in
a serialization failure which prevented the redis data store from
initializing.

* fix: Bump eventsource to resolve header parsing (#239)

The underlying event source library had an issue where, in certain
environments, content-type header detection was failing.

This was resolved in v2.2.2 of the event source gem.

* Add key to error log for invalid context during variation call for easier debugging (#214)

* feat: Add support for payload filtering (#238)

* feat: Add data source status provider support (#240)

The client instance will now provide access to a
`data_source_status_provider`. This provider allows developers to
retrieve the status of the SDK on demand, or asynchronously by
registering listeners.

* test: Skip database integration tests by default (#241)

The full unit test suite includes tests relying on externally instances
of Redis, Consult, and DynamoDB.

By default, we do not want to run these tests. Rather, they should be
opt-in by setting the environment variable `LD_SKIP_DATABASE_TESTS=0`.

* feat: Introduce flag change tracker api (#242)

The client instance will now provide access to a `flag_tracker`. This
tracker allows developers to be notified when a flag configuration
changes (or optionally when the /value/ of a flag changes for a
particular context).

* ci: Add code coverage generation (#244)

* feat: Add support for data store status monitoring (#243)

The client instance will now provide access to a
`data_store_status_provider`. This provider allows developers to
retrieve the data store status of the SDK on demand, or asynchronously
by registering listeners.

* Fix monitoring_enabled? access

---------

Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: Jacob Smith <jacob@jacobsmith.io>
Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: hroederld <hroeder@launchdarkly.com>
Co-authored-by: Kerrie Martinez <kyee@launchdarkly.com>
Co-authored-by: pellyg-ld <gpelly@launchdarkly.com>
Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>
Co-authored-by: Matthew M. Keeler <keelerm84@gmail.com>
Co-authored-by: Ben Levy <benjaminlevy007@gmail.com>
Co-authored-by: Ben Levy <ben@foxhound.systems>
Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>
Co-authored-by: Louis Chan <lchan@launchdarkly.com>
Co-authored-by: Matt Hooks <46452201+matt-dutchie@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants