def push(value, opts={})
      topic = opts[:topic] || @topic
      result = nil

      if value.kind_of? Array
        return value.map { |e| self.push(e, opts) }
      end

      if Hermann.jruby?
        result = @internal.push_single(value, topic, opts[:partition_key], nil)
        unless result.nil?
          @children << result
        end
        # Reaping children on the push just to make sure that it does get
        # called correctly and we don't leak memory
        reap_children
      else
        # Ticking reactor to make sure that we don't inadvertantly let the
        # librdkafka callback queue overflow
        tick_reactor
        result = create_result
        @internal.push_single(value, topic, opts[:partition_key].to_s, result)
      end

      return result
    end
def push(value, opts={})
      topic = opts[:topic] || @topic
      result = nil

      if value.kind_of? Array
        return value.map { |e| self.push(e, opts) }
      end

      if Hermann.jruby?
        result = @internal.push_single(value, topic, opts[:partition_key], nil)
        unless result.nil?
          @children << result
        end
        # Reaping children on the push just to make sure that it does get
        # called correctly and we don't leak memory
        reap_children
      else
        # Ticking reactor to make sure that we don't inadvertantly let the
        # librdkafka callback queue overflow
        tick_reactor
        result = create_result
        @internal.push_single(value, topic, opts[:partition_key].to_s, result)
      end

      return result
    end
Push a value onto the Kafka topic passed to this +Producer+

 @param [Object] value A single object to push
 @param [Hash] opts to pass to push method
 @option opts [String] :topic The topic to push messages to
                       :partition_key The string to partition by

 @return [Hermann::Result] A future-like object which will store the
   result from the broker