ldclient-rb 3.0.1 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/ldclient-rb/evaluation.rb +1 -1
- data/lib/ldclient-rb/events.rb +4 -4
- data/lib/ldclient-rb/ldclient.rb +15 -15
- data/lib/ldclient-rb/polling.rb +6 -6
- data/lib/ldclient-rb/redis_store.rb +8 -8
- data/lib/ldclient-rb/requestor.rb +4 -4
- data/lib/ldclient-rb/stream.rb +9 -9
- data/lib/ldclient-rb/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41869ab263a2b79a395f296f5bdc0be3ff7c6be5
|
4
|
+
data.tar.gz: 180e6a5ca71016e6776a1b3f484824a604b3cbfb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9301b40618e1fd75e1edefcafc2207da147af8ad0ca03e2b945c2e623675cc88c1ad1d62672730aaf1a4f7f8a25a48e0577b8a6037d18cde486d4289b418c69
|
7
|
+
data.tar.gz: 94a9e852962fcdaf98f2a90b257c06ef3107fd59882d8e92e1ae44fc4239b4f1e37a8875ebaa7c14bafa0e33d453c118b8dca4aa734164496ac608e3f21f1258
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
All notable changes to the LaunchDarkly Ruby SDK will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org).
|
4
4
|
|
5
|
+
## [3.0.2] - 2018-03-06
|
6
|
+
## Fixed
|
7
|
+
- Improved efficiency of logging by not constructing messages that won't be visible at the current log level. (Thanks, [julik](https://github.com/launchdarkly/ruby-client/pull/98)!)
|
8
|
+
|
9
|
+
|
5
10
|
## [3.0.1] - 2018-02-26
|
6
11
|
### Fixed
|
7
12
|
- Fixed a bug that could prevent very large feature flags from being updated in streaming mode.
|
@@ -156,7 +156,7 @@ module LaunchDarkly
|
|
156
156
|
failed_prereq = true
|
157
157
|
end
|
158
158
|
rescue => exn
|
159
|
-
@config.logger.error
|
159
|
+
@config.logger.error { "[LDClient] Error evaluating prerequisite: #{exn.inspect}" }
|
160
160
|
failed_prereq = true
|
161
161
|
end
|
162
162
|
end
|
data/lib/ldclient-rb/events.rb
CHANGED
@@ -50,9 +50,9 @@ module LaunchDarkly
|
|
50
50
|
req.options.open_timeout = @config.connect_timeout
|
51
51
|
end
|
52
52
|
if res.status < 200 || res.status >= 300
|
53
|
-
@config.logger.error
|
53
|
+
@config.logger.error { "[LDClient] Unexpected status code while processing events: #{res.status}" }
|
54
54
|
if res.status == 401
|
55
|
-
@config.logger.error
|
55
|
+
@config.logger.error { "[LDClient] Received 401 error, no further events will be posted since SDK key is invalid" }
|
56
56
|
stop
|
57
57
|
end
|
58
58
|
end
|
@@ -78,14 +78,14 @@ module LaunchDarkly
|
|
78
78
|
|
79
79
|
if @queue.length < @config.capacity
|
80
80
|
event[:creationDate] = (Time.now.to_f * 1000).to_i
|
81
|
-
@config.logger.debug
|
81
|
+
@config.logger.debug { "[LDClient] Enqueueing event: #{event.to_json}" }
|
82
82
|
@queue.push(event)
|
83
83
|
|
84
84
|
if !@worker.alive?
|
85
85
|
@worker = create_worker
|
86
86
|
end
|
87
87
|
else
|
88
|
-
@config.logger.warn
|
88
|
+
@config.logger.warn { "[LDClient] Exceeded event queue capacity. Increase capacity to avoid dropping events." }
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
data/lib/ldclient-rb/ldclient.rb
CHANGED
@@ -31,7 +31,7 @@ module LaunchDarkly
|
|
31
31
|
@event_processor = EventProcessor.new(sdk_key, config)
|
32
32
|
|
33
33
|
if @config.use_ldd?
|
34
|
-
@config.logger.info
|
34
|
+
@config.logger.info { "[LDClient] Started LaunchDarkly Client in LDD mode" }
|
35
35
|
return # requestor and update processor are not used in this mode
|
36
36
|
end
|
37
37
|
|
@@ -41,8 +41,8 @@ module LaunchDarkly
|
|
41
41
|
if @config.stream?
|
42
42
|
@update_processor = StreamProcessor.new(sdk_key, config, requestor)
|
43
43
|
else
|
44
|
-
@config.logger.info
|
45
|
-
@config.logger.warn
|
44
|
+
@config.logger.info { "Disabling streaming API" }
|
45
|
+
@config.logger.warn { "You should only disable the streaming API if instructed to do so by LaunchDarkly support" }
|
46
46
|
@update_processor = PollingProcessor.new(config, requestor)
|
47
47
|
end
|
48
48
|
@update_processor.start
|
@@ -54,7 +54,7 @@ module LaunchDarkly
|
|
54
54
|
initialized?
|
55
55
|
end
|
56
56
|
rescue WaitUtil::TimeoutError
|
57
|
-
@config.logger.error
|
57
|
+
@config.logger.error { "[LDClient] Timeout encountered waiting for LaunchDarkly client initialization" }
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
@@ -64,7 +64,7 @@ module LaunchDarkly
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def toggle?(key, user, default = False)
|
67
|
-
@config.logger.warn
|
67
|
+
@config.logger.warn { "[LDClient] toggle? is deprecated. Use variation instead" }
|
68
68
|
variation(key, user, default)
|
69
69
|
end
|
70
70
|
|
@@ -114,16 +114,16 @@ module LaunchDarkly
|
|
114
114
|
return default if @config.offline?
|
115
115
|
|
116
116
|
unless user
|
117
|
-
@config.logger.error
|
117
|
+
@config.logger.error { "[LDClient] Must specify user" }
|
118
118
|
@event_processor.add_event(kind: "feature", key: key, value: default, default: default, user: user)
|
119
119
|
return default
|
120
120
|
end
|
121
121
|
|
122
122
|
if !initialized?
|
123
123
|
if @store.initialized?
|
124
|
-
@config.logger.warn
|
124
|
+
@config.logger.warn { "[LDClient] Client has not finished initializing; using last known values from feature store" }
|
125
125
|
else
|
126
|
-
@config.logger.error
|
126
|
+
@config.logger.error { "[LDClient] Client has not finished initializing; feature store unavailable, returning default value" }
|
127
127
|
@event_processor.add_event(kind: "feature", key: key, value: default, default: default, user: user)
|
128
128
|
return default
|
129
129
|
end
|
@@ -133,7 +133,7 @@ module LaunchDarkly
|
|
133
133
|
feature = @store.get(FEATURES, key)
|
134
134
|
|
135
135
|
if feature.nil?
|
136
|
-
@config.logger.info
|
136
|
+
@config.logger.info { "[LDClient] Unknown feature flag #{key}. Returning default value" }
|
137
137
|
@event_processor.add_event(kind: "feature", key: key, value: default, default: default, user: user)
|
138
138
|
return default
|
139
139
|
end
|
@@ -149,12 +149,12 @@ module LaunchDarkly
|
|
149
149
|
@event_processor.add_event(kind: "feature", key: key, user: user, value: res[:value], default: default, version: feature[:version])
|
150
150
|
return res[:value]
|
151
151
|
else
|
152
|
-
@config.logger.debug
|
152
|
+
@config.logger.debug { "[LDClient] Result value is null in toggle" }
|
153
153
|
@event_processor.add_event(kind: "feature", key: key, user: user, value: default, default: default, version: feature[:version])
|
154
154
|
return default
|
155
155
|
end
|
156
156
|
rescue => exn
|
157
|
-
@config.logger.warn
|
157
|
+
@config.logger.warn { "[LDClient] Error evaluating feature flag: #{exn.inspect}. \nTrace: #{exn.backtrace}" }
|
158
158
|
@event_processor.add_event(kind: "feature", key: key, user: user, value: default, default: default, version: feature[:version])
|
159
159
|
return default
|
160
160
|
end
|
@@ -192,7 +192,7 @@ module LaunchDarkly
|
|
192
192
|
return Hash.new if @config.offline?
|
193
193
|
|
194
194
|
unless user
|
195
|
-
@config.logger.error
|
195
|
+
@config.logger.error { "[LDClient] Must specify user in all_flags" }
|
196
196
|
return Hash.new
|
197
197
|
end
|
198
198
|
|
@@ -202,7 +202,7 @@ module LaunchDarkly
|
|
202
202
|
# TODO rescue if necessary
|
203
203
|
Hash[features.map{ |k, f| [k, evaluate(f, user, @store)[:value]] }]
|
204
204
|
rescue => exn
|
205
|
-
@config.logger.warn
|
205
|
+
@config.logger.warn { "[LDClient] Error evaluating all flags: #{exn.inspect}. \nTrace: #{exn.backtrace}" }
|
206
206
|
return Hash.new
|
207
207
|
end
|
208
208
|
end
|
@@ -212,7 +212,7 @@ module LaunchDarkly
|
|
212
212
|
#
|
213
213
|
# @return [void]
|
214
214
|
def close
|
215
|
-
@config.logger.info
|
215
|
+
@config.logger.info { "[LDClient] Closing LaunchDarkly client..." }
|
216
216
|
if not @config.offline?
|
217
217
|
@update_processor.stop
|
218
218
|
end
|
@@ -223,7 +223,7 @@ module LaunchDarkly
|
|
223
223
|
def log_exception(caller, exn)
|
224
224
|
error_traceback = "#{exn.inspect} #{exn}\n\t#{exn.backtrace.join("\n\t")}"
|
225
225
|
error = "[LDClient] Unexpected exception in #{caller}: #{error_traceback}"
|
226
|
-
@config.logger.error
|
226
|
+
@config.logger.error { error }
|
227
227
|
end
|
228
228
|
|
229
229
|
def sanitize_user(user)
|
data/lib/ldclient-rb/polling.rb
CHANGED
@@ -17,7 +17,7 @@ module LaunchDarkly
|
|
17
17
|
|
18
18
|
def start
|
19
19
|
return unless @started.make_true
|
20
|
-
@config.logger.info
|
20
|
+
@config.logger.info { "[LDClient] Initializing polling connection" }
|
21
21
|
create_worker
|
22
22
|
end
|
23
23
|
|
@@ -26,7 +26,7 @@ module LaunchDarkly
|
|
26
26
|
if @worker && @worker.alive?
|
27
27
|
@worker.raise "shutting down client"
|
28
28
|
end
|
29
|
-
@config.logger.info
|
29
|
+
@config.logger.info { "[LDClient] Polling connection stopped" }
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -38,14 +38,14 @@ module LaunchDarkly
|
|
38
38
|
SEGMENTS => all_data[:segments]
|
39
39
|
})
|
40
40
|
if @initialized.make_true
|
41
|
-
@config.logger.info
|
41
|
+
@config.logger.info { "[LDClient] Polling connection initialized" }
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
46
|
def create_worker
|
47
47
|
@worker = Thread.new do
|
48
|
-
@config.logger.debug
|
48
|
+
@config.logger.debug { "[LDClient] Starting polling worker" }
|
49
49
|
while !@stopped.value do
|
50
50
|
begin
|
51
51
|
started_at = Time.now
|
@@ -55,10 +55,10 @@ module LaunchDarkly
|
|
55
55
|
sleep(delta)
|
56
56
|
end
|
57
57
|
rescue InvalidSDKKeyError
|
58
|
-
@config.logger.error
|
58
|
+
@config.logger.error { "[LDClient] Received 401 error, no further polling requests will be made since SDK key is invalid" };
|
59
59
|
stop
|
60
60
|
rescue StandardError => exn
|
61
|
-
@config.logger.error
|
61
|
+
@config.logger.error { "[LDClient] Exception while polling: #{exn.inspect}" }
|
62
62
|
# TODO: log_exception(__method__.to_s, exn)
|
63
63
|
end
|
64
64
|
end
|
@@ -94,12 +94,12 @@ and prefix: #{@prefix}")
|
|
94
94
|
def get(kind, key)
|
95
95
|
f = @cache[cache_key(kind, key)]
|
96
96
|
if f.nil?
|
97
|
-
@logger.debug
|
97
|
+
@logger.debug { "RedisFeatureStore: no cache hit for #{key} in '#{kind[:namespace]}', requesting from Redis" }
|
98
98
|
f = with_connection do |redis|
|
99
99
|
begin
|
100
100
|
get_redis(kind, redis, key.to_sym)
|
101
101
|
rescue => e
|
102
|
-
@logger.error
|
102
|
+
@logger.error { "RedisFeatureStore: could not retrieve #{key} from Redis in '#{kind[:namespace]}', with error: #{e}" }
|
103
103
|
nil
|
104
104
|
end
|
105
105
|
end
|
@@ -108,10 +108,10 @@ and prefix: #{@prefix}")
|
|
108
108
|
end
|
109
109
|
end
|
110
110
|
if f.nil?
|
111
|
-
@logger.debug
|
111
|
+
@logger.debug { "RedisFeatureStore: #{key} not found in '#{kind[:namespace]}'" }
|
112
112
|
nil
|
113
113
|
elsif f[:deleted]
|
114
|
-
@logger.debug
|
114
|
+
@logger.debug { "RedisFeatureStore: #{key} was deleted in '#{kind[:namespace]}', returning nil" }
|
115
115
|
nil
|
116
116
|
else
|
117
117
|
f
|
@@ -124,7 +124,7 @@ and prefix: #{@prefix}")
|
|
124
124
|
begin
|
125
125
|
hashfs = redis.hgetall(items_key(kind))
|
126
126
|
rescue => e
|
127
|
-
@logger.error
|
127
|
+
@logger.error { "RedisFeatureStore: could not retrieve all '#{kind[:namespace]}' items from Redis with error: #{e}; returning none" }
|
128
128
|
hashfs = {}
|
129
129
|
end
|
130
130
|
hashfs.each do |k, jsonItem|
|
@@ -169,7 +169,7 @@ and prefix: #{@prefix}")
|
|
169
169
|
end
|
170
170
|
end
|
171
171
|
@inited.set(true)
|
172
|
-
@logger.info
|
172
|
+
@logger.info { "RedisFeatureStore: initialized with #{count} items" }
|
173
173
|
end
|
174
174
|
|
175
175
|
def upsert(kind, item)
|
@@ -219,7 +219,7 @@ and prefix: #{@prefix}")
|
|
219
219
|
json_item = redis.hget(items_key(kind), key)
|
220
220
|
JSON.parse(json_item, symbolize_names: true) if json_item
|
221
221
|
rescue => e
|
222
|
-
@logger.error
|
222
|
+
@logger.error { "RedisFeatureStore: could not retrieve #{key} from Redis, error: #{e}" }
|
223
223
|
nil
|
224
224
|
end
|
225
225
|
end
|
@@ -232,7 +232,7 @@ and prefix: #{@prefix}")
|
|
232
232
|
begin
|
233
233
|
redis.hset(items_key(kind), key, item.to_json)
|
234
234
|
rescue => e
|
235
|
-
@logger.error
|
235
|
+
@logger.error { "RedisFeatureStore: could not store #{key} in Redis, error: #{e}" }
|
236
236
|
end
|
237
237
|
put_cache(kind, key.to_sym, item)
|
238
238
|
end
|
@@ -42,20 +42,20 @@ module LaunchDarkly
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
@config.logger.debug
|
45
|
+
@config.logger.debug { "[LDClient] Got response from uri: #{uri}\n\tstatus code: #{res.status}\n\theaders: #{res.headers}\n\tbody: #{res.body}" }
|
46
46
|
|
47
47
|
if res.status == 401
|
48
|
-
@config.logger.error
|
48
|
+
@config.logger.error { "[LDClient] Invalid SDK key" }
|
49
49
|
raise InvalidSDKKeyError
|
50
50
|
end
|
51
51
|
|
52
52
|
if res.status == 404
|
53
|
-
@config.logger.error
|
53
|
+
@config.logger.error { "[LDClient] Resource not found" }
|
54
54
|
return nil
|
55
55
|
end
|
56
56
|
|
57
57
|
if res.status < 200 || res.status >= 300
|
58
|
-
@config.logger.error
|
58
|
+
@config.logger.error { "[LDClient] Unexpected status code #{res.status}" }
|
59
59
|
return nil
|
60
60
|
end
|
61
61
|
|
data/lib/ldclient-rb/stream.rb
CHANGED
@@ -33,7 +33,7 @@ module LaunchDarkly
|
|
33
33
|
def start
|
34
34
|
return unless @started.make_true
|
35
35
|
|
36
|
-
@config.logger.info
|
36
|
+
@config.logger.info { "[LDClient] Initializing stream connection" }
|
37
37
|
|
38
38
|
headers =
|
39
39
|
{
|
@@ -48,9 +48,9 @@ module LaunchDarkly
|
|
48
48
|
conn.on(INDIRECT_PUT) { |message| process_message(message, INDIRECT_PUT) }
|
49
49
|
conn.on(INDIRECT_PATCH) { |message| process_message(message, INDIRECT_PATCH) }
|
50
50
|
conn.on_error { |err|
|
51
|
-
@config.logger.error
|
51
|
+
@config.logger.error { "[LDClient] Unexpected status code #{err[:status_code]} from streaming connection" }
|
52
52
|
if err[:status_code] == 401
|
53
|
-
@config.logger.error
|
53
|
+
@config.logger.error { "[LDClient] Received 401 error, no further streaming connection will be made since SDK key is invalid" }
|
54
54
|
stop
|
55
55
|
end
|
56
56
|
}
|
@@ -60,21 +60,21 @@ module LaunchDarkly
|
|
60
60
|
def stop
|
61
61
|
if @stopped.make_true
|
62
62
|
@es.close
|
63
|
-
@config.logger.info
|
63
|
+
@config.logger.info { "[LDClient] Stream connection stopped" }
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
67
|
def stop
|
68
68
|
if @stopped.make_true
|
69
69
|
@es.close
|
70
|
-
@config.logger.info
|
70
|
+
@config.logger.info { "[LDClient] Stream connection stopped" }
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
74
|
private
|
75
75
|
|
76
76
|
def process_message(message, method)
|
77
|
-
@config.logger.debug
|
77
|
+
@config.logger.debug { "[LDClient] Stream received #{method} message: #{message.data}" }
|
78
78
|
if method == PUT
|
79
79
|
message = JSON.parse(message.data, symbolize_names: true)
|
80
80
|
@feature_store.init({
|
@@ -82,7 +82,7 @@ module LaunchDarkly
|
|
82
82
|
SEGMENTS => message[:data][:segments]
|
83
83
|
})
|
84
84
|
@initialized.make_true
|
85
|
-
@config.logger.info
|
85
|
+
@config.logger.info { "[LDClient] Stream initialized" }
|
86
86
|
elsif method == PATCH
|
87
87
|
message = JSON.parse(message.data, symbolize_names: true)
|
88
88
|
for kind in [FEATURES, SEGMENTS]
|
@@ -108,7 +108,7 @@ module LaunchDarkly
|
|
108
108
|
SEGMENTS => all_data[:segments]
|
109
109
|
})
|
110
110
|
@initialized.make_true
|
111
|
-
@config.logger.info
|
111
|
+
@config.logger.info { "[LDClient] Stream initialized (via indirect message)" }
|
112
112
|
elsif method == INDIRECT_PATCH
|
113
113
|
key = key_for_path(FEATURES, message.data)
|
114
114
|
if key
|
@@ -120,7 +120,7 @@ module LaunchDarkly
|
|
120
120
|
end
|
121
121
|
end
|
122
122
|
else
|
123
|
-
@config.logger.warn
|
123
|
+
@config.logger.warn { "[LDClient] Unknown message received: #{method}" }
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
data/lib/ldclient-rb/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ldclient-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LaunchDarkly
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|