protobuf 3.7.0.pre2 → 3.7.0.pre3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -1
  3. data/.rubocop_todo.yml +7 -1
  4. data/.travis.yml +8 -1
  5. data/CHANGES.md +25 -1
  6. data/bin/protoc-gen-ruby +2 -2
  7. data/lib/protobuf/cli.rb +29 -17
  8. data/lib/protobuf/code_generator.rb +49 -1
  9. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +9 -1
  10. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +14 -1
  11. data/lib/protobuf/encoder.rb +2 -2
  12. data/lib/protobuf/enum.rb +3 -3
  13. data/lib/protobuf/field/base_field.rb +27 -19
  14. data/lib/protobuf/field/bool_field.rb +10 -8
  15. data/lib/protobuf/field/bytes_field.rb +14 -6
  16. data/lib/protobuf/field/float_field.rb +2 -0
  17. data/lib/protobuf/field/string_field.rb +10 -0
  18. data/lib/protobuf/field/varint_field.rb +12 -2
  19. data/lib/protobuf/generators/base.rb +29 -14
  20. data/lib/protobuf/generators/enum_generator.rb +4 -7
  21. data/lib/protobuf/generators/field_generator.rb +17 -4
  22. data/lib/protobuf/generators/file_generator.rb +121 -10
  23. data/lib/protobuf/generators/group_generator.rb +9 -3
  24. data/lib/protobuf/generators/message_generator.rb +8 -2
  25. data/lib/protobuf/generators/option_generator.rb +17 -0
  26. data/lib/protobuf/generators/printable.rb +2 -2
  27. data/lib/protobuf/generators/service_generator.rb +27 -3
  28. data/lib/protobuf/lifecycle.rb +1 -1
  29. data/lib/protobuf/message/fields.rb +13 -15
  30. data/lib/protobuf/message/serialization.rb +9 -9
  31. data/lib/protobuf/message.rb +23 -29
  32. data/lib/protobuf/optionable.rb +10 -10
  33. data/lib/protobuf/rpc/buffer.rb +7 -6
  34. data/lib/protobuf/rpc/client.rb +2 -30
  35. data/lib/protobuf/rpc/connectors/base.rb +168 -6
  36. data/lib/protobuf/rpc/connectors/ping.rb +2 -2
  37. data/lib/protobuf/rpc/connectors/socket.rb +6 -1
  38. data/lib/protobuf/rpc/connectors/zmq.rb +1 -2
  39. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +2 -1
  40. data/lib/protobuf/rpc/error.rb +2 -2
  41. data/lib/protobuf/rpc/middleware/exception_handler.rb +4 -0
  42. data/lib/protobuf/rpc/middleware/logger.rb +4 -0
  43. data/lib/protobuf/rpc/middleware/request_decoder.rb +11 -16
  44. data/lib/protobuf/rpc/middleware/response_encoder.rb +18 -23
  45. data/lib/protobuf/rpc/rpc.pb.rb +2 -1
  46. data/lib/protobuf/rpc/rpc_method.rb +16 -0
  47. data/lib/protobuf/rpc/servers/socket/server.rb +4 -4
  48. data/lib/protobuf/rpc/servers/socket_runner.rb +8 -0
  49. data/lib/protobuf/rpc/servers/zmq/broker.rb +7 -6
  50. data/lib/protobuf/rpc/servers/zmq/server.rb +8 -7
  51. data/lib/protobuf/rpc/servers/zmq/util.rb +6 -6
  52. data/lib/protobuf/rpc/servers/zmq/worker.rb +7 -6
  53. data/lib/protobuf/rpc/servers/zmq_runner.rb +8 -0
  54. data/lib/protobuf/rpc/service.rb +6 -15
  55. data/lib/protobuf/rpc/service_directory.rb +1 -1
  56. data/lib/protobuf/rpc/service_dispatcher.rb +5 -6
  57. data/lib/protobuf/rpc/service_filters.rb +8 -30
  58. data/lib/protobuf/socket.rb +2 -2
  59. data/lib/protobuf/version.rb +1 -1
  60. data/lib/protobuf/zmq.rb +2 -2
  61. data/lib/protobuf.rb +12 -27
  62. data/protobuf.gemspec +5 -3
  63. data/spec/benchmark/tasks.rb +1 -0
  64. data/spec/functional/code_generator_spec.rb +38 -0
  65. data/spec/lib/protobuf/cli_spec.rb +19 -10
  66. data/spec/lib/protobuf/code_generator_spec.rb +28 -0
  67. data/spec/lib/protobuf/enum_spec.rb +6 -2
  68. data/spec/lib/protobuf/field/bool_field_spec.rb +4 -0
  69. data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
  70. data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
  71. data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
  72. data/spec/lib/protobuf/field/float_field_spec.rb +5 -1
  73. data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
  74. data/spec/lib/protobuf/field/message_field_spec.rb +53 -0
  75. data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
  76. data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
  77. data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
  78. data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
  79. data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
  80. data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
  81. data/spec/lib/protobuf/generators/base_spec.rb +69 -1
  82. data/spec/lib/protobuf/generators/enum_generator_spec.rb +1 -1
  83. data/spec/lib/protobuf/generators/field_generator_spec.rb +58 -0
  84. data/spec/lib/protobuf/generators/file_generator_spec.rb +47 -0
  85. data/spec/lib/protobuf/generators/service_generator_spec.rb +58 -14
  86. data/spec/lib/protobuf/message_spec.rb +2 -2
  87. data/spec/lib/protobuf/optionable_spec.rb +96 -0
  88. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +151 -0
  89. data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +3 -3
  90. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +0 -2
  91. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +2 -2
  92. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +4 -4
  93. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +2 -2
  94. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +1 -18
  95. data/spec/lib/protobuf/rpc/service_filters_spec.rb +2 -2
  96. data/spec/lib/protobuf/varint_spec.rb +1 -1
  97. data/spec/lib/protobuf_spec.rb +13 -16
  98. data/spec/support/packed_field.rb +3 -2
  99. data/spec/support/protos/enum.pb.rb +2 -1
  100. data/spec/support/protos/enum.proto +1 -0
  101. data/spec/support/protos/google_unittest.pb.rb +69 -58
  102. data/spec/support/protos/google_unittest_custom_options.bin +0 -0
  103. data/spec/support/protos/google_unittest_custom_options.pb.rb +361 -0
  104. data/spec/support/protos/google_unittest_custom_options.proto +424 -0
  105. data/spec/support/protos/google_unittest_import.pb.rb +8 -0
  106. data/spec/support/protos/google_unittest_import_public.pb.rb +6 -0
  107. data/spec/support/protos/resource.pb.rb +54 -2
  108. data/spec/support/protos/resource.proto +42 -2
  109. data/spec/support/server.rb +1 -1
  110. metadata +39 -16
  111. data/lib/protobuf/rpc/connector.rb +0 -19
  112. data/lib/protobuf/rpc/connectors/common.rb +0 -176
  113. data/spec/lib/protobuf/rpc/connector_spec.rb +0 -26
  114. data/spec/lib/protobuf/rpc/connectors/common_spec.rb +0 -170
@@ -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
- if @_optionable_options.try(:key?, name)
14
- value = @_optionable_options[name]
15
- else
16
- value = option.default_value
17
- end
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
- if base_class.optionable_descriptor_class != block.call
55
- fail 'A class is being defined with two different descriptor classes, something is very wrong'
56
- else
57
- return # Don't define optionable_descriptor_class twice
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)
@@ -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
- if MODES.include?(mode)
21
- @mode = mode
22
- else
23
- @mode = :read
24
- end
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)
@@ -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 = Connector.connector_for_client.new(options)
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 send_request
42
- fail 'If you inherit a Connector from Base you must implement send_request'
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
@@ -29,9 +29,9 @@ module Protobuf
29
29
  def timeout
30
30
  @timeout ||= begin
31
31
  if ::ENV.key?("PB_RPC_PING_PORT_TIMEOUT")
32
- ::ENV["PB_RPC_PING_PORT_TIMEOUT"].to_i
32
+ ::ENV["PB_RPC_PING_PORT_TIMEOUT"].to_f / 1000
33
33
  else
34
- 5 # 5 seconds
34
+ 0.2 # 200 ms
35
35
  end
36
36
  end
37
37
  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/message'
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
@@ -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,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
  app.call(env)
15
19
  rescue => exception
16
20
  log_exception(exception)
@@ -8,6 +8,10 @@ module Protobuf
8
8
 
9
9
  # TODO: Figure out how to control when logs are flushed
10
10
  def call(env)
11
+ dup._call(env)
12
+ end
13
+
14
+ def _call(env)
11
15
  instrumenter.start
12
16
  instrumenter.flush(env) # Log request stats
13
17
 
@@ -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 ||= begin
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
- method_name
44
- end
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 ||= begin
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 ||= begin
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 ||= begin
45
- candidate = env.response
46
- case
47
- when candidate.is_a?(Message) then
48
- validate!(candidate)
49
- when candidate.respond_to?(:to_proto) then
50
- validate!(candidate.to_proto)
51
- when candidate.respond_to?(:to_hash) then
52
- env.response_type.new(candidate.to_hash)
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
- actual = candidate.class
66
- expected = env.response_type
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
@@ -3,10 +3,11 @@
3
3
  ##
4
4
  # This file is auto-generated. DO NOT EDIT!
5
5
  #
6
- require 'protobuf/message'
6
+ require 'protobuf'
7
7
 
8
8
  module Protobuf
9
9
  module Socketrpc
10
+ ::Protobuf::Optionable.inject(self) { ::Google::Protobuf::FileOptions }
10
11
 
11
12
  ##
12
13
  # Enum Classes
@@ -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
- alias_method :running?, :running
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.size > 0 && threads.size % threshold == 0
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
- else
105
+ elsif threads.size > 1
106
106
  # Run a cleanup if select times out while waiting
107
- cleanup_threads if threads.size > 1
107
+ cleanup_threads
108
108
  end
109
109
  end
110
110
  ensure
@@ -36,3 +36,11 @@ module Protobuf
36
36
  end
37
37
  end
38
38
  end
39
+
40
+ module Protobuf
41
+ module Rpc
42
+ module Servers # bad file namespacing
43
+ SocketRunner = ::Protobuf::Rpc::SocketRunner
44
+ end
45
+ end
46
+ end
@@ -107,11 +107,12 @@ module Protobuf
107
107
  end
108
108
 
109
109
  def init_zmq_context
110
- if inproc?
111
- @zmq_context = @server.zmq_context
112
- else
113
- @zmq_context = ZMQ::Context.new
114
- end
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))