splitclient-rb 7.2.3.pre.rc2-java → 7.3.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -0
  3. data/CHANGES.txt +10 -0
  4. data/LICENSE +1 -1
  5. data/README.md +1 -1
  6. data/lib/splitclient-rb.rb +24 -9
  7. data/lib/splitclient-rb/cache/adapters/redis_adapter.rb +4 -0
  8. data/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb +13 -9
  9. data/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +8 -7
  10. data/lib/splitclient-rb/cache/repositories/events/memory_repository.rb +6 -3
  11. data/lib/splitclient-rb/cache/repositories/events_repository.rb +4 -3
  12. data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +8 -0
  13. data/lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb +2 -0
  14. data/lib/splitclient-rb/cache/repositories/repository.rb +0 -4
  15. data/lib/splitclient-rb/cache/repositories/segments_repository.rb +20 -0
  16. data/lib/splitclient-rb/cache/repositories/splits_repository.rb +4 -0
  17. data/lib/splitclient-rb/cache/senders/localhost_repo_cleaner.rb +1 -3
  18. data/lib/splitclient-rb/cache/stores/sdk_blocker.rb +9 -0
  19. data/lib/splitclient-rb/clients/split_client.rb +59 -25
  20. data/lib/splitclient-rb/engine/api/client.rb +3 -2
  21. data/lib/splitclient-rb/engine/api/events.rb +10 -1
  22. data/lib/splitclient-rb/engine/api/impressions.rb +19 -2
  23. data/lib/splitclient-rb/engine/api/segments.rb +20 -18
  24. data/lib/splitclient-rb/engine/api/splits.rb +10 -10
  25. data/lib/splitclient-rb/engine/api/telemetry_api.rb +39 -0
  26. data/lib/splitclient-rb/engine/auth_api_client.rb +21 -8
  27. data/lib/splitclient-rb/engine/common/impressions_manager.rb +27 -3
  28. data/lib/splitclient-rb/engine/metrics/binary_search_latency_tracker.rb +3 -65
  29. data/lib/splitclient-rb/engine/push_manager.rb +10 -2
  30. data/lib/splitclient-rb/engine/sync_manager.rb +42 -20
  31. data/lib/splitclient-rb/engine/synchronizer.rb +13 -12
  32. data/lib/splitclient-rb/split_config.rb +46 -21
  33. data/lib/splitclient-rb/split_factory.rb +31 -13
  34. data/lib/splitclient-rb/split_factory_registry.rb +12 -0
  35. data/lib/splitclient-rb/sse/event_source/client.rb +10 -1
  36. data/lib/splitclient-rb/sse/notification_manager_keeper.rb +17 -3
  37. data/lib/splitclient-rb/sse/sse_handler.rb +10 -6
  38. data/lib/splitclient-rb/telemetry/domain/constants.rb +42 -0
  39. data/lib/splitclient-rb/telemetry/domain/structs.rb +31 -0
  40. data/lib/splitclient-rb/telemetry/evaluation_consumer.rb +14 -0
  41. data/lib/splitclient-rb/telemetry/evaluation_producer.rb +21 -0
  42. data/lib/splitclient-rb/telemetry/init_consumer.rb +14 -0
  43. data/lib/splitclient-rb/telemetry/init_producer.rb +19 -0
  44. data/lib/splitclient-rb/telemetry/memory/memory_evaluation_consumer.rb +32 -0
  45. data/lib/splitclient-rb/telemetry/memory/memory_evaluation_producer.rb +24 -0
  46. data/lib/splitclient-rb/telemetry/memory/memory_init_consumer.rb +28 -0
  47. data/lib/splitclient-rb/telemetry/memory/memory_init_producer.rb +34 -0
  48. data/lib/splitclient-rb/telemetry/memory/memory_runtime_consumer.rb +112 -0
  49. data/lib/splitclient-rb/telemetry/memory/memory_runtime_producer.rb +81 -0
  50. data/lib/splitclient-rb/telemetry/memory/memory_synchronizer.rb +192 -0
  51. data/lib/splitclient-rb/telemetry/redis/redis_evaluation_producer.rb +38 -0
  52. data/lib/splitclient-rb/telemetry/redis/redis_init_producer.rb +37 -0
  53. data/lib/splitclient-rb/telemetry/redis/redis_synchronizer.rb +28 -0
  54. data/lib/splitclient-rb/telemetry/runtime_consumer.rb +24 -0
  55. data/lib/splitclient-rb/telemetry/runtime_producer.rb +24 -0
  56. data/lib/splitclient-rb/telemetry/storages/memory.rb +139 -0
  57. data/lib/splitclient-rb/telemetry/sync_task.rb +38 -0
  58. data/lib/splitclient-rb/telemetry/synchronizer.rb +29 -0
  59. data/lib/splitclient-rb/version.rb +1 -1
  60. metadata +26 -11
  61. data/lib/splitclient-rb/cache/repositories/metrics/memory_repository.rb +0 -163
  62. data/lib/splitclient-rb/cache/repositories/metrics/redis_repository.rb +0 -131
  63. data/lib/splitclient-rb/cache/repositories/metrics_repository.rb +0 -23
  64. data/lib/splitclient-rb/cache/senders/metrics_sender.rb +0 -55
  65. data/lib/splitclient-rb/engine/api/metrics.rb +0 -61
  66. data/lib/splitclient-rb/engine/metrics/metrics.rb +0 -80
  67. data/lib/splitclient-rb/redis_metrics_fixer.rb +0 -36
@@ -6,22 +6,21 @@ require 'cgi'
6
6
  module SplitIoClient
7
7
  module Engine
8
8
  class AuthApiClient
9
- def initialize(config)
9
+ def initialize(config, telemetry_runtime_producer)
10
10
  @config = config
11
11
  @api_client = SplitIoClient::Api::Client.new(@config)
12
+ @telemetry_runtime_producer = telemetry_runtime_producer
12
13
  end
13
14
 
14
15
  def authenticate(api_key)
16
+ start = Time.now
15
17
  response = @api_client.get_api(@config.auth_service_url, api_key)
16
18
 
17
- return process_success(response) if response.success?
19
+ return process_success(response, start) if response.success?
18
20
 
19
- if response.status >= 400 && response.status < 500
20
- @config.logger.debug("Error connecting to: #{@config.auth_service_url}. Response status: #{response.status}")
21
-
22
- return { push_enabled: false, retry: false }
23
- end
21
+ return process_error(response) if response.status >= 400 && response.status < 500
24
22
 
23
+ @telemetry_runtime_producer.record_sync_error(Telemetry::Domain::Constants::TOKEN_SYNC, response.status.to_i)
25
24
  @config.logger.debug("Error connecting to: #{@config.auth_service_url}. Response status: #{response.status}")
26
25
  { push_enabled: false, retry: true }
27
26
  rescue StandardError => e
@@ -51,9 +50,21 @@ module SplitIoClient
51
50
  JWT.decode token, nil, false
52
51
  end
53
52
 
54
- def process_success(response)
53
+ def process_error(response)
54
+ @config.logger.debug("Error connecting to: #{@config.auth_service_url}. Response status: #{response.status}")
55
+ @telemetry_runtime_producer.record_auth_rejections if response.status == 401
56
+
57
+ { push_enabled: false, retry: false }
58
+ end
59
+
60
+ def process_success(response, start)
55
61
  @config.logger.debug("Success connection to: #{@config.auth_service_url}") if @config.debug_enabled
56
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)
67
+
57
68
  body_json = JSON.parse(response.body, symbolize_names: true)
58
69
  push_enabled = body_json[:pushEnabled]
59
70
  token = body_json[:token]
@@ -62,6 +73,8 @@ module SplitIoClient
62
73
  decoded_token = decode_token(token)
63
74
  channels = channels(decoded_token)
64
75
  exp = expiration(decoded_token)
76
+
77
+ @telemetry_runtime_producer.record_token_refreshes
65
78
  end
66
79
 
67
80
  { push_enabled: push_enabled, token: token, channels: channels, exp: exp, retry: false }
@@ -4,11 +4,12 @@ module SplitIoClient
4
4
  module Engine
5
5
  module Common
6
6
  class ImpressionManager
7
- def initialize(config, impressions_repository, impression_counter)
7
+ def initialize(config, impressions_repository, impression_counter, telemetry_runtime_producer)
8
8
  @config = config
9
9
  @impressions_repository = impressions_repository
10
10
  @impression_counter = impression_counter
11
11
  @impression_observer = SplitIoClient::Observers::ImpressionObserver.new
12
+ @telemetry_runtime_producer = telemetry_runtime_producer
12
13
  end
13
14
 
14
15
  # added param time for test
@@ -29,18 +30,41 @@ module SplitIoClient
29
30
 
30
31
  impression_router.add_bulk(impressions)
31
32
 
33
+ dropped = 0
34
+ queued = 0
35
+ dedupe = 0
36
+
32
37
  if optimized? && !redis?
33
38
  optimized_impressions = impressions.select { |imp| should_queue_impression?(imp[:i]) }
34
- @impressions_repository.add_bulk(optimized_impressions)
39
+
40
+ unless optimized_impressions.empty?
41
+ dropped = @impressions_repository.add_bulk(optimized_impressions)
42
+ dedupe = impressions.length - optimized_impressions.length
43
+ queued = optimized_impressions.length - dropped
44
+ end
35
45
  else
36
- @impressions_repository.add_bulk(impressions)
46
+ dropped = @impressions_repository.add_bulk(impressions)
47
+ queued = impressions.length - dropped
37
48
  end
49
+
50
+ record_stats(queued, dropped, dedupe)
38
51
  rescue StandardError => error
39
52
  @config.log_found_exception(__method__.to_s, error)
40
53
  end
41
54
 
42
55
  private
43
56
 
57
+ def record_stats(queued, dropped, dedupe)
58
+ return if redis?
59
+
60
+ imp_queued = Telemetry::Domain::Constants::IMPRESSIONS_QUEUED
61
+ imp_dropped = Telemetry::Domain::Constants::IMPRESSIONS_DROPPED
62
+ imp_dedupe = Telemetry::Domain::Constants::IMPRESSIONS_DEDUPE
63
+ @telemetry_runtime_producer.record_impressions_stats(imp_queued, queued) unless queued.zero?
64
+ @telemetry_runtime_producer.record_impressions_stats(imp_dropped, dropped) unless dropped.zero?
65
+ @telemetry_runtime_producer.record_impressions_stats(imp_dedupe, dedupe) unless dedupe.zero?
66
+ end
67
+
44
68
  # added param time for test
45
69
  def impression_data(matching_key, bucketing_key, split_name, treatment, time = nil)
46
70
  {
@@ -42,75 +42,13 @@ module SplitIoClient
42
42
 
43
43
  MAX_LATENCY = 7481828
44
44
 
45
- attr_accessor :latencies
46
-
47
- def initialize
48
- @latencies = Array.new(BUCKETS.length, 0)
49
- end
50
-
51
- #
52
- # Increment the internal counter for the bucket this latency falls into.
53
- # @param millis
54
- #
55
- def add_latency_millis(millis, return_index = false)
56
- index = find_bucket_index(millis * 1000)
57
-
58
- return index if return_index
59
-
60
- @latencies[index] += 1
61
- @latencies
62
- end
63
-
64
- # Increment the internal counter for the bucket this latency falls into.
65
- # @param micros
66
- def add_latency_micros(micros, return_index = false)
67
- index = find_bucket_index(micros)
68
-
69
- return index if return_index
70
-
71
- @latencies[index] += 1
72
- @latencies
73
- end
74
-
75
- # Returns the list of latencies buckets as an array.
76
- #
77
- #
78
- # @return the list of latencies buckets as an array.
79
- def get_latencies
80
- @latencies
81
- end
82
-
83
- def get_latency(index)
84
- return @latencies[index]
85
- end
86
-
87
- def clear
88
- @latencies = Array.new(BUCKETS.length, 0)
89
- end
90
-
91
- #
92
- # Returns the counts in the bucket this latency falls into.
93
- # The latencies will not be updated.
94
- # @param latency
95
- # @return the bucket content for the latency.
96
- #
97
- def get_bucket_for_latency_millis(latency)
98
- return @latencies[find_bucket_index(latency * 1000)]
99
- end
100
-
101
- #
102
- # Returns the counts in the bucket this latency falls into.
103
- # The latencies will not be updated.
104
- # @param latency
105
- # @return the bucket content for the latency.
106
- #
107
- def get_bucket_for_latency_micros(latency)
108
- return @latencies[find_bucket_index(latency)]
45
+ def self.get_bucket(latency)
46
+ return find_bucket_index(latency * 1000)
109
47
  end
110
48
 
111
49
  private
112
50
 
113
- def find_bucket_index(micros)
51
+ def self.find_bucket_index(micros)
114
52
  if (micros > MAX_LATENCY) then
115
53
  return BUCKETS.length - 1
116
54
  end
@@ -3,12 +3,13 @@
3
3
  module SplitIoClient
4
4
  module Engine
5
5
  class PushManager
6
- def initialize(config, sse_handler, api_key)
6
+ def initialize(config, sse_handler, api_key, telemetry_runtime_producer)
7
7
  @config = config
8
8
  @sse_handler = sse_handler
9
- @auth_api_client = AuthApiClient.new(@config)
9
+ @auth_api_client = AuthApiClient.new(@config, telemetry_runtime_producer)
10
10
  @api_key = api_key
11
11
  @back_off = SplitIoClient::SSE::EventSource::BackOff.new(@config.auth_retry_back_off_base, 1)
12
+ @telemetry_runtime_producer = telemetry_runtime_producer
12
13
  end
13
14
 
14
15
  def start_sse
@@ -19,6 +20,8 @@ module SplitIoClient
19
20
  if response[:push_enabled] && @sse_handler.start(response[:token], response[:channels])
20
21
  schedule_next_token_refresh(response[:exp])
21
22
  @back_off.reset
23
+ record_telemetry(response[:exp])
24
+
22
25
  return true
23
26
  end
24
27
 
@@ -51,6 +54,11 @@ module SplitIoClient
51
54
  end
52
55
  end
53
56
  end
57
+
58
+ def record_telemetry(time)
59
+ data = (Time.now.to_f * 1000.0).to_i + (time * 1000.0).to_i
60
+ @telemetry_runtime_producer.record_streaming_event(Telemetry::Domain::Constants::TOKEN_REFRESH, data)
61
+ end
54
62
  end
55
63
  end
56
64
  end
@@ -3,29 +3,38 @@
3
3
  module SplitIoClient
4
4
  module Engine
5
5
  class SyncManager
6
+ SYNC_MODE_STREAMING = 0
7
+ SYNC_MODE_POLLING = 1
8
+
6
9
  def initialize(
7
10
  repositories,
8
11
  api_key,
9
12
  config,
10
- synchronizer
13
+ synchronizer,
14
+ telemetry_runtime_producer,
15
+ sdk_blocker,
16
+ telemetry_synchronizer
11
17
  )
12
18
  @synchronizer = synchronizer
13
- notification_manager_keeper = SplitIoClient::SSE::NotificationManagerKeeper.new(config) do |manager|
19
+ notification_manager_keeper = SSE::NotificationManagerKeeper.new(config, telemetry_runtime_producer) do |manager|
14
20
  manager.on_action { |action| process_action(action) }
15
21
  end
16
- @sse_handler = SplitIoClient::SSE::SSEHandler.new(
17
- config,
22
+ @sse_handler = SSE::SSEHandler.new(
23
+ { config: config, api_key: api_key },
18
24
  @synchronizer,
19
- repositories[:splits],
20
- repositories[:segments],
21
- notification_manager_keeper
25
+ repositories,
26
+ notification_manager_keeper,
27
+ telemetry_runtime_producer
22
28
  ) do |handler|
23
29
  handler.on_action { |action| process_action(action) }
24
30
  end
25
31
 
26
- @push_manager = PushManager.new(config, @sse_handler, api_key)
32
+ @push_manager = PushManager.new(config, @sse_handler, api_key, telemetry_runtime_producer)
27
33
  @sse_connected = Concurrent::AtomicBoolean.new(false)
28
34
  @config = config
35
+ @telemetry_runtime_producer = telemetry_runtime_producer
36
+ @sdk_blocker = sdk_blocker
37
+ @telemetry_synchronizer = telemetry_synchronizer
29
38
  end
30
39
 
31
40
  def start
@@ -35,6 +44,8 @@ module SplitIoClient
35
44
  elsif @config.standalone?
36
45
  start_poll
37
46
  end
47
+
48
+ synchronize_telemetry_config
38
49
  end
39
50
 
40
51
  private
@@ -42,7 +53,7 @@ module SplitIoClient
42
53
  # Starts tasks if stream is enabled.
43
54
  def start_stream
44
55
  @config.logger.debug('Starting push mode ...')
45
- sync_all_thread
56
+ @synchronizer.sync_all
46
57
  @synchronizer.start_periodic_data_recording
47
58
 
48
59
  start_sse_connection_thread
@@ -52,21 +63,11 @@ module SplitIoClient
52
63
  @config.logger.debug('Starting polling mode ...')
53
64
  @synchronizer.start_periodic_fetch
54
65
  @synchronizer.start_periodic_data_recording
66
+ record_telemetry(Telemetry::Domain::Constants::SYNC_MODE, SYNC_MODE_POLLING)
55
67
  rescue StandardError => e
56
68
  @config.logger.error("start_poll error : #{e.inspect}")
57
69
  end
58
70
 
59
- # Starts thread which fetch splits and segments once and trigger task to periodic data recording.
60
- def sync_all_thread
61
- @config.threads[:sync_manager_start_stream] = Thread.new do
62
- begin
63
- @synchronizer.sync_all
64
- rescue StandardError => e
65
- @config.logger.error("sync_all_thread error : #{e.inspect}")
66
- end
67
- end
68
- end
69
-
70
71
  # Starts thread which connect to sse and after that fetch splits and segments once.
71
72
  def start_sse_connection_thread
72
73
  @config.threads[:sync_manager_start_sse] = Thread.new do
@@ -108,17 +109,20 @@ module SplitIoClient
108
109
  @synchronizer.stop_periodic_fetch
109
110
  @synchronizer.sync_all
110
111
  @sse_handler.start_workers
112
+ record_telemetry(Telemetry::Domain::Constants::SYNC_MODE, SYNC_MODE_STREAMING)
111
113
  end
112
114
 
113
115
  def process_subsystem_down
114
116
  @sse_handler.stop_workers
115
117
  @synchronizer.start_periodic_fetch
118
+ record_telemetry(Telemetry::Domain::Constants::SYNC_MODE, SYNC_MODE_POLLING)
116
119
  end
117
120
 
118
121
  def process_push_shutdown
119
122
  @push_manager.stop_sse
120
123
  @sse_handler.stop_workers
121
124
  @synchronizer.start_periodic_fetch
125
+ record_telemetry(Telemetry::Domain::Constants::SYNC_MODE, SYNC_MODE_POLLING)
122
126
  rescue StandardError => e
123
127
  @config.logger.error("process_push_shutdown error: #{e.inspect}")
124
128
  end
@@ -133,6 +137,7 @@ module SplitIoClient
133
137
  @synchronizer.stop_periodic_fetch
134
138
  @synchronizer.sync_all
135
139
  @sse_handler.start_workers
140
+ record_telemetry(Telemetry::Domain::Constants::SYNC_MODE, SYNC_MODE_STREAMING)
136
141
  rescue StandardError => e
137
142
  @config.logger.error("process_connected error: #{e.inspect}")
138
143
  end
@@ -146,6 +151,7 @@ module SplitIoClient
146
151
  @sse_connected.make_false
147
152
  @sse_handler.stop_workers
148
153
  @synchronizer.start_periodic_fetch
154
+ record_telemetry(Telemetry::Domain::Constants::SYNC_MODE, SYNC_MODE_POLLING)
149
155
 
150
156
  if reconnect
151
157
  @synchronizer.sync_all
@@ -154,6 +160,22 @@ module SplitIoClient
154
160
  rescue StandardError => e
155
161
  @config.logger.error("process_disconnect error: #{e.inspect}")
156
162
  end
163
+
164
+ def record_telemetry(type, data)
165
+ @telemetry_runtime_producer.record_streaming_event(type, data)
166
+ end
167
+
168
+ def synchronize_telemetry_config
169
+ @config.threads[:telemetry_config_sender] = Thread.new do
170
+ begin
171
+ @sdk_blocker.wait_unitil_internal_ready unless @config.consumer?
172
+ @telemetry_synchronizer.synchronize_config
173
+ rescue SplitIoClient::SDKShutdownException
174
+ @telemetry_synchronizer.synchronize_config
175
+ @config.logger.info('Posting Telemetry config due to shutdown')
176
+ end
177
+ end
178
+ end
157
179
  end
158
180
  end
159
181
  end
@@ -6,6 +6,8 @@ module SplitIoClient
6
6
  include SplitIoClient::Cache::Fetchers
7
7
  include SplitIoClient::Cache::Senders
8
8
 
9
+ FORCE_CACHE_CONTROL_HEADERS = true
10
+
9
11
  def initialize(
10
12
  repositories,
11
13
  api_key,
@@ -16,30 +18,30 @@ module SplitIoClient
16
18
  @splits_repository = repositories[:splits]
17
19
  @segments_repository = repositories[:segments]
18
20
  @impressions_repository = repositories[:impressions]
19
- @metrics_repository = repositories[:metrics]
20
21
  @events_repository = repositories[:events]
21
22
  @api_key = api_key
22
23
  @config = config
23
24
  @sdk_blocker = sdk_blocker
24
25
  @split_fetcher = params[:split_fetcher]
25
26
  @segment_fetcher = params[:segment_fetcher]
26
- @impressions_api = SplitIoClient::Api::Impressions.new(@api_key, @config)
27
+ @impressions_api = SplitIoClient::Api::Impressions.new(@api_key, @config, params[:telemetry_runtime_producer])
27
28
  @impression_counter = params[:imp_counter]
29
+ @telemetry_synchronizer = params[:telemetry_synchronizer]
28
30
  end
29
31
 
30
32
  def sync_all
31
33
  @config.threads[:sync_all_thread] = Thread.new do
32
34
  @config.logger.debug('Synchronizing Splits and Segments ...') if @config.debug_enabled
33
35
  @split_fetcher.fetch_splits
34
- fetch_segments
36
+ @segment_fetcher.fetch_segments
35
37
  end
36
38
  end
37
39
 
38
40
  def start_periodic_data_recording
39
41
  impressions_sender
40
- metrics_sender
41
42
  events_sender
42
43
  impressions_count_sender
44
+ start_telemetry_sync_task
43
45
  end
44
46
 
45
47
  def start_periodic_fetch
@@ -53,12 +55,12 @@ module SplitIoClient
53
55
  end
54
56
 
55
57
  def fetch_splits
56
- segment_names = @split_fetcher.fetch_splits
57
- @segment_fetcher.fetch_segments_if_not_exists(segment_names) unless segment_names.empty?
58
+ segment_names = @split_fetcher.fetch_splits(FORCE_CACHE_CONTROL_HEADERS)
59
+ @segment_fetcher.fetch_segments_if_not_exists(segment_names, FORCE_CACHE_CONTROL_HEADERS) unless segment_names.empty?
58
60
  end
59
61
 
60
62
  def fetch_segment(name)
61
- @segment_fetcher.fetch_segment(name)
63
+ @segment_fetcher.fetch_segment(name, FORCE_CACHE_CONTROL_HEADERS)
62
64
  end
63
65
 
64
66
  private
@@ -72,11 +74,6 @@ module SplitIoClient
72
74
  ImpressionsSender.new(@impressions_repository, @config, @impressions_api).call
73
75
  end
74
76
 
75
- # Starts thread which loops constantly and sends metrics to the Split API
76
- def metrics_sender
77
- MetricsSender.new(@metrics_repository, @api_key, @config).call
78
- end
79
-
80
77
  # Starts thread which loops constantly and sends events to the Split API
81
78
  def events_sender
82
79
  EventsSender.new(@events_repository, @config).call
@@ -86,6 +83,10 @@ module SplitIoClient
86
83
  def impressions_count_sender
87
84
  ImpressionsCountSender.new(@config, @impression_counter, @impressions_api).call
88
85
  end
86
+
87
+ def start_telemetry_sync_task
88
+ Telemetry::SyncTask.new(@config, @telemetry_synchronizer).call
89
+ end
89
90
  end
90
91
  end
91
92
  end