flagger 2.0.4 → 2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/flagger/cloud.rb +176 -35
- data/lib/flagger/models.rb +17 -5
- data/lib/flagger/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83ee349b75c8fe210460e4d38f08a1163c26934d9d3479ee6816339f7c717b18
|
4
|
+
data.tar.gz: 05aaec4dcc582463ae66d06ab01dc49f359b8177c655640550f4386ccfa92ced
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a831fff34ffd437e578e7d201328fc2432364695eb09561e2e684b5f9c410dd5471e01d49f3f73a98fb4b587030d7dba8c5e62e35acf9ecce0bf496801392d9
|
7
|
+
data.tar.gz: b6b765ddf6dd34c7c8b3f450f3c549b0514157f29b8d6014929000fb36d58b36c93f231f232e3b1f5f271bd544a2c90b5da4496178ed222bad1ed4f6b73b60ee
|
data/lib/flagger/cloud.rb
CHANGED
@@ -25,17 +25,25 @@ module FlaggerEnvironments
|
|
25
25
|
attr_accessor :request_timeout
|
26
26
|
|
27
27
|
def initialize(env_key, request_timeout)
|
28
|
-
@
|
28
|
+
@env_key = env_key
|
29
|
+
@request_timeout = request_timeout
|
30
|
+
|
31
|
+
@ingestion_max_items = 500
|
32
|
+
@ingestion_interval = 30
|
33
|
+
|
29
34
|
@entities = []
|
30
35
|
@stats = []
|
31
36
|
@exposures = []
|
32
37
|
@flags = Set[]
|
33
38
|
@ingested_flags = Set[]
|
34
|
-
@env_key = env_key
|
35
|
-
@request_timeout = request_timeout
|
36
39
|
|
37
|
-
@
|
38
|
-
@
|
40
|
+
@entity_lru_hashes = LruRedux::Cache.new(500)
|
41
|
+
@first_ingestion = true
|
42
|
+
|
43
|
+
@should_ingest_entities = true
|
44
|
+
@should_ingest_stats = true
|
45
|
+
@should_ingest_exposures = true
|
46
|
+
@should_ingest_flags = true
|
39
47
|
|
40
48
|
begin
|
41
49
|
get_gating_info("#{GATING_INFO_ENDPOINT}/#{@env_key}", 'duration__gating_info')
|
@@ -112,9 +120,37 @@ module FlaggerEnvironments
|
|
112
120
|
if gating_info&.sdk_info&.ingestion_interval then
|
113
121
|
@ingestion_interval = gating_info.sdk_info.ingestion_interval
|
114
122
|
end
|
123
|
+
if gating_info&.sdk_info&.should_ingest_entities then
|
124
|
+
@should_ingest_entities = gating_info.sdk_info.should_ingest_entities
|
125
|
+
end
|
126
|
+
if gating_info&.sdk_info&.should_ingest_stats then
|
127
|
+
@should_ingest_stats = gating_info&.sdk_info&.should_ingest_stats
|
128
|
+
end
|
129
|
+
if gating_info&.sdk_info&.should_ingest_exposures then
|
130
|
+
@should_ingest_exposures = gating_info&.sdk_info&.should_ingest_exposures
|
131
|
+
end
|
132
|
+
if gating_info&.sdk_info&.should_ingest_flags then
|
133
|
+
@should_ingest_flags = gating_info&.sdk_info&.should_ingest_flags
|
134
|
+
end
|
115
135
|
end
|
116
136
|
|
117
137
|
def maybe_ingest(should_ingest = false)
|
138
|
+
if !@should_ingest_entities then
|
139
|
+
@entities = []
|
140
|
+
end
|
141
|
+
|
142
|
+
if !@should_ingest_stats then
|
143
|
+
@stats = []
|
144
|
+
end
|
145
|
+
|
146
|
+
if !@should_ingest_exposures then
|
147
|
+
@exposures = []
|
148
|
+
end
|
149
|
+
|
150
|
+
if !@should_ingest_flags then
|
151
|
+
@flags = Set[]
|
152
|
+
end
|
153
|
+
|
118
154
|
should_ingest |= (
|
119
155
|
@entities.length > @ingestion_max_items ||
|
120
156
|
@stats.length > @ingestion_max_items ||
|
@@ -122,6 +158,11 @@ module FlaggerEnvironments
|
|
122
158
|
@flags.length > 0
|
123
159
|
)
|
124
160
|
|
161
|
+
if @first_ingestion then
|
162
|
+
should_ingest |= @entities.length > 0
|
163
|
+
@first_ingestion = !should_ingest
|
164
|
+
end
|
165
|
+
|
125
166
|
should_ingest &= (
|
126
167
|
@entities.length > 0 ||
|
127
168
|
@stats.length > 0 ||
|
@@ -246,41 +287,141 @@ module FlaggerEnvironments
|
|
246
287
|
end
|
247
288
|
end
|
248
289
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
'eligible?' => 'duration__is_eligible',
|
253
|
-
'enabled?' => 'duration__is_enabled',
|
254
|
-
}.each do |name, stat_name|
|
255
|
-
define_method(name.to_sym) do |flagger_flag, entity_json|
|
256
|
-
stat = FlaggerUtils::Stat.new(stat_name)
|
257
|
-
stat.start()
|
258
|
-
|
259
|
-
entity = identify_entity(entity_json)
|
260
|
-
flag = @gating_info&.flag(flagger_flag.flag_name)
|
261
|
-
if flag.nil? && !@ingested_flags.include?(flagger_flag.flag_name) then
|
262
|
-
save_flag(flagger_flag.flag_name)
|
263
|
-
end
|
264
|
-
return_value = flag&.public_send(name, entity)
|
265
|
-
|
266
|
-
if name == 'treatment' and !return_value.nil? then
|
267
|
-
exposure = {
|
268
|
-
type: entity.type,
|
269
|
-
id: entity.id,
|
270
|
-
treatment_id: return_value.treatment_id,
|
271
|
-
treatment: return_value.codename
|
272
|
-
}
|
290
|
+
def treatment(flagger_flag, entity_json)
|
291
|
+
stat = FlaggerUtils::Stat.new('duration__get_treatment')
|
292
|
+
stat.start()
|
273
293
|
|
274
|
-
|
294
|
+
entity = identify_entity(entity_json)
|
295
|
+
flag = @gating_info&.flag(flagger_flag.flag_name)
|
296
|
+
if flag.nil? && !@ingested_flags.include?(flagger_flag.flag_name) then
|
297
|
+
save_flag(flagger_flag.flag_name)
|
298
|
+
end
|
299
|
+
return_value = flag&.treatment(entity)
|
275
300
|
|
276
|
-
|
277
|
-
|
301
|
+
if !return_value then
|
302
|
+
return return_value
|
303
|
+
end
|
278
304
|
|
279
|
-
|
280
|
-
|
305
|
+
exposure = {
|
306
|
+
flag: flagger_flag.flag_name,
|
307
|
+
type: entity.type,
|
308
|
+
id: entity.id,
|
309
|
+
treatment: return_value[:treatment].codename,
|
310
|
+
method_called: 'get_treatment',
|
311
|
+
eligible: return_value[:eligible]
|
312
|
+
}
|
313
|
+
|
314
|
+
return_value = return_value[:treatment].codename
|
315
|
+
|
316
|
+
save_exposure(exposure)
|
281
317
|
|
282
|
-
|
318
|
+
stat.stop()
|
319
|
+
save_stat(stat)
|
320
|
+
|
321
|
+
return_value
|
322
|
+
end
|
323
|
+
|
324
|
+
|
325
|
+
def payload(flagger_flag, entity_json)
|
326
|
+
stat = FlaggerUtils::Stat.new('duration__get_payload')
|
327
|
+
stat.start()
|
328
|
+
|
329
|
+
entity = identify_entity(entity_json)
|
330
|
+
flag = @gating_info&.flag(flagger_flag.flag_name)
|
331
|
+
if flag.nil? && !@ingested_flags.include?(flagger_flag.flag_name) then
|
332
|
+
save_flag(flagger_flag.flag_name)
|
333
|
+
end
|
334
|
+
return_value = flag&.payload(entity)
|
335
|
+
|
336
|
+
if !return_value then
|
337
|
+
return return_value
|
338
|
+
end
|
339
|
+
|
340
|
+
exposure = {
|
341
|
+
flag: flagger_flag.flag_name,
|
342
|
+
type: entity.type,
|
343
|
+
id: entity.id,
|
344
|
+
treatment: return_value[:treatment].codename,
|
345
|
+
method_called: 'get_payload',
|
346
|
+
eligible: return_value[:eligible]
|
347
|
+
}
|
348
|
+
|
349
|
+
return_value = return_value[:treatment].payload
|
350
|
+
|
351
|
+
save_exposure(exposure)
|
352
|
+
|
353
|
+
stat.stop()
|
354
|
+
save_stat(stat)
|
355
|
+
|
356
|
+
return_value
|
357
|
+
end
|
358
|
+
|
359
|
+
def eligible?(flagger_flag, entity_json)
|
360
|
+
stat = FlaggerUtils::Stat.new('duration__is_eligible')
|
361
|
+
stat.start()
|
362
|
+
|
363
|
+
entity = identify_entity(entity_json)
|
364
|
+
flag = @gating_info&.flag(flagger_flag.flag_name)
|
365
|
+
if flag.nil? && !@ingested_flags.include?(flagger_flag.flag_name) then
|
366
|
+
save_flag(flagger_flag.flag_name)
|
367
|
+
end
|
368
|
+
return_value = flag&.eligible?(entity)
|
369
|
+
|
370
|
+
if !return_value then
|
371
|
+
return return_value
|
283
372
|
end
|
373
|
+
|
374
|
+
exposure = {
|
375
|
+
flag: flagger_flag.flag_name,
|
376
|
+
type: entity.type,
|
377
|
+
id: entity.id,
|
378
|
+
treatment: return_value[:treatment].codename,
|
379
|
+
method_called: 'is_eligible',
|
380
|
+
eligible: return_value[:eligible]
|
381
|
+
}
|
382
|
+
|
383
|
+
return_value = return_value[:eligible]
|
384
|
+
|
385
|
+
save_exposure(exposure)
|
386
|
+
|
387
|
+
stat.stop()
|
388
|
+
save_stat(stat)
|
389
|
+
|
390
|
+
return_value
|
391
|
+
end
|
392
|
+
|
393
|
+
def enabled?(flagger_flag, entity_json)
|
394
|
+
stat = FlaggerUtils::Stat.new('duration__is_enabled')
|
395
|
+
stat.start()
|
396
|
+
|
397
|
+
entity = identify_entity(entity_json)
|
398
|
+
flag = @gating_info&.flag(flagger_flag.flag_name)
|
399
|
+
if flag.nil? && !@ingested_flags.include?(flagger_flag.flag_name) then
|
400
|
+
save_flag(flagger_flag.flag_name)
|
401
|
+
end
|
402
|
+
return_value = flag&.enabled?(entity)
|
403
|
+
|
404
|
+
if !return_value then
|
405
|
+
return return_value
|
406
|
+
end
|
407
|
+
|
408
|
+
exposure = {
|
409
|
+
flag: flagger_flag.flag_name,
|
410
|
+
type: entity.type,
|
411
|
+
id: entity.id,
|
412
|
+
treatment: return_value[:treatment].codename,
|
413
|
+
method_called: 'is_enabled',
|
414
|
+
eligible: return_value[:eligible]
|
415
|
+
}
|
416
|
+
|
417
|
+
return_value = !return_value[:treatment].is_off_treatment
|
418
|
+
|
419
|
+
save_exposure(exposure)
|
420
|
+
|
421
|
+
stat.stop()
|
422
|
+
save_stat(stat)
|
423
|
+
|
424
|
+
return_value
|
284
425
|
end
|
285
426
|
|
286
427
|
def publish(entities)
|
data/lib/flagger/models.rb
CHANGED
@@ -152,14 +152,26 @@ module FlaggerModels
|
|
152
152
|
SCHEMA = Dry::Validation.Schema do
|
153
153
|
optional(:@ingestion_interval) { int? }
|
154
154
|
optional(:@ingestion_max_items) { int? }
|
155
|
+
optional(:@should_ingest_entities) { bool? }
|
156
|
+
optional(:@should_ingest_stats) { bool? }
|
157
|
+
optional(:@should_ingest_exposures) { bool? }
|
158
|
+
optional(:@should_ingest_flags) { bool? }
|
155
159
|
end
|
156
160
|
|
157
161
|
attr_reader :ingestion_interval
|
158
162
|
attr_reader :ingestion_max_items
|
163
|
+
attr_reader :should_ingest_entities
|
164
|
+
attr_reader :should_ingest_stats
|
165
|
+
attr_reader :should_ingest_exposures
|
166
|
+
attr_reader :should_ingest_flags
|
159
167
|
|
160
168
|
def initialize(json)
|
161
169
|
@ingestion_interval = json['SDK_INGESTION_INTERVAL']
|
162
170
|
@ingestion_max_items = json['SDK_INGESTION_MAX_ITEMS']
|
171
|
+
@should_ingest_entities = json['SDK_SHOULD_INGEST_OBJECTS']
|
172
|
+
@should_ingest_stats = json['SDK_SHOULD_INGEST_STATS']
|
173
|
+
@should_ingest_exposures = json['SDK_SHOULD_INGEST_EXPOSURES']
|
174
|
+
@should_ingest_flags = json['SDK_SHOULD_INGEST_FLAGS']
|
163
175
|
|
164
176
|
validate
|
165
177
|
end
|
@@ -232,7 +244,7 @@ module FlaggerModels
|
|
232
244
|
if @flag_type == 'uncategorized' or !entity then
|
233
245
|
nil
|
234
246
|
else
|
235
|
-
resolved_allocation(@env_hash_key, entity)
|
247
|
+
resolved_allocation(@env_hash_key, entity)
|
236
248
|
end
|
237
249
|
end
|
238
250
|
|
@@ -240,7 +252,7 @@ module FlaggerModels
|
|
240
252
|
if @flag_type == 'uncategorized' or !entity then
|
241
253
|
nil
|
242
254
|
else
|
243
|
-
resolved_allocation(@env_hash_key, entity)
|
255
|
+
resolved_allocation(@env_hash_key, entity)
|
244
256
|
end
|
245
257
|
end
|
246
258
|
|
@@ -248,7 +260,7 @@ module FlaggerModels
|
|
248
260
|
if @flag_type == 'uncategorized' or !entity then
|
249
261
|
false
|
250
262
|
else
|
251
|
-
resolved_allocation(@env_hash_key, entity)
|
263
|
+
resolved_allocation(@env_hash_key, entity)
|
252
264
|
end
|
253
265
|
end
|
254
266
|
|
@@ -256,7 +268,7 @@ module FlaggerModels
|
|
256
268
|
if @flag_type == 'uncategorized' or !entity then
|
257
269
|
false
|
258
270
|
else
|
259
|
-
|
271
|
+
resolved_allocation(@env_hash_key, entity)
|
260
272
|
end
|
261
273
|
end
|
262
274
|
|
@@ -621,7 +633,7 @@ module FlaggerModels
|
|
621
633
|
required(:@is_control) { bool? }
|
622
634
|
required(:@codename) { str? }
|
623
635
|
required(:@is_off_treatment) { bool? }
|
624
|
-
optional(:@payload) { str? }
|
636
|
+
optional(:@payload) { str? | type?(Numeric) | bool? | array? | type?(Hash) }
|
625
637
|
end
|
626
638
|
|
627
639
|
attr_reader :treatment_id
|
data/lib/flagger/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flagger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Airship Dev Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10-
|
11
|
+
date: 2018-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|