Class: Flagstack::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/flagstack/client.rb

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Client

Returns a new instance of Client.



6
7
8
9
# File 'lib/flagstack/client.rb', line 6

def initialize(config)
  @config = config
  @etag = nil
end

Instance Method Details

#check(feature_key, actor_id: nil) ⇒ Object



39
40
41
42
43
44
45
46
# File 'lib/flagstack/client.rb', line 39

def check(feature_key, actor_id: nil)
  uri = URI("#{@config.url}/api/v1/features/#{feature_key}/check")
  uri.query = URI.encode_www_form(actor_id: actor_id) if actor_id

  response = request(:get, uri)
  data = JSON.parse(response.body)
  data["enabled"]
end

#health_checkObject

Check if the Flagstack server is reachable and the token is valid Returns a hash with :ok (boolean) and :message (string)



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/flagstack/client.rb', line 50

def health_check
  uri = URI("#{@config.url}/api/v1/sync")

  response = request(:get, uri)

  case response.code.to_i
  when 200, 304
    { ok: true, message: "Connected to Flagstack" }
  when 401
    { ok: false, message: "Invalid API token" }
  when 429
    { ok: true, message: "Connected (rate limited)" }
  else
    { ok: false, message: "Unexpected response: #{response.code}" }
  end
rescue Timeout::Error, Net::OpenTimeout, Net::ReadTimeout => e
  { ok: false, message: "Connection timeout: #{e.message}" }
rescue Errno::ECONNREFUSED => e
  { ok: false, message: "Connection refused: #{e.message}" }
rescue => e
  { ok: false, message: "Connection failed: #{e.message}" }
end

#post_telemetry(compressed_body) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/flagstack/client.rb', line 73

def post_telemetry(compressed_body)
  uri = URI("#{@config.url}/api/v1/telemetry")

  response = request(:post, uri) do |req|
    req["Content-Type"] = "application/json"
    req["Content-Encoding"] = "gzip"
    req.body = compressed_body
  end

  case response.code.to_i
  when 200..299
    @config.log("Telemetry submitted successfully", level: :debug)
    response
  when 429
    @config.log("Telemetry rate limited", level: :warn)
    nil
  else
    @config.log("Telemetry failed: #{response.code}", level: :error)
    nil
  end
rescue Timeout::Error, Net::OpenTimeout, Net::ReadTimeout, Errno::ECONNREFUSED => e
  @config.log("Telemetry connection failed: #{e.message}", level: :error)
  nil
end

#syncObject



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/flagstack/client.rb', line 11

def sync
  uri = URI("#{@config.url}/api/v1/sync")

  response = request(:get, uri) do |req|
    req["If-None-Match"] = @etag if @etag
  end

  case response.code.to_i
  when 200
    @etag = response["ETag"]
    @config.log("Sync successful (ETag: #{@etag})", level: :debug)
    JSON.parse(response.body)
  when 304
    @config.log("Sync not modified (304)", level: :debug)
    nil # Cache is current
  when 401
    raise APIError, "Invalid API token"
  when 429
    @config.log("Rate limited, backing off", level: :warn)
    nil
  else
    raise APIError, "API error: #{response.code} #{response.body}"
  end
rescue Timeout::Error, Net::OpenTimeout, Net::ReadTimeout, Errno::ECONNREFUSED => e
  @config.log("Connection failed: #{e.message}", level: :error)
  nil
end