Class: DevCycle::ConfigManager

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/devcycle-ruby-server-sdk/localbucketing/config_manager.rb

Instance Method Summary collapse

Constructor Details

#initialize(sdkKey, local_bucketing, wait_for_init) ⇒ ConfigManager

Returns a new instance of ConfigManager.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/devcycle-ruby-server-sdk/localbucketing/config_manager.rb', line 16

def initialize(sdkKey, local_bucketing, wait_for_init)
  @first_load = true
  @config_version = "v1"
  @local_bucketing = local_bucketing
  @sdkKey = sdkKey
  @config_e_tag = ""
  @logger = local_bucketing.options.logger
  @polling_enabled = true
  @max_config_retries = 2

  @config_poller = Concurrent::TimerTask.new({
      execution_interval: @local_bucketing.options.config_polling_interval_ms.fdiv(1000)
    }) do |task|
    fetch_config
  end

  t = Thread.new { initialize_config }
  t.join if wait_for_init
end

Instance Method Details

#closeObject



109
110
111
112
# File 'lib/devcycle-ruby-server-sdk/localbucketing/config_manager.rb', line 109

def close
  @config_poller.shutdown if @config_poller.running?
  nil
end

#fetch_configObject



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
# File 'lib/devcycle-ruby-server-sdk/localbucketing/config_manager.rb', line 47

def fetch_config
  return unless @polling_enabled

  req = Typhoeus::Request.new(
    get_config_url,
    headers: {
      Accept: "application/json",
    })

  if @config_e_tag != ""
    req.options[:headers]['If-None-Match'] = @config_e_tag
  end

  @max_config_retries.times do
    @logger.debug("Requesting new config from #{get_config_url}, current etag: #{@config_e_tag}")
    resp = req.run
    @logger.debug("Config request complete, status: #{resp.code}")
    case resp.code
    when 304
      @logger.debug("Config not modified, using cache, etag: #{@config_e_tag}")
      break
    when 200
      @logger.info("New config received, etag: #{resp.headers['Etag']}")
      set_config(resp.body, resp.headers['Etag'])
      @logger.info("New config stored, etag: #{@config_e_tag}")
      break
    when 403
      stop_polling
      @logger.error("Failed to download DevCycle config; Invalid SDK Key.")
      break
    when 500...599
      @logger.error("Failed to download DevCycle config. Status: #{resp.code}")
    else
      stop_polling
      @logger.error("Unexpected response code - DevCycle Response: #{Oj.dump(resp)}")
      break
    end
  end

  nil
end

#get_config_urlObject



99
100
101
102
# File 'lib/devcycle-ruby-server-sdk/localbucketing/config_manager.rb', line 99

def get_config_url
  configBasePath = @local_bucketing.options.config_cdn_uri
  "#{configBasePath}/config/#{@config_version}/server/#{@sdkKey}.json"
end

#initialize_configObject



36
37
38
39
40
41
42
43
44
45
# File 'lib/devcycle-ruby-server-sdk/localbucketing/config_manager.rb', line 36

def initialize_config
  begin
    fetch_config
    @config_poller.execute if @polling_enabled
  rescue => e
    @logger.error("DVC Error Initializing Config: #{e.message}")
  ensure
    @local_bucketing.initialized = true
  end
end

#set_config(config, etag) ⇒ Object



89
90
91
92
93
94
95
96
97
# File 'lib/devcycle-ruby-server-sdk/localbucketing/config_manager.rb', line 89

def set_config(config, etag)
  if !JSON.parse(config).is_a?(Hash)
    raise("Invalid JSON body parsed from Config Response")
  end

  @local_bucketing.store_config(config)
  @config_e_tag = etag
  @local_bucketing.has_config = true
end

#stop_pollingObject



104
105
106
107
# File 'lib/devcycle-ruby-server-sdk/localbucketing/config_manager.rb', line 104

def stop_polling
  @polling_enabled = false
  @config_poller.shutdown if @config_poller.running?
end