def bidi_streamer(requests, metadata: {}, &blk)
      raise_error_if_already_executed
      # Metadata might have already been sent if this is an operation view
      begin
        send_initial_metadata(metadata)
      rescue GRPC::Core::CallError => e
        batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil)
        set_input_stream_done
        set_output_stream_done
        attach_status_results_and_complete_call(batch_result)
        raise e
      rescue => e
        set_input_stream_done
        set_output_stream_done
        raise e
      end

      bd = BidiCall.new(@call,
                        @marshal,
                        @unmarshal,
                        metadata_received: @metadata_received)

      bd.run_on_client(requests,
                       proc { set_input_stream_done },
                       proc { set_output_stream_done },
                       &blk)
    end
def bidi_streamer(requests, metadata: {}, &blk)
      raise_error_if_already_executed
      # Metadata might have already been sent if this is an operation view
      begin
        send_initial_metadata(metadata)
      rescue GRPC::Core::CallError => e
        batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil)
        set_input_stream_done
        set_output_stream_done
        attach_status_results_and_complete_call(batch_result)
        raise e
      rescue => e
        set_input_stream_done
        set_output_stream_done
        raise e
      end

      bd = BidiCall.new(@call,
                        @marshal,
                        @unmarshal,
                        metadata_received: @metadata_received)

      bd.run_on_client(requests,
                       proc { set_input_stream_done },
                       proc { set_output_stream_done },
                       &blk)
    end
bidi_streamer sends a stream of requests to the GRPC server, and yields
 a stream of responses.

 This method takes an Enumerable of requests, and returns and enumerable
 of responses.

 == requests ==

 requests provides an 'iterable' of Requests. I.e. it follows Ruby's
 #each enumeration protocol. In the simplest case, requests will be an
 array of marshallable objects; in typical case it will be an
 Enumerable that allows dynamic construction of the marshallable
 objects.

 == responses ==

 This is an enumerator of responses.  I.e, its #next method blocks
 waiting for the next response.  Also, if at any point the block needs
 to consume all the remaining responses, this can be done using #each or
 #collect.  Calling #each or #collect should only be done if
 the_call#writes_done has been called, otherwise the block will loop
 forever.

 @param requests [Object] an Enumerable of requests to send
 @param metadata [Hash] metadata to be sent to the server. If a value is
 a list, multiple metadata for its key are sent
 @return [Enumerator, nil] a response Enumerator