Exception: SplitIoClient::SplitAdapter

Inherits:
NoMethodError
  • Object
show all
Defined in:
lib/engine/parser/split_adapter.rb

Overview

acts as an api adapater to connect to split endpoints uses a configuration object that can be modified when creating the client instance also, uses safe threads to execute fetches and post give the time execution values from the config

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api_key, config, splits_repository, segments_repository, impressions_repository, metrics_repository, sdk_blocker) ⇒ SplitIoClient

Creates a new split api adapter instance that consumes split api endpoints

Parameters:

  • api_key (String)

    the API key for your split account



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/engine/parser/split_adapter.rb', line 38

def initialize(api_key, config, splits_repository, segments_repository, impressions_repository, metrics_repository, sdk_blocker)
  @api_key = api_key
  @config = config

  @splits_repository = splits_repository
  @segments_repository = segments_repository
  @impressions_repository = impressions_repository
  @metrics_repository = metrics_repository

  @metrics = Metrics.new(100, @config, @metrics_repository)

  @sdk_blocker = sdk_blocker

  @api_client = Faraday.new do |builder|
    builder.use FaradayMiddleware::Gzip
    builder.adapter :net_http_persistent
  end

  start_based_on_mode(@config.mode)
end

Instance Attribute Details

#impressions_producerObject (readonly)

Returns the value of attribute impressions_producer.



28
29
30
# File 'lib/engine/parser/split_adapter.rb', line 28

def impressions_producer
  @impressions_producer
end

#impressions_repositoryObject (readonly)

Returns the value of attribute impressions_repository.



30
31
32
# File 'lib/engine/parser/split_adapter.rb', line 30

def impressions_repository
  @impressions_repository
end

#metricsObject (readonly)

handler for metrics



18
19
20
# File 'lib/engine/parser/split_adapter.rb', line 18

def metrics
  @metrics
end

#parsed_segmentsObject (readonly)



26
27
28
# File 'lib/engine/parser/split_adapter.rb', line 26

def parsed_segments
  @parsed_segments
end

#parsed_splitsObject (readonly)



22
23
24
# File 'lib/engine/parser/split_adapter.rb', line 22

def parsed_splits
  @parsed_splits
end

#segments_repositoryObject (readonly)

Returns the value of attribute segments_repository.



30
31
32
# File 'lib/engine/parser/split_adapter.rb', line 30

def segments_repository
  @segments_repository
end

#splits_repositoryObject (readonly)

Returns the value of attribute splits_repository.



30
31
32
# File 'lib/engine/parser/split_adapter.rb', line 30

def splits_repository
  @splits_repository
end

Instance Method Details

#impressions_senderObject

Starts thread which loops constantly and sends impressions to the Split API



89
90
91
# File 'lib/engine/parser/split_adapter.rb', line 89

def impressions_sender
  SplitIoClient::Cache::Senders::ImpressionsSender.new(@impressions_repository, @config, @api_key).call
end

#metrics_senderObject

creates two safe threads that will be executing api calls for posting impressions and metrics given the execution time provided within the configuration



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/engine/parser/split_adapter.rb', line 138

def metrics_sender
  # TODO: Send metrics in main thread for test ENV
  return if ENV['SPLITCLIENT_ENV'] == 'test'

  Thread.new do

    @config.logger.info('Starting metrics service')

    loop do
      begin

        post_metrics

      rescue StandardError => error
        @config.log_found_exception(__method__.to_s, error)
      end

      # Sleep either on success of failure.
      sleep(randomize_interval(@config.metrics_refresh_rate))
    end
  end

end

#post_api(path, param) ⇒ object

helper method to execute a post request to the provided endpoint

Parameters:

  • path (string)

    api endpoint path

  • params (object)

    hash of params that will be added to the request

Returns:

  • (object)

    response to the request



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/engine/parser/split_adapter.rb', line 100

def post_api(path, param)
  @api_client.post (@config.events_uri + path) do |req|
    req.headers['Authorization'] = 'Bearer ' + @api_key
    req.headers['Content-Type'] = 'application/json'
    req.headers['SplitSDKVersion'] = SplitIoClient::SplitFactory.sdk_version
    req.headers['SplitSDKMachineName'] = @config.machine_name
    req.headers['SplitSDKMachineIP'] = @config.machine_ip
    req.body = param.to_json
    req.options.timeout = @config.read_timeout
    req.options.open_timeout = @config.connection_timeout

    if @config.transport_debug_enabled
      @config.logger.debug("POST #{@config.events_uri + path} #{req.body}")
    elsif @config.debug_enabled
      @config.logger.debug("POST #{@config.events_uri + path}")
    end

  end
end

#post_metricsvoid

This method returns an undefined value.

creates the appropriate json data for the cached metrics values include latencies, counts and gauges and then sends them to the appropriate api endpoint with a valida body format



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/engine/parser/split_adapter.rb', line 168

def post_metrics
  if @metrics_repository.latencies.empty?
    @config.logger.debug('No latencies to report.') if @config.debug_enabled
  else
    @metrics_repository.latencies.each do |name, latencies|
      metrics_time = { name: name, latencies: latencies }
      res = post_api('/metrics/time', metrics_time)
      if res.status / 100 != 2
        @config.logger.error("Unexpected status code while posting time metrics: #{res.status}")
      else
        @config.logger.debug("Metric time reported: #{metrics_time.size}") if @config.debug_enabled
      end
    end
  end
  @metrics_repository.clear_latencies

  if @metrics_repository.counts.empty?
    @config.logger.debug('No counts to report.') if @config.debug_enabled
  else
    @metrics_repository.counts.each do |name, count|
      metrics_count = { name: name, delta: count }
      res = post_api('/metrics/counter', metrics_count)
      if res.status / 100 != 2
        @config.logger.error("Unexpected status code while posting count metrics: #{res.status}")
      else
        @config.logger.debug("Metric counts reported: #{metrics_count.size}") if @config.debug_enabled
      end
    end
  end
  @metrics_repository.clear_counts
end

#segment_storeObject

Starts thread which loops constantly and stores segments in the segments_repository of choice



84
85
86
# File 'lib/engine/parser/split_adapter.rb', line 84

def segment_store
  SplitIoClient::Cache::Stores::SegmentStore.new(@segments_repository, @config, @api_key, @metrics, @sdk_blocker).call
end

#split_storeObject

Starts thread which loops constantly and stores splits in the splits_repository of choice



79
80
81
# File 'lib/engine/parser/split_adapter.rb', line 79

def split_store
  SplitIoClient::Cache::Stores::SplitStore.new(@splits_repository, @config, @api_key, @metrics, @sdk_blocker).call
end

#start_based_on_mode(mode) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/engine/parser/split_adapter.rb', line 59

def start_based_on_mode(mode)
  case mode
  when :standalone
    split_store
    segment_store
    metrics_sender
    impressions_sender
  when :consumer
    # Do nothing in background
  when :producer
    split_store
    segment_store
    impressions_sender
    metrics_sender

    sleep unless ENV['SPLITCLIENT_ENV'] == 'test'
  end
end