Module: GRPC::GenericService::Dsl
- Defined in:
- lib/grpc/generic/service.rb
Overview
Provides a simple DSL to describe RPC services.
E.g, a Maths service that uses the serializable messages DivArgs, DivReply and Num might define its endpoint uses the following way:
rpc :div DivArgs, DivReply # single request, single response rpc :sum stream(Num), Num # streamed input, single response rpc :fib FibArgs, stream(Num) # single request, streamed response rpc :div_many stream(DivArgs), stream(DivReply)
# streamed req and resp
Each ‘rpc’ adds an RpcDesc to classes including this module, and #assert_rpc_descs_have_methods is used to ensure the including class provides methods with signatures that support all the descriptors.
Instance Attribute Summary collapse
-
#marshal_class_method ⇒ Object
the name of the instance method used to marshal events to a byte stream.
-
#service_name ⇒ Object
This allows configuration of the service name.
-
#unmarshal_class_method ⇒ Object
the name of the class method used to unmarshal from a byte stream.
Instance Method Summary collapse
- #assert_can_marshal(cls) ⇒ Object
-
#assert_rpc_descs_have_methods ⇒ Object
Asserts that the appropriate methods are defined for each added rpc spec.
- #inherited(subclass) ⇒ Object
-
#rpc(name, input, output) ⇒ Object
Adds an RPC spec.
-
#rpc_descs ⇒ Object
the RpcDescs defined for this GenericService, keyed by name.
-
#rpc_stub_class ⇒ Object
Creates a rpc client class with methods for accessing the methods currently in rpc_descs.
-
#stream(cls) ⇒ Object
Cls wrapped in a RpcDesc::Stream.
Instance Attribute Details
#marshal_class_method ⇒ Object
the name of the instance method used to marshal events to a byte stream.
126 127 128 |
# File 'lib/grpc/generic/service.rb', line 126 def marshal_class_method @marshal_class_method ||= :marshal end |
#service_name ⇒ Object
This allows configuration of the service name.
94 95 96 |
# File 'lib/grpc/generic/service.rb', line 94 def service_name @service_name end |
#unmarshal_class_method ⇒ Object
the name of the class method used to unmarshal from a byte stream.
131 132 133 |
# File 'lib/grpc/generic/service.rb', line 131 def unmarshal_class_method @unmarshal_class_method ||= :unmarshal end |
Instance Method Details
#assert_can_marshal(cls) ⇒ Object
135 136 137 138 139 140 141 142 143 144 |
# File 'lib/grpc/generic/service.rb', line 135 def assert_can_marshal(cls) cls = cls.type if cls.is_a? RpcDesc::Stream mth = unmarshal_class_method unless cls.methods.include? mth fail(ArgumentError, "#{cls} needs #{cls}.#{mth}") end mth = marshal_class_method return if cls.methods.include? mth fail(ArgumentError, "#{cls} needs #{cls}.#{mth}") end |
#assert_rpc_descs_have_methods ⇒ Object
Asserts that the appropriate methods are defined for each added rpc spec. Is intended to aid verifying that server classes are correctly implemented.
208 209 210 211 212 213 214 215 216 |
# File 'lib/grpc/generic/service.rb', line 208 def assert_rpc_descs_have_methods rpc_descs.each_pair do |m, spec| mth_name = m.to_s.underscore.to_sym unless instance_methods.include?(mth_name) fail "#{self} does not provide instance method '#{mth_name}'" end spec.assert_arity_matches(instance_method(mth_name)) end end |
#inherited(subclass) ⇒ Object
117 118 119 120 121 122 |
# File 'lib/grpc/generic/service.rb', line 117 def inherited(subclass) # Each subclass should have a distinct class variable with its own # rpc_descs subclass.rpc_descs.merge!(rpc_descs) subclass.service_name = service_name end |
#rpc(name, input, output) ⇒ Object
Adds an RPC spec.
Takes the RPC name and the classes representing the types to be serialized, and adds them to the including classes rpc_desc hash.
input and output should both have the methods #marshal and #unmarshal that are responsible for writing and reading an object instance from a byte buffer respectively.
108 109 110 111 112 113 114 115 |
# File 'lib/grpc/generic/service.rb', line 108 def rpc(name, input, output) fail(DuplicateRpcName, name) if rpc_descs.key? name assert_can_marshal(input) assert_can_marshal(output) rpc_descs[name] = RpcDesc.new(name, input, output, marshal_class_method, unmarshal_class_method) end |
#rpc_descs ⇒ Object
the RpcDescs defined for this GenericService, keyed by name.
154 155 156 |
# File 'lib/grpc/generic/service.rb', line 154 def rpc_descs @rpc_descs ||= {} end |
#rpc_stub_class ⇒ Object
Creates a rpc client class with methods for accessing the methods currently in rpc_descs.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/grpc/generic/service.rb', line 160 def rpc_stub_class descs = rpc_descs route_prefix = service_name Class.new(ClientStub) do # @param host [String] the host the stub connects to # @param kw [KeywordArgs] the channel arguments, plus any optional # args for configuring the client's channel def initialize(host, **kw) super(host, Core::CompletionQueue.new, **kw) end # Used define_method to add a method for each rpc_desc. Each method # calls the base class method for the given descriptor. descs.each_pair do |name, desc| mth_name = name.to_s.underscore.to_sym marshal = desc.marshal_proc unmarshal = desc.unmarshal_proc(:output) route = "/#{route_prefix}/#{name}" if desc.request_response? define_method(mth_name) do |req, deadline = nil, **kw| logger.debug("calling #{@host}:#{route}") request_response(route, req, marshal, unmarshal, deadline, **kw) end elsif desc.client_streamer? define_method(mth_name) do |reqs, deadline = nil, **kw| logger.debug("calling #{@host}:#{route}") client_streamer(route, reqs, marshal, unmarshal, deadline, **kw) end elsif desc.server_streamer? define_method(mth_name) do |req, deadline = nil, **kw, &blk| logger.debug("calling #{@host}:#{route}") server_streamer(route, req, marshal, unmarshal, deadline, **kw, &blk) end else # is a bidi_stream define_method(mth_name) do |reqs, deadline = nil, **kw, &blk| logger.debug("calling #{@host}:#{route}") bidi_streamer(route, reqs, marshal, unmarshal, deadline, **kw, &blk) end end end end end |