protobuf 3.7.0.pre2 → 3.7.0.pre3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -1
- data/.rubocop_todo.yml +7 -1
- data/.travis.yml +8 -1
- data/CHANGES.md +25 -1
- data/bin/protoc-gen-ruby +2 -2
- data/lib/protobuf/cli.rb +29 -17
- data/lib/protobuf/code_generator.rb +49 -1
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +9 -1
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +14 -1
- data/lib/protobuf/encoder.rb +2 -2
- data/lib/protobuf/enum.rb +3 -3
- data/lib/protobuf/field/base_field.rb +27 -19
- data/lib/protobuf/field/bool_field.rb +10 -8
- data/lib/protobuf/field/bytes_field.rb +14 -6
- data/lib/protobuf/field/float_field.rb +2 -0
- data/lib/protobuf/field/string_field.rb +10 -0
- data/lib/protobuf/field/varint_field.rb +12 -2
- data/lib/protobuf/generators/base.rb +29 -14
- data/lib/protobuf/generators/enum_generator.rb +4 -7
- data/lib/protobuf/generators/field_generator.rb +17 -4
- data/lib/protobuf/generators/file_generator.rb +121 -10
- data/lib/protobuf/generators/group_generator.rb +9 -3
- data/lib/protobuf/generators/message_generator.rb +8 -2
- data/lib/protobuf/generators/option_generator.rb +17 -0
- data/lib/protobuf/generators/printable.rb +2 -2
- data/lib/protobuf/generators/service_generator.rb +27 -3
- data/lib/protobuf/lifecycle.rb +1 -1
- data/lib/protobuf/message/fields.rb +13 -15
- data/lib/protobuf/message/serialization.rb +9 -9
- data/lib/protobuf/message.rb +23 -29
- data/lib/protobuf/optionable.rb +10 -10
- data/lib/protobuf/rpc/buffer.rb +7 -6
- data/lib/protobuf/rpc/client.rb +2 -30
- data/lib/protobuf/rpc/connectors/base.rb +168 -6
- data/lib/protobuf/rpc/connectors/ping.rb +2 -2
- data/lib/protobuf/rpc/connectors/socket.rb +6 -1
- data/lib/protobuf/rpc/connectors/zmq.rb +1 -2
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +2 -1
- data/lib/protobuf/rpc/error.rb +2 -2
- data/lib/protobuf/rpc/middleware/exception_handler.rb +4 -0
- data/lib/protobuf/rpc/middleware/logger.rb +4 -0
- data/lib/protobuf/rpc/middleware/request_decoder.rb +11 -16
- data/lib/protobuf/rpc/middleware/response_encoder.rb +18 -23
- data/lib/protobuf/rpc/rpc.pb.rb +2 -1
- data/lib/protobuf/rpc/rpc_method.rb +16 -0
- data/lib/protobuf/rpc/servers/socket/server.rb +4 -4
- data/lib/protobuf/rpc/servers/socket_runner.rb +8 -0
- data/lib/protobuf/rpc/servers/zmq/broker.rb +7 -6
- data/lib/protobuf/rpc/servers/zmq/server.rb +8 -7
- data/lib/protobuf/rpc/servers/zmq/util.rb +6 -6
- data/lib/protobuf/rpc/servers/zmq/worker.rb +7 -6
- data/lib/protobuf/rpc/servers/zmq_runner.rb +8 -0
- data/lib/protobuf/rpc/service.rb +6 -15
- data/lib/protobuf/rpc/service_directory.rb +1 -1
- data/lib/protobuf/rpc/service_dispatcher.rb +5 -6
- data/lib/protobuf/rpc/service_filters.rb +8 -30
- data/lib/protobuf/socket.rb +2 -2
- data/lib/protobuf/version.rb +1 -1
- data/lib/protobuf/zmq.rb +2 -2
- data/lib/protobuf.rb +12 -27
- data/protobuf.gemspec +5 -3
- data/spec/benchmark/tasks.rb +1 -0
- data/spec/functional/code_generator_spec.rb +38 -0
- data/spec/lib/protobuf/cli_spec.rb +19 -10
- data/spec/lib/protobuf/code_generator_spec.rb +28 -0
- data/spec/lib/protobuf/enum_spec.rb +6 -2
- data/spec/lib/protobuf/field/bool_field_spec.rb +4 -0
- data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/float_field_spec.rb +5 -1
- data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/message_field_spec.rb +53 -0
- data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
- data/spec/lib/protobuf/generators/base_spec.rb +69 -1
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +1 -1
- data/spec/lib/protobuf/generators/field_generator_spec.rb +58 -0
- data/spec/lib/protobuf/generators/file_generator_spec.rb +47 -0
- data/spec/lib/protobuf/generators/service_generator_spec.rb +58 -14
- data/spec/lib/protobuf/message_spec.rb +2 -2
- data/spec/lib/protobuf/optionable_spec.rb +96 -0
- data/spec/lib/protobuf/rpc/connectors/base_spec.rb +151 -0
- data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +3 -3
- data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +0 -2
- data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +2 -2
- data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +4 -4
- data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +2 -2
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +1 -18
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +2 -2
- data/spec/lib/protobuf/varint_spec.rb +1 -1
- data/spec/lib/protobuf_spec.rb +13 -16
- data/spec/support/packed_field.rb +3 -2
- data/spec/support/protos/enum.pb.rb +2 -1
- data/spec/support/protos/enum.proto +1 -0
- data/spec/support/protos/google_unittest.pb.rb +69 -58
- data/spec/support/protos/google_unittest_custom_options.bin +0 -0
- data/spec/support/protos/google_unittest_custom_options.pb.rb +361 -0
- data/spec/support/protos/google_unittest_custom_options.proto +424 -0
- data/spec/support/protos/google_unittest_import.pb.rb +8 -0
- data/spec/support/protos/google_unittest_import_public.pb.rb +6 -0
- data/spec/support/protos/resource.pb.rb +54 -2
- data/spec/support/protos/resource.proto +42 -2
- data/spec/support/server.rb +1 -1
- metadata +39 -16
- data/lib/protobuf/rpc/connector.rb +0 -19
- data/lib/protobuf/rpc/connectors/common.rb +0 -176
- data/spec/lib/protobuf/rpc/connector_spec.rb +0 -26
- data/spec/lib/protobuf/rpc/connectors/common_spec.rb +0 -170
data/lib/protobuf/optionable.rb
CHANGED
@@ -10,11 +10,12 @@ module Protobuf
|
|
10
10
|
# are accessing options correctly. We allow simple names in other places for backwards compatibility.
|
11
11
|
fail ArgumentError, "must access option using its fully qualified name: #{option.fully_qualified_name.inspect}"
|
12
12
|
end
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
value =
|
14
|
+
if @_optionable_options.try(:key?, name)
|
15
|
+
@_optionable_options[name]
|
16
|
+
else
|
17
|
+
option.default_value
|
18
|
+
end
|
18
19
|
if option.type_class < ::Protobuf::Message
|
19
20
|
option.type_class.new(value)
|
20
21
|
else
|
@@ -51,11 +52,10 @@ module Protobuf
|
|
51
52
|
# File options are injected per module, and since a module can be defined more than once,
|
52
53
|
# we will get a warning if we try to define optionable_descriptor_class twice.
|
53
54
|
if base_class.respond_to?(:optionable_descriptor_class)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
55
|
+
# Don't define optionable_descriptor_class twice
|
56
|
+
return if base_class.optionable_descriptor_class == block.call
|
57
|
+
|
58
|
+
fail 'A class is being defined with two different descriptor classes, something is very wrong'
|
59
59
|
end
|
60
60
|
|
61
61
|
base_class.extend(ClassMethods)
|
data/lib/protobuf/rpc/buffer.rb
CHANGED
@@ -4,7 +4,7 @@ module Protobuf
|
|
4
4
|
|
5
5
|
attr_accessor :mode, :data, :size
|
6
6
|
|
7
|
-
MODES = [:read, :write]
|
7
|
+
MODES = [:read, :write].freeze
|
8
8
|
|
9
9
|
# constantize this so we don't re-initialize the regex every time we need it
|
10
10
|
SIZE_REGEX = /^\d+-/
|
@@ -17,11 +17,12 @@ module Protobuf
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def mode=(mode)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
@mode =
|
21
|
+
if MODES.include?(mode)
|
22
|
+
mode
|
23
|
+
else
|
24
|
+
:read
|
25
|
+
end
|
25
26
|
end
|
26
27
|
|
27
28
|
def write(force_mode = true)
|
data/lib/protobuf/rpc/client.rb
CHANGED
@@ -2,7 +2,6 @@ require 'forwardable'
|
|
2
2
|
require 'protobuf'
|
3
3
|
require 'protobuf/logging'
|
4
4
|
require 'protobuf/rpc/error'
|
5
|
-
require 'protobuf/rpc/connector'
|
6
5
|
|
7
6
|
module Protobuf
|
8
7
|
module Rpc
|
@@ -10,7 +9,7 @@ module Protobuf
|
|
10
9
|
extend Forwardable
|
11
10
|
include Protobuf::Logging
|
12
11
|
|
13
|
-
def_delegators :@connector, :options, :complete_cb, :success_cb, :failure_cb
|
12
|
+
def_delegators :@connector, :options, :complete_cb, :success_cb, :failure_cb, :send_request
|
14
13
|
attr_reader :connector
|
15
14
|
|
16
15
|
# Create a new client with default options (defined in ClientConnection)
|
@@ -28,7 +27,7 @@ module Protobuf
|
|
28
27
|
#
|
29
28
|
def initialize(options = {})
|
30
29
|
fail "Invalid client configuration. Service must be defined." if options[:service].nil?
|
31
|
-
@connector =
|
30
|
+
@connector = ::Protobuf.connector_type_class.new(options)
|
32
31
|
logger.debug { sign_message("Initialized with options: #{options.inspect}") }
|
33
32
|
end
|
34
33
|
|
@@ -134,33 +133,6 @@ module Protobuf
|
|
134
133
|
end
|
135
134
|
end
|
136
135
|
|
137
|
-
# Send the request to the service.
|
138
|
-
# This method is usually never called directly
|
139
|
-
# but is invoked by method_missing (see docs above).
|
140
|
-
#
|
141
|
-
# request = WidgetFindRequest.new
|
142
|
-
# client = Client.new({
|
143
|
-
# :service => WidgetService,
|
144
|
-
# :method => "find",
|
145
|
-
# :request_type => "WidgetFindRequest",
|
146
|
-
# :response_type => "WidgetList",
|
147
|
-
# :request => request
|
148
|
-
# })
|
149
|
-
#
|
150
|
-
# client.on_success do |res|
|
151
|
-
# res.widgets.each{|w| puts w.inspect }
|
152
|
-
# end
|
153
|
-
#
|
154
|
-
# client.on_failure do |err|
|
155
|
-
# puts err.message
|
156
|
-
# end
|
157
|
-
#
|
158
|
-
# client.send_request
|
159
|
-
#
|
160
|
-
def send_request
|
161
|
-
@connector.send_request
|
162
|
-
end
|
163
|
-
|
164
136
|
end
|
165
137
|
|
166
138
|
ActiveSupport.run_load_hooks(:protobuf_rpc_client, Client)
|
@@ -4,7 +4,6 @@ require 'protobuf/rpc/rpc.pb'
|
|
4
4
|
require 'protobuf/rpc/buffer'
|
5
5
|
require 'protobuf/rpc/error'
|
6
6
|
require 'protobuf/rpc/stat'
|
7
|
-
require 'protobuf/rpc/connectors/common'
|
8
7
|
|
9
8
|
module Protobuf
|
10
9
|
module Rpc
|
@@ -20,26 +19,113 @@ module Protobuf
|
|
20
19
|
:timeout => nil, # The timeout for the request, also handled by client.rb
|
21
20
|
:client_host => nil, # The hostname or address of this client
|
22
21
|
:first_alive_load_balance => false, # Do we want to use check_avail frames before request
|
23
|
-
}
|
22
|
+
}.freeze
|
24
23
|
|
25
24
|
class Base
|
26
25
|
include Protobuf::Logging
|
27
26
|
|
28
|
-
attr_reader :options
|
29
|
-
attr_accessor :success_cb, :failure_cb, :complete_cb
|
27
|
+
attr_reader :options, :error
|
28
|
+
attr_accessor :success_cb, :failure_cb, :complete_cb, :stats
|
30
29
|
|
31
30
|
def initialize(options)
|
32
31
|
@options = DEFAULT_OPTIONS.merge(options)
|
33
32
|
@stats = ::Protobuf::Rpc::Stat.new(:CLIENT)
|
34
33
|
end
|
35
34
|
|
35
|
+
def any_callbacks?
|
36
|
+
[@complete_cb, @failure_cb, @success_cb].any?
|
37
|
+
end
|
38
|
+
|
39
|
+
def close_connection
|
40
|
+
fail 'If you inherit a Connector from Base you must implement close_connection'
|
41
|
+
end
|
42
|
+
|
43
|
+
def complete
|
44
|
+
@stats.stop
|
45
|
+
logger.info { @stats.to_s }
|
46
|
+
logger.debug { sign_message('Response proceessing complete') }
|
47
|
+
@complete_cb.call(self) unless @complete_cb.nil?
|
48
|
+
rescue => e
|
49
|
+
logger.error { sign_message('Complete callback error encountered') }
|
50
|
+
log_exception(e)
|
51
|
+
raise
|
52
|
+
end
|
53
|
+
|
54
|
+
def data_callback(data)
|
55
|
+
logger.debug { sign_message('Using data_callback') }
|
56
|
+
@used_data_callback = true
|
57
|
+
@data = data
|
58
|
+
end
|
59
|
+
|
60
|
+
# All failures should be routed through this method.
|
61
|
+
#
|
62
|
+
# @param [Symbol] code The code we're using (see ::Protobuf::Socketrpc::ErrorReason)
|
63
|
+
# @param [String] message The error message
|
64
|
+
def failure(code, message)
|
65
|
+
@error = ClientError.new
|
66
|
+
@error.code = ::Protobuf::Socketrpc::ErrorReason.fetch(code)
|
67
|
+
@error.message = message
|
68
|
+
logger.debug { sign_message("Server failed request (invoking on_failure): #{@error.inspect}") }
|
69
|
+
|
70
|
+
@failure_cb.call(@error) unless @failure_cb.nil?
|
71
|
+
rescue => e
|
72
|
+
logger.error { sign_message("Failure callback error encountered") }
|
73
|
+
log_exception(e)
|
74
|
+
raise
|
75
|
+
ensure
|
76
|
+
complete
|
77
|
+
end
|
78
|
+
|
36
79
|
def first_alive_load_balance?
|
37
80
|
ENV.key?("PB_FIRST_ALIVE_LOAD_BALANCE") ||
|
38
81
|
options[:first_alive_load_balance]
|
39
82
|
end
|
40
83
|
|
41
|
-
def
|
42
|
-
|
84
|
+
def initialize_stats
|
85
|
+
@stats = ::Protobuf::Rpc::Stat.new(:CLIENT)
|
86
|
+
@stats.server = [@options[:port], @options[:host]]
|
87
|
+
@stats.service = @options[:service].name
|
88
|
+
@stats.method_name = @options[:method].to_s
|
89
|
+
rescue => ex
|
90
|
+
log_exception(ex)
|
91
|
+
failure(:RPC_ERROR, "Invalid stats configuration. #{ex.message}")
|
92
|
+
end
|
93
|
+
|
94
|
+
def log_signature
|
95
|
+
@_log_signature ||= "[client-#{self.class}]"
|
96
|
+
end
|
97
|
+
|
98
|
+
def parse_response
|
99
|
+
# Close up the connection as we no longer need it
|
100
|
+
close_connection
|
101
|
+
|
102
|
+
logger.debug { sign_message("Parsing response from server (connection closed)") }
|
103
|
+
|
104
|
+
# Parse out the raw response
|
105
|
+
@stats.response_size = @response_data.size unless @response_data.nil?
|
106
|
+
response_wrapper = ::Protobuf::Socketrpc::Response.decode(@response_data)
|
107
|
+
|
108
|
+
# Determine success or failure based on parsed data
|
109
|
+
if response_wrapper.field?(:error_reason)
|
110
|
+
logger.debug { sign_message("Error response parsed") }
|
111
|
+
|
112
|
+
# fail the call if we already know the client is failed
|
113
|
+
# (don't try to parse out the response payload)
|
114
|
+
failure(response_wrapper.error_reason, response_wrapper.error)
|
115
|
+
else
|
116
|
+
logger.debug { sign_message("Successful response parsed") }
|
117
|
+
|
118
|
+
# Ensure client_response is an instance
|
119
|
+
parsed = @options[:response_type].decode(response_wrapper.response_proto.to_s)
|
120
|
+
|
121
|
+
if parsed.nil? && !response_wrapper.field?(:error_reason)
|
122
|
+
failure(:BAD_RESPONSE_PROTO, 'Unable to parse response from server')
|
123
|
+
else
|
124
|
+
verify_callbacks
|
125
|
+
succeed(parsed)
|
126
|
+
return @data if @used_data_callback
|
127
|
+
end
|
128
|
+
end
|
43
129
|
end
|
44
130
|
|
45
131
|
def ping_port
|
@@ -49,6 +135,82 @@ module Protobuf
|
|
49
135
|
def ping_port_enabled?
|
50
136
|
ENV.key?("PB_RPC_PING_PORT")
|
51
137
|
end
|
138
|
+
|
139
|
+
def request_bytes
|
140
|
+
validate_request_type!
|
141
|
+
fields = { :service_name => @options[:service].name,
|
142
|
+
:method_name => @options[:method].to_s,
|
143
|
+
:request_proto => @options[:request],
|
144
|
+
:caller => request_caller }
|
145
|
+
|
146
|
+
return ::Protobuf::Socketrpc::Request.encode(fields)
|
147
|
+
rescue => e
|
148
|
+
failure(:INVALID_REQUEST_PROTO, "Could not set request proto: #{e.message}")
|
149
|
+
end
|
150
|
+
|
151
|
+
def request_caller
|
152
|
+
@options[:client_host] || ::Protobuf.client_host
|
153
|
+
end
|
154
|
+
|
155
|
+
def send_request
|
156
|
+
fail 'If you inherit a Connector from Base you must implement send_request'
|
157
|
+
end
|
158
|
+
|
159
|
+
def setup_connection
|
160
|
+
initialize_stats
|
161
|
+
@request_data = request_bytes
|
162
|
+
@stats.request_size = @request_data.size
|
163
|
+
end
|
164
|
+
|
165
|
+
def succeed(response)
|
166
|
+
logger.debug { sign_message("Server succeeded request (invoking on_success)") }
|
167
|
+
@success_cb.call(response) unless @success_cb.nil?
|
168
|
+
rescue => e
|
169
|
+
logger.error { sign_message("Success callback error encountered") }
|
170
|
+
log_exception(e)
|
171
|
+
failure(:RPC_ERROR, "An exception occurred while calling on_success: #{e.message}")
|
172
|
+
ensure
|
173
|
+
complete
|
174
|
+
end
|
175
|
+
|
176
|
+
def timeout
|
177
|
+
if options[:timeout]
|
178
|
+
options[:timeout]
|
179
|
+
else
|
180
|
+
300 # seconds
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Wrap the given block in a timeout of the configured number of seconds.
|
185
|
+
#
|
186
|
+
def timeout_wrap(&block)
|
187
|
+
::Timeout.timeout(timeout, &block)
|
188
|
+
rescue ::Timeout::Error
|
189
|
+
failure(:RPC_FAILED, "The server took longer than #{timeout} seconds to respond")
|
190
|
+
end
|
191
|
+
|
192
|
+
def validate_request_type!
|
193
|
+
unless @options[:request].class == @options[:request_type]
|
194
|
+
expected = @options[:request_type].name
|
195
|
+
actual = @options[:request].class.name
|
196
|
+
failure(:INVALID_REQUEST_PROTO, "Expected request type to be type of #{expected}, got #{actual} instead")
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def verify_callbacks
|
201
|
+
unless any_callbacks?
|
202
|
+
logger.debug { sign_message("No callbacks set, using data_callback") }
|
203
|
+
@success_cb = @failure_cb = method(:data_callback)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def verify_options!
|
208
|
+
# Verify the options that are necessary and merge them in
|
209
|
+
[:service, :method, :host, :port].each do |opt|
|
210
|
+
failure(:RPC_ERROR, "Invalid client connection configuration. #{opt} must be a defined option.") if @options[opt].nil?
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
52
214
|
end
|
53
215
|
end
|
54
216
|
end
|
@@ -4,7 +4,6 @@ module Protobuf
|
|
4
4
|
module Rpc
|
5
5
|
module Connectors
|
6
6
|
class Socket < Base
|
7
|
-
include Protobuf::Rpc::Connectors::Common
|
8
7
|
include Protobuf::Logging
|
9
8
|
|
10
9
|
def send_request
|
@@ -39,6 +38,12 @@ module Protobuf
|
|
39
38
|
@socket.closed?
|
40
39
|
end
|
41
40
|
|
41
|
+
def post_init
|
42
|
+
send_data unless error?
|
43
|
+
rescue => e
|
44
|
+
failure(:RPC_ERROR, "Connection error: #{e.message}")
|
45
|
+
end
|
46
|
+
|
42
47
|
def read_data
|
43
48
|
size_io = StringIO.new
|
44
49
|
|
@@ -14,7 +14,6 @@ module Protobuf
|
|
14
14
|
##
|
15
15
|
# Included Modules
|
16
16
|
#
|
17
|
-
include Protobuf::Rpc::Connectors::Common
|
18
17
|
include Protobuf::Logging
|
19
18
|
|
20
19
|
##
|
@@ -271,7 +270,7 @@ module Protobuf
|
|
271
270
|
def zmq_eagain_error_check(return_code, source)
|
272
271
|
return if ::ZMQ::Util.resultcode_ok?(return_code || -1)
|
273
272
|
|
274
|
-
if ::ZMQ::Util.errno == ::ZMQ::EAGAIN
|
273
|
+
if ::ZMQ::Util.errno == ::ZMQ::EAGAIN # rubocop:disable Style/GuardClause
|
275
274
|
fail ZmqEagainError, <<-ERROR
|
276
275
|
Last ZMQ API call to #{source} failed with "#{::ZMQ::Util.error_string}".
|
277
276
|
|
@@ -3,11 +3,12 @@
|
|
3
3
|
##
|
4
4
|
# This file is auto-generated. DO NOT EDIT!
|
5
5
|
#
|
6
|
-
require 'protobuf
|
6
|
+
require 'protobuf'
|
7
7
|
|
8
8
|
module Protobuf
|
9
9
|
module Rpc
|
10
10
|
module DynamicDiscovery
|
11
|
+
::Protobuf::Optionable.inject(self) { ::Google::Protobuf::FileOptions }
|
11
12
|
|
12
13
|
##
|
13
14
|
# Enum Classes
|
data/lib/protobuf/rpc/error.rb
CHANGED
@@ -9,7 +9,7 @@ module Protobuf
|
|
9
9
|
attr_reader :error_type
|
10
10
|
|
11
11
|
def initialize(message = 'An unknown RpcError occurred', error_type = 'RPC_ERROR')
|
12
|
-
@error_type = error_type.is_a?(String) ? Socketrpc::ErrorReason.const_get(error_type) : error_type
|
12
|
+
@error_type = error_type.is_a?(String) ? ::Protobuf::Socketrpc::ErrorReason.const_get(error_type) : error_type
|
13
13
|
super message
|
14
14
|
end
|
15
15
|
|
@@ -18,7 +18,7 @@ module Protobuf
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def to_response
|
21
|
-
Socketrpc::Response.new(:error => message, :error_reason => error_type)
|
21
|
+
::Protobuf::Socketrpc::Response.new(:error => message, :error_reason => error_type)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -11,8 +11,13 @@ module Protobuf
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(env)
|
14
|
+
dup._call(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
def _call(env)
|
14
18
|
@env = env
|
15
19
|
|
20
|
+
logger.debug { sign_message("Decoding request: #{env.encoded_request}") }
|
16
21
|
env.service_name = service_name
|
17
22
|
env.method_name = method_name
|
18
23
|
env.request = request
|
@@ -33,22 +38,15 @@ module Protobuf
|
|
33
38
|
private
|
34
39
|
|
35
40
|
def method_name
|
36
|
-
@method_name
|
37
|
-
method_name = request_wrapper.method_name.underscore.to_sym
|
38
|
-
|
39
|
-
unless service.rpc_method?(method_name)
|
40
|
-
fail MethodNotFound, "#{service.name}##{method_name} is not a defined RPC method."
|
41
|
-
end
|
41
|
+
return @method_name unless @method_name.nil?
|
42
42
|
|
43
|
-
|
44
|
-
|
43
|
+
@method_name = request_wrapper.method_name.underscore.to_sym
|
44
|
+
fail MethodNotFound, "#{service.name}##{@method_name} is not a defined RPC method." unless service.rpc_method?(@method_name)
|
45
|
+
@method_name
|
45
46
|
end
|
46
47
|
|
47
48
|
def request
|
48
|
-
@request ||=
|
49
|
-
data = request_wrapper.request_proto
|
50
|
-
rpc_method.request_type.decode(data)
|
51
|
-
end
|
49
|
+
@request ||= rpc_method.request_type.decode(request_wrapper.request_proto)
|
52
50
|
rescue => exception
|
53
51
|
raise BadRequestData, "Unable to decode request: #{exception.message}"
|
54
52
|
end
|
@@ -56,10 +54,7 @@ module Protobuf
|
|
56
54
|
# Decode the incoming request object into our expected request object
|
57
55
|
#
|
58
56
|
def request_wrapper
|
59
|
-
@request_wrapper ||=
|
60
|
-
logger.debug { sign_message("Decoding request: #{env.encoded_request}") }
|
61
|
-
Socketrpc::Request.decode(env.encoded_request)
|
62
|
-
end
|
57
|
+
@request_wrapper ||= ::Protobuf::Socketrpc::Request.decode(env.encoded_request)
|
63
58
|
rescue => exception
|
64
59
|
raise BadRequestData, "Unable to decode request: #{exception.message}"
|
65
60
|
end
|
@@ -11,6 +11,10 @@ module Protobuf
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(env)
|
14
|
+
dup._call(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
def _call(env)
|
14
18
|
@env = app.call(env)
|
15
19
|
|
16
20
|
env.response = response
|
@@ -41,32 +45,23 @@ module Protobuf
|
|
41
45
|
# Prod the object to see if we can produce a proto object as a response
|
42
46
|
# candidate. Validate the candidate protos.
|
43
47
|
def response
|
44
|
-
@response
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
when candidate.is_a?(PbError) then
|
54
|
-
candidate
|
55
|
-
else
|
56
|
-
validate!(candidate)
|
57
|
-
end
|
58
|
-
end
|
48
|
+
return @response unless @response.nil?
|
49
|
+
|
50
|
+
candidate = env.response
|
51
|
+
return @response = validate!(candidate) if candidate.is_a?(Message)
|
52
|
+
return @response = validate!(candidate.to_proto) if candidate.respond_to?(:to_proto)
|
53
|
+
return @response = env.response_type.new(candidate.to_hash) if candidate.respond_to?(:to_hash)
|
54
|
+
return @response = candidate if candidate.is_a?(PbError)
|
55
|
+
|
56
|
+
@response = validate!(candidate)
|
59
57
|
end
|
60
58
|
|
61
59
|
# Ensure that the response candidate we've been given is of the type
|
62
60
|
# we expect so that deserialization on the client side works.
|
63
61
|
#
|
64
62
|
def validate!(candidate)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
if expected != actual
|
69
|
-
fail BadResponseProto, "Expected response to be of type #{expected.name} but was #{actual.name}"
|
63
|
+
if candidate.class != env.response_type
|
64
|
+
fail BadResponseProto, "Expected response to be of type #{env.response_type.name} but was #{candidate.class.name}"
|
70
65
|
end
|
71
66
|
|
72
67
|
candidate
|
@@ -76,10 +71,10 @@ module Protobuf
|
|
76
71
|
# it up so that it's in the correct spot in the response wrapper
|
77
72
|
#
|
78
73
|
def wrapped_response
|
79
|
-
if response.is_a?(Protobuf::Rpc::PbError)
|
80
|
-
Socketrpc::Response.new(:error => response.message, :error_reason => response.error_type)
|
74
|
+
if response.is_a?(::Protobuf::Rpc::PbError)
|
75
|
+
::Protobuf::Socketrpc::Response.new(:error => response.message, :error_reason => response.error_type)
|
81
76
|
else
|
82
|
-
Socketrpc::Response.new(:response_proto => response.encode)
|
77
|
+
::Protobuf::Socketrpc::Response.new(:response_proto => response.encode)
|
83
78
|
end
|
84
79
|
end
|
85
80
|
end
|
data/lib/protobuf/rpc/rpc.pb.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Protobuf
|
2
|
+
module Rpc
|
3
|
+
class RpcMethod
|
4
|
+
::Protobuf::Optionable.inject(self, false) { ::Google::Protobuf::MethodOptions }
|
5
|
+
|
6
|
+
attr_reader :method, :request_type, :response_type
|
7
|
+
|
8
|
+
def initialize(method, request_type, response_type, &options_block)
|
9
|
+
@method = method
|
10
|
+
@request_type = request_type
|
11
|
+
@response_type = response_type
|
12
|
+
instance_eval(&options_block) if options_block
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -18,7 +18,7 @@ module Protobuf
|
|
18
18
|
public
|
19
19
|
|
20
20
|
attr_reader :running
|
21
|
-
|
21
|
+
alias :running? running
|
22
22
|
|
23
23
|
def initialize(options)
|
24
24
|
self.running = false
|
@@ -38,7 +38,7 @@ module Protobuf
|
|
38
38
|
|
39
39
|
def cleanup?
|
40
40
|
# every `threshold` connections run a cleanup routine after closing the response
|
41
|
-
threads.
|
41
|
+
!threads.empty? && threads.size % threshold == 0
|
42
42
|
end
|
43
43
|
|
44
44
|
def cleanup_threads
|
@@ -102,9 +102,9 @@ module Protobuf
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
end
|
105
|
-
|
105
|
+
elsif threads.size > 1
|
106
106
|
# Run a cleanup if select times out while waiting
|
107
|
-
cleanup_threads
|
107
|
+
cleanup_threads
|
108
108
|
end
|
109
109
|
end
|
110
110
|
ensure
|
@@ -107,11 +107,12 @@ module Protobuf
|
|
107
107
|
end
|
108
108
|
|
109
109
|
def init_zmq_context
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
110
|
+
@zmq_context =
|
111
|
+
if inproc?
|
112
|
+
@server.zmq_context
|
113
|
+
else
|
114
|
+
ZMQ::Context.new
|
115
|
+
end
|
115
116
|
end
|
116
117
|
|
117
118
|
def inproc?
|
@@ -146,7 +147,7 @@ module Protobuf
|
|
146
147
|
write_to_frontend([address, ::Protobuf::Rpc::Zmq::EMPTY_STRING, ::Protobuf::Rpc::Zmq::NO_WORKERS_AVAILABLE])
|
147
148
|
end
|
148
149
|
else
|
149
|
-
if @idle_workers.empty?
|
150
|
+
if @idle_workers.empty? # rubocop:disable Style/IfInsideElse
|
150
151
|
local_queue << [address, ::Protobuf::Rpc::Zmq::EMPTY_STRING, message].concat(frames)
|
151
152
|
else
|
152
153
|
write_to_backend([@idle_workers.shift, ::Protobuf::Rpc::Zmq::EMPTY_STRING].concat([address, ::Protobuf::Rpc::Zmq::EMPTY_STRING, message]).concat(frames))
|