Skip to content

Commit bd1473c

Browse files
authored
Merge pull request #447 from splitio/development
[8.1.1] Development into master
2 parents 3cb0d68 + 0e3f3a7 commit bd1473c

17 files changed

Lines changed: 64 additions & 60 deletions

File tree

CHANGES.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
CHANGES
22

3+
8.1.1 (Mar 17, 2023)
4+
- Added retries with backoff when the sdk tries to connect to the Streaming service and it is not available.
5+
- Updated the way that the sdk write mtks in redis.
6+
- Fixed calculation of timeUntilReady in telemetry.
7+
38
8.1.0 (Oct 5, 2022)
49
- Added a new impressions mode for the SDK called NONE , to be used in factory when there is no desire to capture impressions on an SDK factory to feed Split's analytics engine. Running NONE mode, the SDK will only capture unique keys evaluated for a particular feature flag instead of full blown impressions.
510

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright © 2022 Split Software, Inc.
1+
Copyright © 2023 Split Software, Inc.
22

33
Licensed under the Apache License, Version 2.0 (the "License");
44
you may not use this file except in compliance with the License.

lib/splitclient-rb/cache/adapters/redis_adapter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def bool(key)
9999
alias find_sets_by_prefix find_strings_by_prefix
100100

101101
def add_to_set(key, val)
102-
@redis.sadd(key, val)
102+
@redis.sadd?(key, val)
103103
end
104104

105105
def delete_from_set(key, val)

lib/splitclient-rb/cache/senders/impressions_adapter/redis_sender.rb

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,11 @@ def initialize(config)
1212
end
1313

1414
def record_uniques_key(uniques)
15-
return if uniques.nil? || uniques == {}
15+
return if uniques.nil? || uniques.empty?
1616

17-
formatted = uniques_formatter(uniques).to_json
17+
size = @adapter.add_to_queue(unique_keys_key, uniques_formatter(uniques))
1818

19-
unless formatted.nil?
20-
size = @adapter.add_to_queue(unique_keys_key, formatted)
21-
@adapter.expire(unique_keys_key, EXPIRE_SECONDS) if formatted.size == size
22-
end
19+
@adapter.expire(unique_keys_key, EXPIRE_SECONDS) if uniques.length == size
2320
rescue StandardError => e
2421
@config.log_found_exception(__method__.to_s, e)
2522
end
@@ -47,29 +44,24 @@ def expire_impressions_count_key(impressions_count, pipeline_result)
4744
@adapter.expire(impressions_count_key, EXPIRE_SECONDS) if impressions_count.size == hlen && (pipeline_result.sum - hlen) == total_count
4845
end
4946

50-
def impressions_count_key
51-
"#{@config.redis_namespace}.impressions.count"
52-
end
53-
54-
def unique_keys_key
55-
"#{@config.redis_namespace}.uniquekeys"
56-
end
57-
5847
def uniques_formatter(uniques)
59-
return if uniques.nil? || uniques.empty?
60-
6148
to_return = []
6249
uniques.each do |key, value|
6350
to_return << {
6451
f: key,
65-
k: value.to_a
66-
}
52+
ks: value.to_a
53+
}.to_json
6754
end
6855

6956
to_return
70-
rescue StandardError => e
71-
@config.log_found_exception(__method__.to_s, e)
72-
nil
57+
end
58+
59+
def impressions_count_key
60+
"#{@config.redis_namespace}.impressions.count"
61+
end
62+
63+
def unique_keys_key
64+
"#{@config.redis_namespace}.uniquekeys"
7365
end
7466
end
7567
end

lib/splitclient-rb/engine/auth_api_client.rb

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,7 @@ def process_error(response)
5959

6060
def process_success(response, start)
6161
@config.logger.debug("Success connection to: #{@config.auth_service_url}") if @config.debug_enabled
62-
63-
bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0)
64-
@telemetry_runtime_producer.record_sync_latency(Telemetry::Domain::Constants::TOKEN_SYNC, bucket)
65-
timestamp = (Time.now.to_f * 1000.0).to_i
66-
@telemetry_runtime_producer.record_successful_sync(Telemetry::Domain::Constants::TOKEN_SYNC, timestamp)
62+
record_telemetry(start)
6763

6864
body_json = JSON.parse(response.body, symbolize_names: true)
6965
push_enabled = body_json[:pushEnabled]
@@ -77,7 +73,7 @@ def process_success(response, start)
7773
@telemetry_runtime_producer.record_token_refreshes
7874
end
7975

80-
{ push_enabled: push_enabled, token: token, channels: channels, exp: exp, retry: false }
76+
{ push_enabled: push_enabled, token: token, channels: channels, exp: exp, retry: true }
8177
end
8278

8379
def control_channels(channels_string)
@@ -88,6 +84,13 @@ def control_channels(channels_string)
8884

8985
channels_string.gsub(control_sec, "#{prefix}#{control_sec}")
9086
end
87+
88+
def record_telemetry(start)
89+
bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0)
90+
@telemetry_runtime_producer.record_sync_latency(Telemetry::Domain::Constants::TOKEN_SYNC, bucket)
91+
timestamp = (Time.now.to_f * 1000.0).to_i
92+
@telemetry_runtime_producer.record_successful_sync(Telemetry::Domain::Constants::TOKEN_SYNC, timestamp)
93+
end
9194
end
9295
end
9396
end

lib/splitclient-rb/engine/back_off.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module SplitIoClient
44
module Engine
5-
BACKOFF_MAX_ALLOWED = 1.8
5+
BACKOFF_MAX_ALLOWED = 1800
66
class BackOff
77
def initialize(back_off_base, attempt = 0, max_allowed = BACKOFF_MAX_ALLOWED)
88
@attempt = attempt

lib/splitclient-rb/engine/push_manager.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ def initialize(config, sse_handler, api_key, telemetry_runtime_producer)
1414

1515
def start_sse
1616
response = @auth_api_client.authenticate(@api_key)
17-
1817
@config.logger.debug("Auth service response push_enabled: #{response[:push_enabled]}") if @config.debug_enabled
1918

2019
if response[:push_enabled] && @sse_handler.start(response[:token], response[:channels])
@@ -26,7 +25,6 @@ def start_sse
2625
end
2726

2827
stop_sse
29-
3028
schedule_next_token_refresh(@back_off.interval) if response[:retry]
3129
false
3230
rescue StandardError => e
@@ -35,7 +33,8 @@ def start_sse
3533

3634
def stop_sse
3735
@sse_handler.stop
38-
SplitIoClient::Helpers::ThreadHelper.stop(:schedule_next_token_refresh, @config)
36+
rescue StandardError => e
37+
@config.logger.error(e.inspect)
3938
end
4039

4140
private

lib/splitclient-rb/engine/synchronizer.rb

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ class Synchronizer
66
include SplitIoClient::Cache::Fetchers
77
include SplitIoClient::Cache::Senders
88

9-
ON_DEMAND_FETCH_BACKOFF_BASE_SECONDS = 10
10-
ON_DEMAND_FETCH_BACKOFF_MAX_WAIT_SECONDS = 60
119
ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES = 10
1210

1311
def initialize(
@@ -27,6 +25,9 @@ def initialize(
2725
@telemetry_synchronizer = params[:telemetry_synchronizer]
2826
@impressions_sender_adapter = params[:impressions_sender_adapter]
2927
@unique_keys_tracker = params[:unique_keys_tracker]
28+
29+
@splits_sync_backoff = Engine::BackOff.new(10, 0, 60)
30+
@segments_sync_backoff = Engine::BackOff.new(10, 0, 60)
3031
end
3132

3233
def sync_all(asynchronous = true)
@@ -140,7 +141,7 @@ def fetch_segment(name, target_change_number)
140141

141142
def attempt_segment_sync(name, target_cn, fetch_options, max_retries, retry_delay_seconds, with_backoff)
142143
remaining_attempts = max_retries
143-
backoff = Engine::BackOff.new(ON_DEMAND_FETCH_BACKOFF_BASE_SECONDS, 0, ON_DEMAND_FETCH_BACKOFF_MAX_WAIT_SECONDS) if with_backoff
144+
@segments_sync_backoff.reset
144145

145146
loop do
146147
remaining_attempts -= 1
@@ -150,14 +151,14 @@ def attempt_segment_sync(name, target_cn, fetch_options, max_retries, retry_dela
150151
return sync_result(true, remaining_attempts) if target_cn <= @segments_repository.get_change_number(name).to_i
151152
return sync_result(false, remaining_attempts) if remaining_attempts <= 0
152153

153-
delay = with_backoff ? backoff.interval : retry_delay_seconds
154+
delay = with_backoff ? @segments_sync_backoff.interval : retry_delay_seconds
154155
sleep(delay)
155156
end
156157
end
157158

158159
def attempt_splits_sync(target_cn, fetch_options, max_retries, retry_delay_seconds, with_backoff)
159160
remaining_attempts = max_retries
160-
backoff = Engine::BackOff.new(ON_DEMAND_FETCH_BACKOFF_BASE_SECONDS, 0, ON_DEMAND_FETCH_BACKOFF_MAX_WAIT_SECONDS) if with_backoff
161+
@splits_sync_backoff.reset
161162

162163
loop do
163164
remaining_attempts -= 1
@@ -167,7 +168,7 @@ def attempt_splits_sync(target_cn, fetch_options, max_retries, retry_delay_secon
167168
return sync_result(true, remaining_attempts, result[:segment_names]) if target_cn <= @splits_repository.get_change_number
168169
return sync_result(false, remaining_attempts, result[:segment_names]) if remaining_attempts <= 0
169170

170-
delay = with_backoff ? backoff.interval : retry_delay_seconds
171+
delay = with_backoff ? @splits_sync_backoff.interval : retry_delay_seconds
171172
sleep(delay)
172173
end
173174
end

lib/splitclient-rb/split_config.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def initialize(opts = {})
117117

118118
@counter_refresh_rate = SplitConfig.default_counter_refresh_rate(@cache_adapter)
119119

120-
@sdk_start_time = Time.now
120+
@sdk_start_time = Time.now.to_f
121121

122122
@on_demand_fetch_retry_delay_seconds = SplitConfig.default_on_demand_fetch_retry_delay_seconds
123123
@on_demand_fetch_max_retries = SplitConfig.default_on_demand_fetch_max_retries

lib/splitclient-rb/telemetry/domain/structs.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ module Telemetry
1313
# s: sdkUrl, e: eventsUrl, a: authUrl, st: streamUrl, t: telemetryUrl
1414
UrlOverrides = Struct.new(:s, :e, :a, :st, :t)
1515

16-
# om: operationMode, se: streamingEnabled, st: storage, rr: refreshRate, uo: urlOverrides, iq: impressionsQueueSize,
17-
# eq: eventsQueueSize, im: impressionsMode, il: impressionListenerEnabled, hp: httpProxyDetected, af: activeFactories,
18-
# rf: redundantActiveFactories, tr: timeUntilSdkReady, bt: burTimeouts, nr: sdkNotReadyUsage, t: tags, i: integrations
16+
# om: operationMode, st: storage, af: activeFactories, rf: redundantActiveFactories, t: tags, se: streamingEnabled,
17+
# rr: refreshRate, uo: urlOverrides, iq: impressionsQueueSize, eq: eventsQueueSize, im: impressionsMode,
18+
# il: impressionListenerEnabled, hp: httpProxyDetected, tr: timeUntilSdkReady, bt: burTimeouts,
19+
# nr: sdkNotReadyUsage, i: integrations
1920
ConfigInit = Struct.new(:om, :st, :af, :rf, :t, :se, :rr, :uo, :iq, :eq, :im, :il, :hp, :tr, :bt, :nr, :i)
2021

2122
# ls: lastSynchronization, ml: clientMethodLatencies, me: clientMethodExceptions, he: httpErros, hl: httpLatencies,

0 commit comments

Comments
 (0)