class Gapic::Rest::ServerStream


server_stream.each { |response| puts response }
@example normal iteration over resources.
ServerStream provides the enumerations over the individual response messages within the stream.
A class to provide the Enumerable interface to the response of a REST server-streaming dmethod.
#

def each

Returns:
  • (Enumerator) - if no block is provided

Other tags:
    Yield: - Gives one complete Message object.
def each
  return enum_for :each unless block_given?
  loop do
    while @ready_objs.empty?
      begin
        chunk = @json_enumerator.next
        next unless chunk
        next_json! chunk
      rescue StopIteration
        dangling_content = @obj.strip
        error_expl = "Dangling content left after iterating through the stream. " \
                     "This means that not all content was received or parsed correctly. " \
                     "It is likely a result of server or network error."
        error_text = "#{error_expl}\n Content left unparsed: #{dangling_content}"
        raise Gapic::Common::Error, error_text unless dangling_content.empty?
        return
      end
    end
    yield @message_klass.decode_json @ready_objs.shift, ignore_unknown_fields: true
  end
end

def initialize message_klass, json_enumerator

Parameters:
  • json_enumerator (Enumerator) --
  • message_klass (Class) --
def initialize message_klass, json_enumerator
  @json_enumerator = json_enumerator
  @obj = ""
  @message_klass = message_klass
  @ready_objs = [] # List of strings
end

def next_json! chunk

Parameters:
  • chunk (String) -- Contains (partial) JSON object
def next_json! chunk
  chunk.chars.each do |char|
    # Invariant: @obj is always either a part of a single JSON object or the entire JSON object.
    # Hence, it's safe to strip whitespace, commans and array brackets. These characters
    # are only added before @obj is a complete JSON object and essentially can be flushed.
    next if @obj.empty? && char != "{"
    @obj += char
    next unless char == "}"
    begin
      # Two choices here: append a Ruby object into
      # ready_objs or a string. Going with the latter here.
      JSON.parse @obj
      @ready_objs.append @obj
      @obj = ""
    rescue JSON::ParserError
      next
    end
  end
end