launchdarkly-server-sdk 5.5.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +134 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  5. data/.gitignore +15 -0
  6. data/.hound.yml +2 -0
  7. data/.rspec +2 -0
  8. data/.rubocop.yml +600 -0
  9. data/.simplecov +4 -0
  10. data/.yardopts +9 -0
  11. data/CHANGELOG.md +261 -0
  12. data/CODEOWNERS +1 -0
  13. data/CONTRIBUTING.md +37 -0
  14. data/Gemfile +3 -0
  15. data/Gemfile.lock +102 -0
  16. data/LICENSE.txt +13 -0
  17. data/README.md +56 -0
  18. data/Rakefile +5 -0
  19. data/azure-pipelines.yml +51 -0
  20. data/ext/mkrf_conf.rb +11 -0
  21. data/launchdarkly-server-sdk.gemspec +40 -0
  22. data/lib/ldclient-rb.rb +29 -0
  23. data/lib/ldclient-rb/cache_store.rb +45 -0
  24. data/lib/ldclient-rb/config.rb +411 -0
  25. data/lib/ldclient-rb/evaluation.rb +455 -0
  26. data/lib/ldclient-rb/event_summarizer.rb +55 -0
  27. data/lib/ldclient-rb/events.rb +468 -0
  28. data/lib/ldclient-rb/expiring_cache.rb +77 -0
  29. data/lib/ldclient-rb/file_data_source.rb +312 -0
  30. data/lib/ldclient-rb/flags_state.rb +76 -0
  31. data/lib/ldclient-rb/impl.rb +13 -0
  32. data/lib/ldclient-rb/impl/integrations/consul_impl.rb +158 -0
  33. data/lib/ldclient-rb/impl/integrations/dynamodb_impl.rb +228 -0
  34. data/lib/ldclient-rb/impl/integrations/redis_impl.rb +155 -0
  35. data/lib/ldclient-rb/impl/store_client_wrapper.rb +47 -0
  36. data/lib/ldclient-rb/impl/store_data_set_sorter.rb +55 -0
  37. data/lib/ldclient-rb/in_memory_store.rb +100 -0
  38. data/lib/ldclient-rb/integrations.rb +55 -0
  39. data/lib/ldclient-rb/integrations/consul.rb +38 -0
  40. data/lib/ldclient-rb/integrations/dynamodb.rb +47 -0
  41. data/lib/ldclient-rb/integrations/redis.rb +55 -0
  42. data/lib/ldclient-rb/integrations/util/store_wrapper.rb +230 -0
  43. data/lib/ldclient-rb/interfaces.rb +153 -0
  44. data/lib/ldclient-rb/ldclient.rb +424 -0
  45. data/lib/ldclient-rb/memoized_value.rb +32 -0
  46. data/lib/ldclient-rb/newrelic.rb +17 -0
  47. data/lib/ldclient-rb/non_blocking_thread_pool.rb +46 -0
  48. data/lib/ldclient-rb/polling.rb +78 -0
  49. data/lib/ldclient-rb/redis_store.rb +87 -0
  50. data/lib/ldclient-rb/requestor.rb +101 -0
  51. data/lib/ldclient-rb/simple_lru_cache.rb +25 -0
  52. data/lib/ldclient-rb/stream.rb +141 -0
  53. data/lib/ldclient-rb/user_filter.rb +51 -0
  54. data/lib/ldclient-rb/util.rb +50 -0
  55. data/lib/ldclient-rb/version.rb +3 -0
  56. data/scripts/gendocs.sh +11 -0
  57. data/scripts/release.sh +27 -0
  58. data/spec/config_spec.rb +63 -0
  59. data/spec/evaluation_spec.rb +739 -0
  60. data/spec/event_summarizer_spec.rb +63 -0
  61. data/spec/events_spec.rb +642 -0
  62. data/spec/expiring_cache_spec.rb +76 -0
  63. data/spec/feature_store_spec_base.rb +213 -0
  64. data/spec/file_data_source_spec.rb +255 -0
  65. data/spec/fixtures/feature.json +37 -0
  66. data/spec/fixtures/feature1.json +36 -0
  67. data/spec/fixtures/user.json +9 -0
  68. data/spec/flags_state_spec.rb +81 -0
  69. data/spec/http_util.rb +109 -0
  70. data/spec/in_memory_feature_store_spec.rb +12 -0
  71. data/spec/integrations/consul_feature_store_spec.rb +42 -0
  72. data/spec/integrations/dynamodb_feature_store_spec.rb +105 -0
  73. data/spec/integrations/store_wrapper_spec.rb +276 -0
  74. data/spec/ldclient_spec.rb +471 -0
  75. data/spec/newrelic_spec.rb +5 -0
  76. data/spec/polling_spec.rb +120 -0
  77. data/spec/redis_feature_store_spec.rb +95 -0
  78. data/spec/requestor_spec.rb +214 -0
  79. data/spec/segment_store_spec_base.rb +95 -0
  80. data/spec/simple_lru_cache_spec.rb +24 -0
  81. data/spec/spec_helper.rb +9 -0
  82. data/spec/store_spec.rb +10 -0
  83. data/spec/stream_spec.rb +60 -0
  84. data/spec/user_filter_spec.rb +91 -0
  85. data/spec/util_spec.rb +17 -0
  86. data/spec/version_spec.rb +7 -0
  87. metadata +375 -0
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ describe LaunchDarkly::SimpleLRUCacheSet do
4
+ subject { LaunchDarkly::SimpleLRUCacheSet }
5
+
6
+ it "retains values up to capacity" do
7
+ lru = subject.new(3)
8
+ expect(lru.add("a")).to be false
9
+ expect(lru.add("b")).to be false
10
+ expect(lru.add("c")).to be false
11
+ expect(lru.add("a")).to be true
12
+ expect(lru.add("b")).to be true
13
+ expect(lru.add("c")).to be true
14
+ end
15
+
16
+ it "discards oldest value on overflow" do
17
+ lru = subject.new(2)
18
+ expect(lru.add("a")).to be false
19
+ expect(lru.add("b")).to be false
20
+ expect(lru.add("a")).to be true
21
+ expect(lru.add("c")).to be false # b is discarded as oldest
22
+ expect(lru.add("b")).to be false
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ require "codeclimate-test-reporter"
2
+ CodeClimate::TestReporter.start
3
+
4
+ require "ldclient-rb"
5
+
6
+ RSpec.configure do |config|
7
+ config.before(:each) do
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ require "spec_helper"
2
+
3
+ describe LaunchDarkly::ThreadSafeMemoryStore do
4
+ subject { LaunchDarkly::ThreadSafeMemoryStore }
5
+ let(:store) { subject.new }
6
+ it "can read and write" do
7
+ store.write("key", "value")
8
+ expect(store.read("key")).to eq "value"
9
+ end
10
+ end
@@ -0,0 +1,60 @@
1
+ require "ld-eventsource"
2
+ require "spec_helper"
3
+
4
+ describe LaunchDarkly::StreamProcessor do
5
+ subject { LaunchDarkly::StreamProcessor }
6
+ let(:config) { LaunchDarkly::Config.new }
7
+ let(:requestor) { double() }
8
+ let(:processor) { subject.new("sdk_key", config, requestor) }
9
+
10
+ describe '#process_message' do
11
+ let(:put_message) { SSE::StreamEvent.new(:put, '{"data":{"flags":{"asdf": {"key": "asdf"}},"segments":{"segkey": {"key": "segkey"}}}}') }
12
+ let(:patch_flag_message) { SSE::StreamEvent.new(:patch, '{"path": "/flags/key", "data": {"key": "asdf", "version": 1}}') }
13
+ let(:patch_seg_message) { SSE::StreamEvent.new(:patch, '{"path": "/segments/key", "data": {"key": "asdf", "version": 1}}') }
14
+ let(:delete_flag_message) { SSE::StreamEvent.new(:delete, '{"path": "/flags/key", "version": 2}') }
15
+ let(:delete_seg_message) { SSE::StreamEvent.new(:delete, '{"path": "/segments/key", "version": 2}') }
16
+ let(:indirect_patch_flag_message) { SSE::StreamEvent.new(:'indirect/patch', "/flags/key") }
17
+ let(:indirect_patch_segment_message) { SSE::StreamEvent.new(:'indirect/patch', "/segments/key") }
18
+
19
+ it "will accept PUT methods" do
20
+ processor.send(:process_message, put_message)
21
+ expect(config.feature_store.get(LaunchDarkly::FEATURES, "asdf")).to eq(key: "asdf")
22
+ expect(config.feature_store.get(LaunchDarkly::SEGMENTS, "segkey")).to eq(key: "segkey")
23
+ end
24
+ it "will accept PATCH methods for flags" do
25
+ processor.send(:process_message, patch_flag_message)
26
+ expect(config.feature_store.get(LaunchDarkly::FEATURES, "asdf")).to eq(key: "asdf", version: 1)
27
+ end
28
+ it "will accept PATCH methods for segments" do
29
+ processor.send(:process_message, patch_seg_message)
30
+ expect(config.feature_store.get(LaunchDarkly::SEGMENTS, "asdf")).to eq(key: "asdf", version: 1)
31
+ end
32
+ it "will accept DELETE methods for flags" do
33
+ processor.send(:process_message, patch_flag_message)
34
+ processor.send(:process_message, delete_flag_message)
35
+ expect(config.feature_store.get(LaunchDarkly::FEATURES, "key")).to eq(nil)
36
+ end
37
+ it "will accept DELETE methods for segments" do
38
+ processor.send(:process_message, patch_seg_message)
39
+ processor.send(:process_message, delete_seg_message)
40
+ expect(config.feature_store.get(LaunchDarkly::SEGMENTS, "key")).to eq(nil)
41
+ end
42
+ it "will accept INDIRECT PATCH method for flags" do
43
+ flag = { key: 'key', version: 1 }
44
+ allow(requestor).to receive(:request_flag).with(flag[:key]).and_return(flag)
45
+ processor.send(:process_message, indirect_patch_flag_message);
46
+ expect(config.feature_store.get(LaunchDarkly::FEATURES, flag[:key])).to eq(flag)
47
+ end
48
+ it "will accept INDIRECT PATCH method for segments" do
49
+ segment = { key: 'key', version: 1 }
50
+ allow(requestor).to receive(:request_segment).with(segment[:key]).and_return(segment)
51
+ processor.send(:process_message, indirect_patch_segment_message);
52
+ expect(config.feature_store.get(LaunchDarkly::SEGMENTS, segment[:key])).to eq(segment)
53
+ end
54
+ it "will log a warning if the method is not recognized" do
55
+ expect(processor.instance_variable_get(:@config).logger).to receive :warn
56
+ processor.send(:process_message, SSE::StreamEvent.new(type: :get, data: "", id: nil))
57
+ end
58
+ end
59
+ end
60
+
@@ -0,0 +1,91 @@
1
+ require "spec_helper"
2
+
3
+ describe LaunchDarkly::UserFilter do
4
+ subject { LaunchDarkly::UserFilter }
5
+
6
+ let(:base_config) { LaunchDarkly::Config.new }
7
+ let(:config_with_all_attrs_private) { LaunchDarkly::Config.new({ all_attributes_private: true })}
8
+ let(:config_with_some_attrs_private) { LaunchDarkly::Config.new({ private_attribute_names: ['firstName', 'bizzle'] })}
9
+
10
+ # users to serialize
11
+
12
+ let(:user) {
13
+ { key: 'abc', firstName: 'Sue', custom: { bizzle: 'def', dizzle: 'ghi' }}
14
+ }
15
+
16
+ let(:user_specifying_own_private_attr) {
17
+ u = user.clone
18
+ u[:privateAttributeNames] = [ 'dizzle', 'unused' ]
19
+ u
20
+ }
21
+
22
+ let(:user_with_unknown_top_level_attrs) {
23
+ { key: 'abc', firstName: 'Sue', species: 'human', hatSize: 6, custom: { bizzle: 'def', dizzle: 'ghi' }}
24
+ }
25
+
26
+ let(:anon_user) {
27
+ { key: 'abc', anonymous: 'true', custom: { bizzle: 'def', dizzle: 'ghi' }}
28
+ }
29
+
30
+ # expected results from serializing user
31
+
32
+ let(:user_with_all_attrs_hidden) {
33
+ { key: 'abc', custom: { }, privateAttrs: [ 'bizzle', 'dizzle', 'firstName' ]}
34
+ }
35
+
36
+ let(:user_with_some_attrs_hidden) {
37
+ { key: 'abc', custom: { dizzle: 'ghi' }, privateAttrs: [ 'bizzle', 'firstName' ]}
38
+ }
39
+
40
+ let(:user_with_own_specified_attr_hidden) {
41
+ { key: 'abc', firstName: 'Sue', custom: { bizzle: 'def' }, privateAttrs: [ 'dizzle' ]}
42
+ }
43
+
44
+ let(:anon_user_with_all_attrs_hidden) {
45
+ { key: 'abc', anonymous: 'true', custom: { }, privateAttrs: [ 'bizzle', 'dizzle' ]}
46
+ }
47
+
48
+ describe "serialize_events" do
49
+ it "includes all user attributes by default" do
50
+ uf = LaunchDarkly::UserFilter.new(base_config)
51
+ result = uf.transform_user_props(user)
52
+ expect(result).to eq user
53
+ end
54
+
55
+ it "hides all except key if all_attributes_private is true" do
56
+ uf = LaunchDarkly::UserFilter.new(config_with_all_attrs_private)
57
+ result = uf.transform_user_props(user)
58
+ expect(result).to eq user_with_all_attrs_hidden
59
+ end
60
+
61
+ it "hides some attributes if private_attribute_names is set" do
62
+ uf = LaunchDarkly::UserFilter.new(config_with_some_attrs_private)
63
+ result = uf.transform_user_props(user)
64
+ expect(result).to eq user_with_some_attrs_hidden
65
+ end
66
+
67
+ it "hides attributes specified in per-user privateAttrs" do
68
+ uf = LaunchDarkly::UserFilter.new(base_config)
69
+ result = uf.transform_user_props(user_specifying_own_private_attr)
70
+ expect(result).to eq user_with_own_specified_attr_hidden
71
+ end
72
+
73
+ it "looks at both per-user privateAttrs and global config" do
74
+ uf = LaunchDarkly::UserFilter.new(config_with_some_attrs_private)
75
+ result = uf.transform_user_props(user_specifying_own_private_attr)
76
+ expect(result).to eq user_with_all_attrs_hidden
77
+ end
78
+
79
+ it "strips out any unknown top-level attributes" do
80
+ uf = LaunchDarkly::UserFilter.new(base_config)
81
+ result = uf.transform_user_props(user_with_unknown_top_level_attrs)
82
+ expect(result).to eq user
83
+ end
84
+
85
+ it "leaves the anonymous attribute as is" do
86
+ uf = LaunchDarkly::UserFilter.new(config_with_all_attrs_private)
87
+ result = uf.transform_user_props(anon_user)
88
+ expect(result).to eq anon_user_with_all_attrs_hidden
89
+ end
90
+ end
91
+ end
data/spec/util_spec.rb ADDED
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+
3
+ describe LaunchDarkly::Util do
4
+ describe 'log_exception' do
5
+ let(:logger) { double() }
6
+
7
+ it "logs error data" do
8
+ expect(logger).to receive(:error)
9
+ expect(logger).to receive(:debug)
10
+ begin
11
+ raise StandardError.new 'asdf'
12
+ rescue StandardError => exn
13
+ LaunchDarkly::Util.log_exception(logger, "message", exn)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe LaunchDarkly do
4
+ it "has a version" do
5
+ expect(LaunchDarkly::VERSION).to be
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,375 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: launchdarkly-server-sdk
3
+ version: !ruby/object:Gem::Version
4
+ version: 5.5.7
5
+ platform: ruby
6
+ authors:
7
+ - LaunchDarkly
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-05-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-dynamodb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.18'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.18'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: codeclimate-test-reporter
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: diplomat
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 2.0.2
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 2.0.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: redis
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 3.3.5
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 3.3.5
97
+ - !ruby/object:Gem::Dependency
98
+ name: connection_pool
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 2.1.2
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 2.1.2
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '10.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '10.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec_junit_formatter
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.3.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 0.3.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: timecop
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.9.1
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.9.1
153
+ - !ruby/object:Gem::Dependency
154
+ name: listen
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '3.0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '3.0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: json
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '1.8'
174
+ - - "<"
175
+ - !ruby/object:Gem::Version
176
+ version: '3'
177
+ type: :runtime
178
+ prerelease: false
179
+ version_requirements: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ version: '1.8'
184
+ - - "<"
185
+ - !ruby/object:Gem::Version
186
+ version: '3'
187
+ - !ruby/object:Gem::Dependency
188
+ name: semantic
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: '1.6'
194
+ type: :runtime
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - "~>"
199
+ - !ruby/object:Gem::Version
200
+ version: '1.6'
201
+ - !ruby/object:Gem::Dependency
202
+ name: concurrent-ruby
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - "~>"
206
+ - !ruby/object:Gem::Version
207
+ version: '1.0'
208
+ type: :runtime
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - "~>"
213
+ - !ruby/object:Gem::Version
214
+ version: '1.0'
215
+ - !ruby/object:Gem::Dependency
216
+ name: ld-eventsource
217
+ requirement: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - "~>"
220
+ - !ruby/object:Gem::Version
221
+ version: '1.0'
222
+ type: :runtime
223
+ prerelease: false
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - "~>"
227
+ - !ruby/object:Gem::Version
228
+ version: '1.0'
229
+ description: Official LaunchDarkly SDK for Ruby
230
+ email:
231
+ - team@launchdarkly.com
232
+ executables: []
233
+ extensions:
234
+ - ext/mkrf_conf.rb
235
+ extra_rdoc_files: []
236
+ files:
237
+ - ".circleci/config.yml"
238
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
239
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
240
+ - ".gitignore"
241
+ - ".hound.yml"
242
+ - ".rspec"
243
+ - ".rubocop.yml"
244
+ - ".simplecov"
245
+ - ".yardopts"
246
+ - CHANGELOG.md
247
+ - CODEOWNERS
248
+ - CONTRIBUTING.md
249
+ - Gemfile
250
+ - Gemfile.lock
251
+ - LICENSE.txt
252
+ - README.md
253
+ - Rakefile
254
+ - azure-pipelines.yml
255
+ - ext/mkrf_conf.rb
256
+ - launchdarkly-server-sdk.gemspec
257
+ - lib/ldclient-rb.rb
258
+ - lib/ldclient-rb/cache_store.rb
259
+ - lib/ldclient-rb/config.rb
260
+ - lib/ldclient-rb/evaluation.rb
261
+ - lib/ldclient-rb/event_summarizer.rb
262
+ - lib/ldclient-rb/events.rb
263
+ - lib/ldclient-rb/expiring_cache.rb
264
+ - lib/ldclient-rb/file_data_source.rb
265
+ - lib/ldclient-rb/flags_state.rb
266
+ - lib/ldclient-rb/impl.rb
267
+ - lib/ldclient-rb/impl/integrations/consul_impl.rb
268
+ - lib/ldclient-rb/impl/integrations/dynamodb_impl.rb
269
+ - lib/ldclient-rb/impl/integrations/redis_impl.rb
270
+ - lib/ldclient-rb/impl/store_client_wrapper.rb
271
+ - lib/ldclient-rb/impl/store_data_set_sorter.rb
272
+ - lib/ldclient-rb/in_memory_store.rb
273
+ - lib/ldclient-rb/integrations.rb
274
+ - lib/ldclient-rb/integrations/consul.rb
275
+ - lib/ldclient-rb/integrations/dynamodb.rb
276
+ - lib/ldclient-rb/integrations/redis.rb
277
+ - lib/ldclient-rb/integrations/util/store_wrapper.rb
278
+ - lib/ldclient-rb/interfaces.rb
279
+ - lib/ldclient-rb/ldclient.rb
280
+ - lib/ldclient-rb/memoized_value.rb
281
+ - lib/ldclient-rb/newrelic.rb
282
+ - lib/ldclient-rb/non_blocking_thread_pool.rb
283
+ - lib/ldclient-rb/polling.rb
284
+ - lib/ldclient-rb/redis_store.rb
285
+ - lib/ldclient-rb/requestor.rb
286
+ - lib/ldclient-rb/simple_lru_cache.rb
287
+ - lib/ldclient-rb/stream.rb
288
+ - lib/ldclient-rb/user_filter.rb
289
+ - lib/ldclient-rb/util.rb
290
+ - lib/ldclient-rb/version.rb
291
+ - scripts/gendocs.sh
292
+ - scripts/release.sh
293
+ - spec/config_spec.rb
294
+ - spec/evaluation_spec.rb
295
+ - spec/event_summarizer_spec.rb
296
+ - spec/events_spec.rb
297
+ - spec/expiring_cache_spec.rb
298
+ - spec/feature_store_spec_base.rb
299
+ - spec/file_data_source_spec.rb
300
+ - spec/fixtures/feature.json
301
+ - spec/fixtures/feature1.json
302
+ - spec/fixtures/user.json
303
+ - spec/flags_state_spec.rb
304
+ - spec/http_util.rb
305
+ - spec/in_memory_feature_store_spec.rb
306
+ - spec/integrations/consul_feature_store_spec.rb
307
+ - spec/integrations/dynamodb_feature_store_spec.rb
308
+ - spec/integrations/store_wrapper_spec.rb
309
+ - spec/ldclient_spec.rb
310
+ - spec/newrelic_spec.rb
311
+ - spec/polling_spec.rb
312
+ - spec/redis_feature_store_spec.rb
313
+ - spec/requestor_spec.rb
314
+ - spec/segment_store_spec_base.rb
315
+ - spec/simple_lru_cache_spec.rb
316
+ - spec/spec_helper.rb
317
+ - spec/store_spec.rb
318
+ - spec/stream_spec.rb
319
+ - spec/user_filter_spec.rb
320
+ - spec/util_spec.rb
321
+ - spec/version_spec.rb
322
+ homepage: https://github.com/launchdarkly/ruby-server-sdk
323
+ licenses:
324
+ - Apache-2.0
325
+ metadata: {}
326
+ post_install_message:
327
+ rdoc_options: []
328
+ require_paths:
329
+ - lib
330
+ required_ruby_version: !ruby/object:Gem::Requirement
331
+ requirements:
332
+ - - ">="
333
+ - !ruby/object:Gem::Version
334
+ version: '0'
335
+ required_rubygems_version: !ruby/object:Gem::Requirement
336
+ requirements:
337
+ - - ">="
338
+ - !ruby/object:Gem::Version
339
+ version: '0'
340
+ requirements: []
341
+ rubyforge_project:
342
+ rubygems_version: 2.5.2
343
+ signing_key:
344
+ specification_version: 4
345
+ summary: LaunchDarkly SDK for Ruby
346
+ test_files:
347
+ - spec/config_spec.rb
348
+ - spec/evaluation_spec.rb
349
+ - spec/event_summarizer_spec.rb
350
+ - spec/events_spec.rb
351
+ - spec/expiring_cache_spec.rb
352
+ - spec/feature_store_spec_base.rb
353
+ - spec/file_data_source_spec.rb
354
+ - spec/fixtures/feature.json
355
+ - spec/fixtures/feature1.json
356
+ - spec/fixtures/user.json
357
+ - spec/flags_state_spec.rb
358
+ - spec/http_util.rb
359
+ - spec/in_memory_feature_store_spec.rb
360
+ - spec/integrations/consul_feature_store_spec.rb
361
+ - spec/integrations/dynamodb_feature_store_spec.rb
362
+ - spec/integrations/store_wrapper_spec.rb
363
+ - spec/ldclient_spec.rb
364
+ - spec/newrelic_spec.rb
365
+ - spec/polling_spec.rb
366
+ - spec/redis_feature_store_spec.rb
367
+ - spec/requestor_spec.rb
368
+ - spec/segment_store_spec_base.rb
369
+ - spec/simple_lru_cache_spec.rb
370
+ - spec/spec_helper.rb
371
+ - spec/store_spec.rb
372
+ - spec/stream_spec.rb
373
+ - spec/user_filter_spec.rb
374
+ - spec/util_spec.rb
375
+ - spec/version_spec.rb