lib/ably/models/paginated_resource.rb in ably-0.2.0 vs lib/ably/models/paginated_resource.rb in ably-0.6.2
- old
+ new
@@ -1,27 +1,31 @@
module Ably::Models
- # Wraps any Ably HTTP response that supports paging and automatically provides methdos to iterated through
+ # Wraps any Ably HTTP response that supports paging and automatically provides methods to iterate through
# the array of resources using {#first_page}, {#next_page}, {#first_page?} and {#last_page?}
#
# Paging information is provided by Ably in the LINK HTTP headers
class PaginatedResource
include Enumerable
+ include Ably::Modules::AsyncWrapper
# @param [Faraday::Response] http_response Initial HTTP response from an Ably request to a paged resource
# @param [String] base_url Base URL for request that generated the http_response so that subsequent paged requests can be made
# @param [Client] client {Ably::Client} used to make the request to Ably
# @param [Hash] options Options for this paged resource
# @option options [Symbol,String] :coerce_into symbol or string representing class that should be used to create each item in the PaginatedResource
#
+ # @yield [Object] block will be called for each resource object for the current page. This is a useful way to apply a transformation to any page resources after they are retrieved
+ #
# @return [PaginatedResource]
def initialize(http_response, base_url, client, options = {}, &each_block)
@http_response = http_response
@client = client
@base_url = "#{base_url.gsub(%r{/[^/]*$}, '')}/"
@coerce_into = options[:coerce_into]
@raw_body = http_response.body
@each_block = each_block
+ @make_async = options.fetch(:async_blocking_operations, false)
@body = if @coerce_into
http_response.body.map do |item|
Kernel.const_get(@coerce_into).new(item)
end
@@ -32,23 +36,31 @@
@body = @body.map do |resource|
each_block.call(resource)
end if block_given?
end
- # Retrieve the first page of results
+ # Retrieve the first page of results.
+ # When used as part of the {Ably::Realtime} library, it will return a {EventMachine::Deferrable} object,
+ # and allows an optional success callback block to be provided.
#
- # @return [PaginatedResource]
- def first_page
- PaginatedResource.new(client.get(pagination_url('first')), base_url, client, coerce_into: coerce_into, &each_block)
+ # @return [PaginatedResource,EventMachine::Deferrable]
+ def first_page(&success_callback)
+ async_wrap_if(make_async, success_callback) do
+ PaginatedResource.new(client.get(pagination_url('first')), base_url, client, pagination_options, &each_block)
+ end
end
- # Retrieve the next page of results
+ # Retrieve the next page of results.
+ # When used as part of the {Ably::Realtime} library, it will return a {EventMachine::Deferrable} object,
+ # and allows an optional success callback block to be provided.
#
- # @return [PaginatedResource]
- def next_page
- raise Ably::Exceptions::InvalidPageError, 'There are no more pages' if supports_pagination? && last_page?
- PaginatedResource.new(client.get(pagination_url('next')), base_url, client, coerce_into: coerce_into, &each_block)
+ # @return [PaginatedResource,EventMachine::Deferrable]
+ def next_page(&success_callback)
+ async_wrap_if(make_async, success_callback) do
+ raise Ably::Exceptions::InvalidPageError, 'There are no more pages' if supports_pagination? && last_page?
+ PaginatedResource.new(client.get(pagination_url('next')), base_url, client, pagination_options, &each_block)
+ end
end
# True if this is the last page in the paged resource set
#
# @return [Boolean]
@@ -82,22 +94,22 @@
body.length
end
alias_method :count, :length
alias_method :size, :length
- # Method ensuring this {PaginatedResource} is {http://ruby-doc.org/core-2.1.3/Enumerable.html Enumerable}
+ # Method to allow {PaginatedResource} to be {http://ruby-doc.org/core-2.1.3/Enumerable.html Enumerable}
def each(&block)
body.each do |item|
if block_given?
block.call item
else
yield item
end
end
end
- # Last item in this page
+ # First item in this page
def first
body.first
end
# Last item in this page
@@ -116,11 +128,11 @@
>
EOF
end
private
- attr_reader :body, :http_response, :base_url, :client, :coerce_into, :raw_body, :each_block
+ attr_reader :body, :http_response, :base_url, :client, :coerce_into, :raw_body, :each_block, :make_async
def pagination_headers
link_regex = %r{<(?<url>[^>]+)>; rel="(?<rel>[^"]+)"}
@pagination_headers ||= begin
# All `Link:` headers are concatenated by Faraday into a comma separated list
@@ -142,9 +154,24 @@
if pagination_header(id).match(%r{^\./})
"#{base_url}#{pagination_header(id)[2..-1]}"
else
pagination_header[id]
+ end
+ end
+
+ def pagination_options
+ {
+ coerce_into: coerce_into,
+ async_blocking_operations: make_async
+ }
+ end
+
+ def async_wrap_if(is_realtime, success_callback, &operation)
+ if is_realtime
+ async_wrap success_callback, &operation
+ else
+ yield
end
end
end
end