Class: Aireview::ModelState

Inherits:
Object
  • Object
show all
Defined in:
lib/aireview/model_state.rb

Overview

What the router learned about a model during the run. Three things with different lifetimes: sent requests are counted per stage, a quarantine lasts until a moment in time, an exclusion lasts until the end of the run (the provider has no such model, every key is out of quota) or the end of the stage (an invalid result). Keys with an exhausted daily quota are remembered separately: a quota is a property of "key + model", a quarantine a property of the model.

Constant Summary collapse

MAX_REQUESTS_PER_STAGE =

Every request sent, the short retry and the JSON repair included, spends an attempt regardless of its outcome; the keys of a model share one counter, a quarantine does not reset it.

3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(limit: MAX_REQUESTS_PER_STAGE) ⇒ ModelState

Returns a new instance of ModelState.



20
21
22
23
24
25
26
27
# File 'lib/aireview/model_state.rb', line 20

def initialize(limit: MAX_REQUESTS_PER_STAGE)
  @limit = limit
  @sent = Hash.new(0)
  @quarantined_until = nil
  @excluded_reason = nil
  @stage_exclusions = {}
  @exhausted_keys = Set.new
end

Instance Attribute Details

#excluded_reason ⇒ Object (readonly)

Returns the value of attribute excluded_reason.



18
19
20
# File 'lib/aireview/model_state.rb', line 18

def excluded_reason
  @excluded_reason
end

Instance Method Details

#exclude(reason) ⇒ Object



56
57
58
# File 'lib/aireview/model_state.rb', line 56

def exclude(reason)
  @excluded_reason = reason
end

#exclude_for_stage(stage, reason) ⇒ Object



60
61
62
# File 'lib/aireview/model_state.rb', line 60

def exclude_for_stage(stage, reason)
  @stage_exclusions[stage.to_s] = reason
end

#exhaust_key(key_index) ⇒ Object



64
65
66
# File 'lib/aireview/model_state.rb', line 64

def exhaust_key(key_index)
  @exhausted_keys << key_index
end

#key_exhausted?(key_index) ⇒ Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/aireview/model_state.rb', line 68

def key_exhausted?(key_index)
  @exhausted_keys.include?(key_index)
end

#lift_quarantine ⇒ Object

A model that answered is not overloaded, whichever key answered.



46
47
48
# File 'lib/aireview/model_state.rb', line 46

def lift_quarantine
  @quarantined_until = nil
end

#quarantine(until_time) ⇒ Object



41
42
43
# File 'lib/aireview/model_state.rb', line 41

def quarantine(until_time)
  @quarantined_until = until_time
end

#quarantine_left(now) ⇒ Object



50
51
52
53
54
# File 'lib/aireview/model_state.rb', line 50

def quarantine_left(now)
  return 0 unless @quarantined_until

  [@quarantined_until - now, 0].max
end

#record_request(stage) ⇒ Object



33
34
35
# File 'lib/aireview/model_state.rb', line 33

def record_request(stage)
  @sent[stage.to_s] += 1
end

#requests_left?(stage) ⇒ Boolean

Returns:

  • (Boolean)


37
38
39
# File 'lib/aireview/model_state.rb', line 37

def requests_left?(stage)
  sent(stage) < @limit
end

#sent(stage) ⇒ Object



29
30
31
# File 'lib/aireview/model_state.rb', line 29

def sent(stage)
  @sent[stage.to_s]
end

#skip_reason(stage) ⇒ Object

Why the model cannot be tried in the stage; nil — it can (the quarantine is checked separately: it is a wait, not a ban).



74
75
76
77
78
79
80
# File 'lib/aireview/model_state.rb', line 74

def skip_reason(stage)
  return @excluded_reason if @excluded_reason
  return "excluded for this stage: #{@stage_exclusions[stage.to_s]}" if @stage_exclusions.key?(stage.to_s)
  return "attempt limit of #{@limit} reached" unless requests_left?(stage)

  nil
end