Class: InstagramConnect::Usage

Inherits:
Object
  • Object
show all
Defined in:
lib/instagram_connect/usage.rb

Overview

Meta's own account of how much of the rate budget a call just consumed, parsed from the response headers.

This is worth having because the documented formula — 4800 calls per 24 hours multiplied by the account's impressions — depends on a number the messaging API never returns. Any budget computed locally is a guess. These headers are Meta telling you the answer directly, so they are treated as ground truth and the arithmetic only as a fallback.

Constant Summary collapse

HEADERS =
%w[x-business-use-case-usage x-app-usage].freeze
WARN_AT =

Back off well before the wall: at 100% Meta stops answering, and the penalty is measured in hours.

80
CRITICAL_AT =
95

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(call_count: 0, total_cputime: 0, total_time: 0, estimated_time_to_regain_access: nil) ⇒ Usage

Returns a new instance of Usage.



22
23
24
25
26
27
# File 'lib/instagram_connect/usage.rb', line 22

def initialize(call_count: 0, total_cputime: 0, total_time: 0, estimated_time_to_regain_access: nil)
  @call_count = call_count.to_i
  @total_cputime = total_cputime.to_i
  @total_time = total_time.to_i
  @estimated_time_to_regain_access = estimated_time_to_regain_access
end

Instance Attribute Details

#call_countObject (readonly)

Returns the value of attribute call_count.



20
21
22
# File 'lib/instagram_connect/usage.rb', line 20

def call_count
  @call_count
end

#estimated_time_to_regain_accessObject (readonly)

Returns the value of attribute estimated_time_to_regain_access.



20
21
22
# File 'lib/instagram_connect/usage.rb', line 20

def estimated_time_to_regain_access
  @estimated_time_to_regain_access
end

#total_cputimeObject (readonly)

Returns the value of attribute total_cputime.



20
21
22
# File 'lib/instagram_connect/usage.rb', line 20

def total_cputime
  @total_cputime
end

#total_timeObject (readonly)

Returns the value of attribute total_time.



20
21
22
# File 'lib/instagram_connect/usage.rb', line 20

def total_time
  @total_time
end

Class Method Details

.from_headers(headers) ⇒ Object

Returns nil when Meta sent no usage headers, which is normal for some endpoints — absence is not zero usage and must not be read as headroom.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/instagram_connect/usage.rb', line 31

def self.from_headers(headers)
  raw = HEADERS.filter_map { |name| headers&.[](name) }.first
  return nil if raw.blank?

  payload = JSON.parse(raw)
  # The business header is keyed by object id and holds an array; the app
  # header is a flat hash.
  metrics = payload.is_a?(Hash) && payload.values.first.is_a?(Array) ? payload.values.first.first : payload
  return nil unless metrics.is_a?(Hash)

  new(
    call_count: metrics["call_count"],
    total_cputime: metrics["total_cputime"],
    total_time: metrics["total_time"],
    estimated_time_to_regain_access: metrics["estimated_time_to_regain_access"]
  )
rescue JSON::ParserError
  nil
end

Instance Method Details

#critical?Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/instagram_connect/usage.rb', line 60

def critical?
  percentage >= CRITICAL_AT
end

#percentageObject

The worst of the three, since exhausting any one of them throttles the app.



52
53
54
# File 'lib/instagram_connect/usage.rb', line 52

def percentage
  [ call_count, total_cputime, total_time ].max
end

#retry_afterObject



64
65
66
# File 'lib/instagram_connect/usage.rb', line 64

def retry_after
  estimated_time_to_regain_access.to_i * 60 if estimated_time_to_regain_access.to_i.positive?
end

#warning?Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/instagram_connect/usage.rb', line 56

def warning?
  percentage >= WARN_AT
end