Class: Jbr::Throttle

Inherits:
Object
  • Object
show all
Defined in:
lib/jbr/throttle.rb

Overview

How much Jobber will still answer, and how long to wait before asking again. Jobber holds an app to two limits at once, and this keeps both: a count of requests over a window, and a bucket of query cost that drains as it is asked and refills at a rate it reports.

Constant Summary collapse

SPACING =

Jobber answers 2,500 requests every 5 minutes, which is one every 0.12 seconds. Spacing them is what keeps a walk of many pages under the count, whatever each page costs.

300.0 / 2_500

Instance Method Summary collapse

Instance Method Details

#affordable?Boolean

Whether the bucket could ever pay for the query it last priced. A refusal is worth waiting out where it could: the shortfall refills and the same query goes through. Where the query costs more than the bucket ever holds, no wait will do — and where Jobber said nothing about the ceiling, one attempt at waiting is cheaper than assuming the worst.

Returns:

  • (Boolean)

    false only where the ceiling is known and the query is over it.



37
# File 'lib/jbr/throttle.rb', line 37

def affordable? = !@maximum.to_f.positive? || @cost.to_f <= @maximum

#read(extensions) ⇒ Object

Takes in what the answer said it had left. Jobber reports the bucket beside the data, so what the next caller may ask for is known before they ask for it.

Parameters:

  • extensions (Hash, nil)

    the extensions Jobber answered beside the data.



21
22
23
24
25
26
27
28
29
30
# File 'lib/jbr/throttle.rb', line 21

def read(extensions)
  cost = extensions.to_h['cost'].to_h
  status = cost['throttleStatus'].to_h
  # What a refused query would have cost is what it costs: Jobber prices it either way,
  # and only an answered one reports an actual.
  @cost = (cost['actualQueryCost'] || cost['requestedQueryCost']).to_f
  @available = status['currentlyAvailable'].to_f
  @maximum = status['maximumAvailable'].to_f
  @restore_rate = status['restoreRate'].to_f
end

#waitFloat

Returns the seconds waited, which is zero where nothing was owed.

Returns:

  • (Float)

    the seconds waited, which is zero where nothing was owed.



11
12
13
14
15
16
# File 'lib/jbr/throttle.rb', line 11

def wait
  owed = [ spacing_owed, restore_owed ].max
  sleep owed if owed.positive?
  @asked_at = Time.now
  owed
end