Class: Wavefront::Paginator::Base
- Inherits:
-
Object
- Object
- Wavefront::Paginator::Base
- Defined in:
- lib/wavefront-sdk/paginator/base.rb
Overview
Automatically handle pagination. This is an abstract class made concrete by an extension for each HTTP request type.
This class and its children do slightly unpleasant things with the HTTP request passed to us by the user, extracting and changing values in the URI, query string, or POST/PUT body. The POST class is particularly onerous.
Automatic pagination works by letting the user override the limit and offset values in API calls.
-
Calling with limit = :all iteratively calls the Wavefront API,
returning all requested objects in a standard Wavefront::Response wrapper.
-
Calling with limit = :lazy returns a lazy Enumerable.
The number of objects fetched in each API call, eager or lazy, defaults to PAGE_SIZE, but the user can override that value by using the offset argument in conjunction with limit = :lazy | :all.
So, for example, to fetch all objects in blocks of ten (which could require a lot of API calls) you would use { limit: :all, offset: 10 }
Instance Attribute Summary collapse
-
#api_caller ⇒ Object
readonly
Returns the value of attribute api_caller.
-
#args ⇒ Object
readonly
Returns the value of attribute args.
-
#conn ⇒ Object
readonly
Returns the value of attribute conn.
-
#initial_limit ⇒ Object
readonly
Returns the value of attribute initial_limit.
-
#method ⇒ Object
readonly
Returns the value of attribute method.
-
#page_size ⇒ Object
readonly
Returns the value of attribute page_size.
Instance Method Summary collapse
-
#finalize_response(resp) ⇒ Object
In #make_recursive_call we’ve built up a composite response object.
-
#initialize(api_caller, conn, method, *args) ⇒ Base
constructor
A new instance of Base.
-
#limit_and_offset(args) ⇒ Hash
An API call may or may not have a limit and/or offset value.
-
#make_lazy_call ⇒ Enumerable
Return all objects using a lazy enumerator.
-
#make_recursive_call ⇒ Wavefront::Response
‘get’ eagerly.
- #set_limit_and_offset(arg, page_size, offset) ⇒ Object
- #set_pagination(offset, page_size, args) ⇒ Object
- #setup_vars ⇒ Object
-
#user_page_size(args) ⇒ Object
How many objects to get on each iteration? The user can pass it in as an alternative to the offset argument, If it’s not a positive integer, default to 999.
Constructor Details
#initialize(api_caller, conn, method, *args) ⇒ Base
Returns a new instance of Base.
43 44 45 46 47 48 49 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 43 def initialize(api_caller, conn, method, *args) @api_caller = api_caller @conn = conn @method = method @args = args setup_vars end |
Instance Attribute Details
#api_caller ⇒ Object (readonly)
Returns the value of attribute api_caller.
33 34 35 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 33 def api_caller @api_caller end |
#args ⇒ Object (readonly)
Returns the value of attribute args.
33 34 35 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 33 def args @args end |
#conn ⇒ Object (readonly)
Returns the value of attribute conn.
33 34 35 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 33 def conn @conn end |
#initial_limit ⇒ Object (readonly)
Returns the value of attribute initial_limit.
33 34 35 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 33 def initial_limit @initial_limit end |
#method ⇒ Object (readonly)
Returns the value of attribute method.
33 34 35 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 33 def method @method end |
#page_size ⇒ Object (readonly)
Returns the value of attribute page_size.
33 34 35 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 33 def page_size @page_size end |
Instance Method Details
#finalize_response(resp) ⇒ Object
In #make_recursive_call we’ve built up a composite response object. This method corrects a couple of things in that object which are misleading. (Because they’re left over from the original call.)
137 138 139 140 141 142 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 137 def finalize_response(resp) resp.tap do |r| r.response[:limit] = r.response.items.size - 1 r.response[:moreItems] = false end end |
#limit_and_offset(args) ⇒ Hash
An API call may or may not have a limit and/or offset value. They could (I think) be anywhere. Safely find and return them. If multiple elements of @args have :limit or :offset keys, the last value wins.
66 67 68 69 70 71 72 73 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 66 def limit_and_offset(args) ret = { offset: nil, limit: nil } args.select { |a| a.is_a?(Hash) }.each_with_object(ret) do |arg, a| a[:limit] = arg[:limit] if arg.key?(:limit) a[:offset] = arg[:offset] if arg.key?(:offset) end end |
#make_lazy_call ⇒ Enumerable
Return all objects using a lazy enumerator.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 151 def make_lazy_call offset = 0 p_args = set_pagination(offset, page_size, args) api_caller.verbosity(conn, method, *p_args) return if api_caller.opts[:noop] Enumerator.new do |y| loop do offset += page_size api_caller.verbosity(conn, method, *p_args) resp = api_caller.respond(conn.public_send(method, *p_args)) unless resp.ok? raise(Wavefront::Exception::EnumerableError, resp.status) end p_args = set_pagination(offset, page_size, p_args) resp.response.items.map { |i| y << i } raise StopIteration unless resp.more_items? end end.lazy end |
#make_recursive_call ⇒ Wavefront::Response
‘get’ eagerly. Re-run the get operation, merging together returned items until we have them all. rubocop:disable Metrics/MethodLength rubocop:disable Metrics/AbcSize
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 109 def make_recursive_call offset = 0 p_args = set_pagination(offset, page_size, args) api_caller.verbosity(conn, method, *p_args) return if api_caller.opts[:noop] ret = api_caller.respond(conn.public_send(method, *p_args)) return ret unless ret.more_items? loop do offset += page_size p_args = set_pagination(offset, page_size, p_args) api_caller.verbosity(conn, method, *p_args) resp = api_caller.respond(conn.public_send(method, *p_args)) raise StopIteration unless resp.ok? ret.response.items += resp.response.items return finalize_response(ret) unless resp.more_items? end end |
#set_limit_and_offset(arg, page_size, offset) ⇒ Object
96 97 98 99 100 101 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 96 def set_limit_and_offset(arg, page_size, offset) arg.tap do |a| a[:limit] = page_size if a.key?(:limit) a[:offset] = offset if a.key?(:offset) end end |
#set_pagination(offset, page_size, args) ⇒ Object
90 91 92 93 94 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 90 def set_pagination(offset, page_size, args) args.map do |arg| arg.is_a?(Hash) ? set_limit_and_offset(arg, page_size, offset) : arg end end |
#setup_vars ⇒ Object
51 52 53 54 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 51 def setup_vars @initial_limit = limit_and_offset(args)[:limit] @page_size = user_page_size(args) unless initial_limit.is_a?(Integer) end |
#user_page_size(args) ⇒ Object
How many objects to get on each iteration? The user can pass it in as an alternative to the offset argument, If it’s not a positive integer, default to 999
79 80 81 82 83 84 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 79 def user_page_size(args) arg_val = limit_and_offset(args)[:offset].to_i return arg_val if arg_val&.positive? PAGE_SIZE end |