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.



26
27
28
29
30
31
# File 'lib/instagram_connect/usage.rb', line 26

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.



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

def call_count
  @call_count
end

#estimated_time_to_regain_accessObject (readonly)

Returns the value of attribute estimated_time_to_regain_access.



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

def estimated_time_to_regain_access
  @estimated_time_to_regain_access
end

#total_cputimeObject (readonly)

Returns the value of attribute total_cputime.



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

def total_cputime
  @total_cputime
end

#total_timeObject (readonly)

Returns the value of attribute total_time.



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

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.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/instagram_connect/usage.rb', line 35

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)


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

def critical?
  percentage >= CRITICAL_AT
end

#percentageObject

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



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

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

#retry_afterObject



68
69
70
# File 'lib/instagram_connect/usage.rb', line 68

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)


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

def warning?
  percentage >= WARN_AT
end