Class: Shipeasy::SDK::FlagsClient

Inherits:
Object
  • Object
show all
Defined in:
lib/shipeasy/sdk/flags_client.rb

Constant Summary collapse

DEFAULT_BASE_URL =
"https://edge.shipeasy.dev"

Instance Method Summary collapse

Constructor Details

#initialize(api_key:, base_url: nil) ⇒ FlagsClient

Returns a new instance of FlagsClient.



12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/shipeasy/sdk/flags_client.rb', line 12

def initialize(api_key:, base_url: nil)
  @api_key     = api_key
  @base_url    = (base_url || DEFAULT_BASE_URL).chomp("/")
  @flags_blob  = nil
  @exps_blob   = nil
  @flags_etag  = nil
  @exps_etag   = nil
  @poll_interval = 30
  @mutex       = Mutex.new
  @timer       = nil
  @initialized = false
end

Instance Method Details

#destroyObject



37
38
39
40
# File 'lib/shipeasy/sdk/flags_client.rb', line 37

def destroy
  @timer&.kill
  @timer = nil
end

#get_config(name, decode = nil) ⇒ Object



48
49
50
51
52
53
# File 'lib/shipeasy/sdk/flags_client.rb', line 48

def get_config(name, decode = nil)
  entry = @mutex.synchronize { @flags_blob&.dig("configs", name) }
  return nil unless entry
  value = entry["value"]
  decode ? decode.call(value) : value
end

#get_experiment(name, user, default_params, decode = nil) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/shipeasy/sdk/flags_client.rb', line 55

def get_experiment(name, user, default_params, decode = nil)
  flags_blob, exps_blob = @mutex.synchronize { [@flags_blob, @exps_blob] }
  exp = exps_blob&.dig("experiments", name)
  result = Eval.eval_experiment(exp, flags_blob, exps_blob, user.transform_keys(&:to_s))
  result.params ||= default_params

  if result.in_experiment && decode
    begin
      result = Eval::ExperimentResult.new(
        in_experiment: true,
        group: result.group,
        params: decode.call(result.params),
      )
    rescue => e
      warn "[shipeasy] get_experiment('#{name}') decode failed: #{e.message}"
      return Eval::ExperimentResult.new(in_experiment: false, group: "control", params: default_params)
    end
  end

  result
end

#get_flag(name, user) ⇒ Object



42
43
44
45
46
# File 'lib/shipeasy/sdk/flags_client.rb', line 42

def get_flag(name, user)
  gate = @mutex.synchronize { @flags_blob&.dig("gates", name) }
  return false unless gate
  Eval.eval_gate(gate, user.transform_keys(&:to_s))
end

#initObject



25
26
27
28
29
# File 'lib/shipeasy/sdk/flags_client.rb', line 25

def init
  fetch_all
  @initialized = true
  start_poll
end

#init_onceObject



31
32
33
34
35
# File 'lib/shipeasy/sdk/flags_client.rb', line 31

def init_once
  return if @initialized
  fetch_all
  @initialized = true
end

#track(user_id, event_name, props = {}) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/shipeasy/sdk/flags_client.rb', line 77

def track(user_id, event_name, props = {})
  payload = JSON.generate({
    events: [{
      type: "metric",
      event_name: event_name,
      user_id: user_id.to_s,
      ts: (Time.now.to_f * 1000).to_i,
      **(props.empty? ? {} : { properties: props }),
    }],
  })

  Thread.new do
    post("/collect", payload)
  rescue => e
    warn "[shipeasy] track failed: #{e.message}"
  end
end