Class: Square::Reporting::Client
- Inherits:
-
Object
- Object
- Square::Reporting::Client
- Defined in:
- lib/square/reporting_helper.rb,
lib/square/reporting/client.rb
Overview
Custom, +.fernignore+-protected polling helper for the Reporting API.
The /reporting/v1/load endpoint is asynchronous: a query that is still
being computed comes back as an HTTP 200 whose body is
{ "error": "Continue wait" } rather than the results. Callers are expected
to re-send the identical request, with backoff, until real results arrive.
This file reopens the generated Client to add
load_and_wait, which owns that retry loop.
Constant Summary collapse
- CONTINUE_WAIT_SENTINEL =
The value of the
errorfield the Reporting API returns on an HTTP 200 while a/reporting/v1/loadquery is still processing. It is NOT a failure — the identical request should be re-sent until real results arrive. See https://developer.squareup.com/docs/reporting-api/overview. "Continue wait"- DEFAULT_MAX_ATTEMPTS =
Default polling parameters for #load_and_wait.
20- DEFAULT_INITIAL_DELAY =
2.0- DEFAULT_MAX_DELAY =
20.0- DEFAULT_BACKOFF_FACTOR =
2.0- POLL_TICK =
Granularity (seconds) at which a backoff wait checks
should_cancel, so cancellation stays responsive even during a long delay. 0.1
Instance Method Summary collapse
-
#get_metadata(request_options: {}, **params) ⇒ Square::Types::MetadataResponse
Describes the data available to query: the cubes, views, measures, dimensions, and segments you can reference in a reporting query.
- #initialize(client:) ⇒ void constructor
-
#load(request_options: {}, **params) ⇒ Square::Types::LoadResponse
Runs a reporting query against the discovered schema and returns the aggregated results.
-
#load_and_wait(request_options: {}, max_attempts: DEFAULT_MAX_ATTEMPTS, initial_delay: DEFAULT_INITIAL_DELAY, max_delay: DEFAULT_MAX_DELAY, backoff_factor: DEFAULT_BACKOFF_FACTOR, should_cancel: nil, **params) ⇒ Square::Types::LoadResponse
Runs a reporting query and transparently polls until it resolves, returning the final Types::LoadResponse.
Constructor Details
#initialize(client:) ⇒ void
9 10 11 |
# File 'lib/square/reporting/client.rb', line 9 def initialize(client:) @client = client end |
Instance Method Details
#get_metadata(request_options: {}, **params) ⇒ Square::Types::MetadataResponse
Describes the data available to query: the cubes, views, measures, dimensions, and segments you can reference in
a reporting query. Call this first to discover the schema, then pass the members you need to load.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/square/reporting/client.rb', line 25 def (request_options: {}, **params) Square::Internal::Types::Utils.normalize_keys(params) request = Square::Internal::JSON::Request.new( base_url: [:base_url], method: "GET", path: "reporting/v1/meta", request_options: ) begin response = @client.send(request) rescue Net::HTTPRequestTimeout raise Square::Errors::TimeoutError end code = response.code.to_i if code.between?(200, 299) Square::Types::MetadataResponse.load(response.body) else error_class = Square::Errors::ResponseError.subclass_for_code(code) raise error_class.new(response.body, code: code) end end |
#load(request_options: {}, **params) ⇒ Square::Types::LoadResponse
Runs a reporting query against the discovered schema and returns the aggregated results. Long-running queries may return a "Continue wait" response while processing — retry the same request until results are ready.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/square/reporting/client.rb', line 59 def load(request_options: {}, **params) params = Square::Internal::Types::Utils.normalize_keys(params) request = Square::Internal::JSON::Request.new( base_url: [:base_url], method: "POST", path: "reporting/v1/load", body: Square::Reporting::Types::LoadRequest.new(params).to_h, request_options: ) begin response = @client.send(request) rescue Net::HTTPRequestTimeout raise Square::Errors::TimeoutError end code = response.code.to_i if code.between?(200, 299) Square::Types::LoadResponse.load(response.body) else error_class = Square::Errors::ResponseError.subclass_for_code(code) raise error_class.new(response.body, code: code) end end |
#load_and_wait(request_options: {}, max_attempts: DEFAULT_MAX_ATTEMPTS, initial_delay: DEFAULT_INITIAL_DELAY, max_delay: DEFAULT_MAX_DELAY, backoff_factor: DEFAULT_BACKOFF_FACTOR, should_cancel: nil, **params) ⇒ Square::Types::LoadResponse
Runs a reporting query and transparently polls until it resolves, returning the final Types::LoadResponse.
A query that is still being computed comes back as an HTTP 200 whose body
is { "error": "Continue wait" }. That body deserializes into a
LoadResponse whose error key lands in the model's extra fields (it is
not a declared field) while results stays nil; that is the signal to
retry. load_and_wait re-sends the identical request with exponential
backoff until real results arrive.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/square/reporting_helper.rb', line 79 def load_and_wait( request_options: {}, max_attempts: DEFAULT_MAX_ATTEMPTS, initial_delay: DEFAULT_INITIAL_DELAY, max_delay: DEFAULT_MAX_DELAY, backoff_factor: DEFAULT_BACKOFF_FACTOR, should_cancel: nil, **params ) delay = initial_delay attempt = 1 loop do raise PollingCancelledError if should_cancel&.call response = load(request_options: , **params) return response unless continue_wait?(response) break if attempt >= max_attempts cancellable_sleep(delay, should_cancel) attempt += 1 delay = [delay * backoff_factor, max_delay].min end raise ContinueWaitTimeoutError, "Reporting query did not complete after #{max_attempts} attempts " \ "(#{CONTINUE_WAIT_SENTINEL.inspect})" end |