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. Setting the limit to :all iteratively calls the Wavefront API, returning all requested objects an a standard Wavefront::Response wrapper; setting limit to :lazy returns a lazy Enumerable. The number of objects fetched in each API call, whether 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.
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.
37 38 39 40 41 42 43 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 37 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.
27 28 29 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 27 def api_caller @api_caller end |
#args ⇒ Object (readonly)
Returns the value of attribute args.
27 28 29 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 27 def args @args end |
#conn ⇒ Object (readonly)
Returns the value of attribute conn.
27 28 29 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 27 def conn @conn end |
#initial_limit ⇒ Object (readonly)
Returns the value of attribute initial_limit.
27 28 29 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 27 def initial_limit @initial_limit end |
#method ⇒ Object (readonly)
Returns the value of attribute method.
27 28 29 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 27 def method @method end |
#page_size ⇒ Object (readonly)
Returns the value of attribute page_size.
27 28 29 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 27 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.)
131 132 133 134 135 136 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 131 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.
60 61 62 63 64 65 66 67 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 60 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.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 145 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
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 103 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
90 91 92 93 94 95 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 90 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
84 85 86 87 88 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 84 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
45 46 47 48 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 45 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
73 74 75 76 77 78 |
# File 'lib/wavefront-sdk/paginator/base.rb', line 73 def user_page_size(args) arg_val = limit_and_offset(args)[:offset].to_i return arg_val if arg_val&.positive? PAGE_SIZE end |