-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathsegments.rb
More file actions
87 lines (68 loc) · 3.58 KB
/
segments.rb
File metadata and controls
87 lines (68 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# frozen_string_literal: true
module SplitIoClient
module Api
# Retrieves segment changes from the Split Backend
class Segments < Client
def initialize(api_key, segments_repository, config, telemetry_runtime_producer)
super(config)
@api_key = api_key
@segments_repository = segments_repository
@telemetry_runtime_producer = telemetry_runtime_producer
end
def fetch_segments_by_names(names, fetch_options = { cache_control_headers: false, till: nil })
return if names.nil? || names.empty?
names.each do |name|
since = @segments_repository.get_change_number(name)
loop do
segment = fetch_segment_changes(name, since, fetch_options)
if segment.nil?
@segments_repository.remove_registered_segment(name)
break
end
@segments_repository.add_to_segment(segment)
@config.split_logger.log_if_debug("Segment #{name} fetched before: #{since}, \
till: #{@segments_repository.get_change_number(name)}")
break if since.to_i >= @segments_repository.get_change_number(name).to_i
since = @segments_repository.get_change_number(name)
end
end
end
private
def fetch_segment_changes(name, since, fetch_options = { cache_control_headers: false, till: nil })
start = Time.now
params = { since: since }
params[:till] = fetch_options[:till] unless fetch_options[:till].nil?
response = get_api("#{@config.base_uri}/segmentChanges/#{name}", @api_key, params, fetch_options[:cache_control_headers])
if response.success?
segment = JSON.parse(response.body, symbolize_names: true)
@segments_repository.set_change_number(name, segment[:till])
@config.split_logger.log_if_debug("\'#{segment[:name]}\' segment retrieved.")
unless segment[:added].empty?
@config.split_logger.log_if_debug("\'#{segment[:name]}\' #{segment[:added].size} added keys")
end
unless segment[:removed].empty?
@config.split_logger.log_if_debug("\'#{segment[:name]}\' #{segment[:removed].size} removed keys")
end
@config.split_logger.log_if_transport("Segment changes response: #{segment.to_s}")
bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0)
@telemetry_runtime_producer.record_sync_latency(Telemetry::Domain::Constants::SEGMENT_SYNC, bucket)
@telemetry_runtime_producer.record_successful_sync(Telemetry::Domain::Constants::SEGMENT_SYNC, (Time.now.to_f * 1000.0).to_i)
segment
elsif response.status == 403
@telemetry_runtime_producer.record_sync_error(Telemetry::Domain::Constants::SEGMENT_SYNC, response.status)
@config.logger.error('Factory Instantiation: You passed a browser type api_key, ' \
'please grab an api key from the Split console that is of type sdk')
@config.valid_mode = false
elsif response.status == 404
@config.logger.warn("Segment '#{name}' not found (404). The segment may have been removed from the Split environment.")
nil
else
@telemetry_runtime_producer.record_sync_error(Telemetry::Domain::Constants::SEGMENT_SYNC, response.status)
@config.logger.error("Unexpected status code while fetching segments: #{response.status}." \
"Since #{since} - Check your API key and base URI")
raise 'Split SDK failed to connect to backend to fetch segments'
end
end
end
end
end