Class: Protocol::GRPC::Body::Writable

Inherits:
HTTP::Body::Writable
  • Object
show all
Defined in:
lib/protocol/grpc/body/writable.rb

Overview

Represents a writable body for gRPC messages with length-prefixed framing. This is the standard writable body for gRPC - all gRPC requests use message framing.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(encoding: nil, level: Zlib::DEFAULT_COMPRESSION, message_class: nil, **options) ⇒ Writable

Initialize a new writable body for gRPC messages.



24
25
26
27
28
29
# File 'lib/protocol/grpc/body/writable.rb', line 24

def initialize(encoding: nil, level: Zlib::DEFAULT_COMPRESSION, message_class: nil, **options)
	super(**options)
	@encoding = encoding
	@level = level
	@message_class = message_class
end

Instance Attribute Details

#encodingObject (readonly)

Returns the value of attribute encoding.



32
33
34
# File 'lib/protocol/grpc/body/writable.rb', line 32

def encoding
  @encoding
end

#message_classObject (readonly)

Returns the value of attribute message_class.



35
36
37
# File 'lib/protocol/grpc/body/writable.rb', line 35

def message_class
  @message_class
end

#The compression encoding.(compressionencoding.) ⇒ Object (readonly)



32
# File 'lib/protocol/grpc/body/writable.rb', line 32

attr_reader :encoding

Instance Method Details

#The expected message class for validation.=(expectedmessage) ⇒ Object



35
# File 'lib/protocol/grpc/body/writable.rb', line 35

attr_reader :message_class

#write(message, compressed: nil) ⇒ Object

Write a message with gRPC framing.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/protocol/grpc/body/writable.rb', line 40

def write(message, compressed: nil)
	# Validate message type if message_class is specified:
	if @message_class && !message.is_a?(String)
		unless message.is_a?(@message_class)
			raise TypeError, "Expected #{@message_class}, got #{message.class}"
		end
	end
	
	# Encode message to binary if it's not already a string:
	# This supports both high-level (protobuf objects) and low-level (binary) usage
	data = if message.is_a?(String)
		message # Already binary, use as-is (for channel adapters)
	elsif message.respond_to?(:to_proto)
		# Use protobuf gem's to_proto method:
		message.to_proto
	elsif message.respond_to?(:encode)
		# Use encode method:
		message.encode
	else
		raise ArgumentError, "Message must respond to :to_proto or :encode"
	end
	
	# Determine if we should compress this message:
	# If compressed param is nil, use the encoding setting
	should_compress = compressed.nil? ? (@encoding && @encoding != "identity") : compressed
	
	# Compress if requested:
	data = compress(data) if should_compress
	
	# Build prefix: compression flag + length
	compression_flag = should_compress ? 1 : 0
	length = data.bytesize
	prefix = [compression_flag].pack("C") + [length].pack("N")
	
	# Write prefix + data to underlying body:
	super(prefix + data) # Call Protocol::HTTP::Body::Writable#write
end