protobuf 2.8.13 → 3.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +84 -5
- data/CONTRIBUTING.md +3 -3
- data/Rakefile +46 -7
- data/lib/protobuf/cli.rb +2 -20
- data/lib/protobuf/decoder.rb +74 -0
- data/lib/protobuf/deprecator.rb +42 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +17 -16
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +86 -85
- data/lib/protobuf/encoder.rb +62 -0
- data/lib/protobuf/enum.rb +298 -37
- data/lib/protobuf/field/base_field.rb +41 -27
- data/lib/protobuf/field/bool_field.rb +22 -4
- data/lib/protobuf/field/bytes_field.rb +36 -15
- data/lib/protobuf/field/double_field.rb +10 -3
- data/lib/protobuf/field/enum_field.rb +21 -18
- data/lib/protobuf/field/field_array.rb +26 -16
- data/lib/protobuf/field/fixed32_field.rb +10 -4
- data/lib/protobuf/field/fixed64_field.rb +10 -3
- data/lib/protobuf/field/float_field.rb +18 -5
- data/lib/protobuf/field/int32_field.rb +14 -4
- data/lib/protobuf/field/int64_field.rb +14 -4
- data/lib/protobuf/field/integer_field.rb +9 -4
- data/lib/protobuf/field/message_field.rb +16 -7
- data/lib/protobuf/field/sfixed32_field.rb +10 -3
- data/lib/protobuf/field/sfixed64_field.rb +12 -7
- data/lib/protobuf/field/signed_integer_field.rb +7 -0
- data/lib/protobuf/field/sint32_field.rb +14 -4
- data/lib/protobuf/field/sint64_field.rb +14 -4
- data/lib/protobuf/field/string_field.rb +11 -1
- data/lib/protobuf/field/uint32_field.rb +14 -4
- data/lib/protobuf/field/uint64_field.rb +14 -4
- data/lib/protobuf/field/varint_field.rb +11 -9
- data/lib/protobuf/field.rb +42 -25
- data/lib/protobuf/generators/enum_generator.rb +12 -1
- data/lib/protobuf/generators/field_generator.rb +1 -1
- data/lib/protobuf/lifecycle.rb +3 -4
- data/lib/protobuf/message/fields.rb +122 -0
- data/lib/protobuf/message/serialization.rb +84 -0
- data/lib/protobuf/message.rb +21 -221
- data/lib/protobuf/optionable.rb +23 -0
- data/lib/protobuf/rpc/client.rb +2 -4
- data/lib/protobuf/rpc/connector.rb +0 -2
- data/lib/protobuf/rpc/connectors/common.rb +2 -2
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +14 -16
- data/lib/protobuf/rpc/env.rb +58 -0
- data/lib/protobuf/rpc/error.rb +8 -5
- data/lib/protobuf/rpc/middleware/exception_handler.rb +36 -0
- data/lib/protobuf/rpc/middleware/logger.rb +91 -0
- data/lib/protobuf/rpc/middleware/request_decoder.rb +83 -0
- data/lib/protobuf/rpc/middleware/response_encoder.rb +88 -0
- data/lib/protobuf/rpc/middleware/runner.rb +18 -0
- data/lib/protobuf/rpc/middleware.rb +25 -0
- data/lib/protobuf/rpc/rpc.pb.rb +15 -16
- data/lib/protobuf/rpc/server.rb +14 -64
- data/lib/protobuf/rpc/servers/socket/server.rb +0 -2
- data/lib/protobuf/rpc/servers/socket/worker.rb +11 -15
- data/lib/protobuf/rpc/servers/zmq/util.rb +4 -1
- data/lib/protobuf/rpc/servers/zmq/worker.rb +5 -13
- data/lib/protobuf/rpc/servers/zmq_runner.rb +1 -1
- data/lib/protobuf/rpc/service.rb +38 -72
- data/lib/protobuf/rpc/service_dispatcher.rb +20 -108
- data/lib/protobuf/version.rb +1 -2
- data/lib/protobuf.rb +5 -13
- data/protobuf.gemspec +5 -5
- data/spec/benchmark/tasks.rb +2 -77
- data/spec/functional/zmq_server_spec.rb +13 -21
- data/spec/lib/protobuf/cli_spec.rb +5 -43
- data/spec/lib/protobuf/enum_spec.rb +194 -61
- data/spec/lib/protobuf/field_spec.rb +194 -0
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +24 -1
- data/spec/lib/protobuf/generators/field_generator_spec.rb +6 -6
- data/spec/lib/protobuf/message_spec.rb +52 -70
- data/spec/lib/protobuf/optionable_spec.rb +46 -0
- data/spec/lib/protobuf/rpc/client_spec.rb +1 -93
- data/spec/lib/protobuf/rpc/connector_spec.rb +1 -7
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +8 -0
- data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
- data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
- data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
- data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +75 -0
- data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +0 -6
- data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +10 -0
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +30 -105
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +4 -4
- data/spec/lib/protobuf/rpc/service_spec.rb +20 -24
- data/spec/lib/protobuf_spec.rb +3 -3
- data/spec/spec_helper.rb +5 -4
- data/spec/support/packed_field.rb +15 -14
- data/spec/support/server.rb +4 -21
- data/spec/support/test/defaults.pb.rb +4 -4
- data/spec/support/test/enum.pb.rb +13 -1
- data/spec/support/test/enum.proto +15 -0
- data/spec/support/test/extended.pb.rb +1 -1
- data/spec/support/test/google_unittest.pb.rb +239 -241
- data/spec/support/test/google_unittest_import.pb.rb +2 -2
- data/spec/support/test/multi_field_extensions.pb.rb +2 -2
- data/spec/support/test/resource.pb.rb +19 -18
- data/spec/support/test/resource.proto +1 -0
- data/spec/support/test/resource_service.rb +5 -0
- metadata +78 -57
- data/bin/rprotoc +0 -8
- data/lib/protobuf/enum_value.rb +0 -85
- data/lib/protobuf/evented.rb +0 -37
- data/lib/protobuf/ext/eventmachine.rb +0 -14
- data/lib/protobuf/field/extension_fields.rb +0 -32
- data/lib/protobuf/message/decoder.rb +0 -72
- data/lib/protobuf/message/message.rb +0 -1
- data/lib/protobuf/rpc/connectors/em_client.rb +0 -84
- data/lib/protobuf/rpc/connectors/eventmachine.rb +0 -87
- data/lib/protobuf/rpc/servers/evented/server.rb +0 -36
- data/lib/protobuf/rpc/servers/evented_runner.rb +0 -31
- data/spec/functional/embedded_service_spec.rb +0 -7
- data/spec/functional/evented_server_spec.rb +0 -64
- data/spec/lib/protobuf/enum_value_spec.rb +0 -29
- data/spec/lib/protobuf/rpc/servers/evented_server_spec.rb +0 -19
data/lib/protobuf/rpc/server.rb
CHANGED
@@ -2,88 +2,38 @@ require 'protobuf'
|
|
2
2
|
require 'protobuf/logger'
|
3
3
|
require 'protobuf/rpc/rpc.pb'
|
4
4
|
require 'protobuf/rpc/buffer'
|
5
|
+
require 'protobuf/rpc/env'
|
5
6
|
require 'protobuf/rpc/error'
|
6
|
-
require 'protobuf/rpc/
|
7
|
+
require 'protobuf/rpc/middleware'
|
7
8
|
require 'protobuf/rpc/service_dispatcher'
|
8
9
|
|
9
10
|
module Protobuf
|
10
11
|
module Rpc
|
11
12
|
module Server
|
12
|
-
|
13
|
-
def initialize_request!
|
14
|
-
log_debug { sign_message('Post init') }
|
15
|
-
@request = ::Protobuf::Socketrpc::Request.new
|
16
|
-
@response = ::Protobuf::Socketrpc::Response.new
|
17
|
-
@stats = Protobuf::Rpc::Stat.new(:SERVER)
|
18
|
-
end
|
19
|
-
|
20
|
-
def disable_gc!
|
13
|
+
def gc_pause
|
21
14
|
::GC.disable if ::Protobuf.gc_pause_server_request?
|
22
|
-
end
|
23
15
|
|
24
|
-
|
25
|
-
|
16
|
+
yield
|
17
|
+
|
18
|
+
::GC.enable if ::Protobuf.gc_pause_server_request?
|
26
19
|
end
|
27
20
|
|
28
21
|
# Invoke the service method dictated by the proto wrapper request object
|
29
|
-
|
30
|
-
|
31
|
-
|
22
|
+
#
|
23
|
+
def handle_request(request_data)
|
24
|
+
# Create an env object that holds different parts of the environment and
|
25
|
+
# is available to all of the middlewares
|
26
|
+
env = Env.new('encoded_request' => request_data, 'log_signature' => log_signature)
|
32
27
|
|
33
|
-
|
34
|
-
|
35
|
-
log_info { @stats.to_s }
|
28
|
+
# Invoke the middleware stack, the last of which is the service dispatcher
|
29
|
+
env = Rpc.middleware.call(env)
|
36
30
|
|
37
|
-
|
38
|
-
@dispatcher.invoke!
|
39
|
-
if @dispatcher.success?
|
40
|
-
@response.response_proto = @dispatcher.response
|
41
|
-
else
|
42
|
-
handle_error(@dispatcher.error)
|
43
|
-
end
|
44
|
-
rescue => error
|
45
|
-
log_exception(error)
|
46
|
-
handle_error(error)
|
47
|
-
ensure
|
48
|
-
send_response
|
49
|
-
end
|
50
|
-
|
51
|
-
# Client error handler. Receives an exception object and writes it into the @response
|
52
|
-
def handle_error(error)
|
53
|
-
log_debug { sign_message("handle_error: #{error.inspect}") }
|
54
|
-
if error.respond_to?(:to_response)
|
55
|
-
error.to_response(@response)
|
56
|
-
else
|
57
|
-
message = error.respond_to?(:message) ? error.message : error.to_s
|
58
|
-
code = error.respond_to?(:code) ? error.code : 'RPC_ERROR'
|
59
|
-
::Protobuf::Rpc::PbError.new(message, code).to_response(@response)
|
60
|
-
end
|
31
|
+
env.encoded_response
|
61
32
|
end
|
62
33
|
|
63
34
|
def log_signature
|
64
35
|
@_log_signature ||= "[server-#{self.class.name}]"
|
65
36
|
end
|
66
|
-
|
67
|
-
# Parse the incoming request object into our expected request object
|
68
|
-
def parse_request_from_buffer
|
69
|
-
log_debug { sign_message("Parsing request from buffer: #{@request_data}") }
|
70
|
-
@stats.request_size = @request_data.size
|
71
|
-
@request.decode(@request_data)
|
72
|
-
rescue => error
|
73
|
-
exc = ::Protobuf::Rpc::BadRequestData.new("Unable to parse request: #{error.message}")
|
74
|
-
log_error { exc.message }
|
75
|
-
raise exc
|
76
|
-
end
|
77
|
-
|
78
|
-
# Write the response wrapper to the client
|
79
|
-
def send_response
|
80
|
-
log_debug { sign_message("Sending response to client: #{@response.inspect}") }
|
81
|
-
send_data
|
82
|
-
ensure
|
83
|
-
@stats.stop
|
84
|
-
log_info { @stats.to_s }
|
85
|
-
enable_gc!
|
86
|
-
end
|
87
37
|
end
|
88
38
|
end
|
89
39
|
end
|
@@ -4,24 +4,21 @@ require 'protobuf/logger'
|
|
4
4
|
module Protobuf
|
5
5
|
module Rpc
|
6
6
|
module Socket
|
7
|
-
|
8
7
|
class Worker
|
9
8
|
include ::Protobuf::Rpc::Server
|
10
9
|
include ::Protobuf::Logger::LogMethods
|
11
10
|
|
12
11
|
def initialize(sock, &complete_cb)
|
13
12
|
@socket = sock
|
14
|
-
initialize_request!
|
15
|
-
|
16
|
-
request_buffer = Protobuf::Rpc::Buffer.new(:read)
|
17
13
|
@complete_cb = complete_cb
|
18
14
|
|
19
|
-
|
20
|
-
|
21
|
-
@request_data = request_buffer.data
|
15
|
+
data = read_data
|
16
|
+
return unless data
|
22
17
|
|
23
|
-
|
24
|
-
|
18
|
+
gc_pause do
|
19
|
+
encoded_response = handle_request(data)
|
20
|
+
send_data(encoded_response)
|
21
|
+
end
|
25
22
|
end
|
26
23
|
|
27
24
|
def read_data
|
@@ -32,17 +29,17 @@ module Protobuf
|
|
32
29
|
end
|
33
30
|
str_size_io = size_io.string
|
34
31
|
|
35
|
-
|
32
|
+
@socket.read(str_size_io.to_i)
|
36
33
|
end
|
37
34
|
|
38
|
-
def send_data
|
35
|
+
def send_data(data)
|
39
36
|
raise 'Socket closed unexpectedly' unless socket_writable?
|
40
37
|
response_buffer = Protobuf::Rpc::Buffer.new(:write)
|
41
|
-
response_buffer.set_data(
|
42
|
-
|
43
|
-
log_debug { sign_message("sending data : #{response_buffer.data}") }
|
38
|
+
response_buffer.set_data(data)
|
39
|
+
|
44
40
|
@socket.write(response_buffer.write)
|
45
41
|
@socket.flush
|
42
|
+
|
46
43
|
@complete_cb.call(@socket)
|
47
44
|
end
|
48
45
|
|
@@ -54,7 +51,6 @@ module Protobuf
|
|
54
51
|
! @socket.nil? && ! @socket.closed?
|
55
52
|
end
|
56
53
|
end
|
57
|
-
|
58
54
|
end
|
59
55
|
end
|
60
56
|
end
|
@@ -4,6 +4,7 @@ module Protobuf
|
|
4
4
|
module Rpc
|
5
5
|
module Zmq
|
6
6
|
|
7
|
+
ADDRESS_MATCH = /\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\z/.freeze
|
7
8
|
WORKER_READY_MESSAGE = "\1"
|
8
9
|
|
9
10
|
module Util
|
@@ -33,7 +34,9 @@ module Protobuf
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def resolve_ip(hostname)
|
36
|
-
::Resolv.
|
37
|
+
::Resolv.getaddresses(hostname).detect do |address|
|
38
|
+
address =~ ADDRESS_MATCH
|
39
|
+
end
|
37
40
|
end
|
38
41
|
end
|
39
42
|
end
|
@@ -26,11 +26,12 @@ module Protobuf
|
|
26
26
|
# Instance Methods
|
27
27
|
#
|
28
28
|
def process_request
|
29
|
-
|
29
|
+
client_address, _, data = read_from_backend
|
30
|
+
return unless data
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
gc_pause do
|
33
|
+
encoded_response = handle_request(data)
|
34
|
+
write_to_backend([client_address, "", encoded_response])
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
@@ -53,7 +54,6 @@ module Protobuf
|
|
53
54
|
|
54
55
|
if rc > 0
|
55
56
|
::Thread.current[:busy] = true
|
56
|
-
initialize_request!
|
57
57
|
process_request
|
58
58
|
::Thread.current[:busy] = false
|
59
59
|
end
|
@@ -66,14 +66,6 @@ module Protobuf
|
|
66
66
|
@server.running?
|
67
67
|
end
|
68
68
|
|
69
|
-
def send_data
|
70
|
-
data = @response.encode
|
71
|
-
|
72
|
-
@stats.response_size = data.size
|
73
|
-
|
74
|
-
write_to_backend([@client_address, "", data])
|
75
|
-
end
|
76
|
-
|
77
69
|
private
|
78
70
|
|
79
71
|
def init_zmq_context
|
data/lib/protobuf/rpc/service.rb
CHANGED
@@ -5,23 +5,32 @@ require 'protobuf/rpc/service_filters'
|
|
5
5
|
|
6
6
|
module Protobuf
|
7
7
|
module Rpc
|
8
|
-
|
9
8
|
# Object to encapsulate the request/response types for a given service method
|
10
9
|
#
|
11
10
|
RpcMethod = Struct.new("RpcMethod", :method, :request_type, :response_type)
|
12
11
|
|
13
12
|
class Service
|
14
|
-
include ::Protobuf::Rpc::ServiceFilters
|
15
13
|
include ::Protobuf::Logger::LogMethods
|
16
|
-
|
14
|
+
include ::Protobuf::Rpc::ServiceFilters
|
17
15
|
|
18
16
|
DEFAULT_HOST = '127.0.0.1'.freeze
|
19
17
|
DEFAULT_PORT = 9399
|
20
18
|
|
19
|
+
attr_reader :env, :request
|
20
|
+
|
21
21
|
##
|
22
|
-
#
|
22
|
+
# Constructor!
|
23
23
|
#
|
24
|
+
# Initialize a service with the rpc endpoint name and the bytes
|
25
|
+
# for the request.
|
26
|
+
def initialize(env)
|
27
|
+
@env = env.dup # Dup the env so it doesn't change out from under us
|
28
|
+
@request = env.request
|
29
|
+
end
|
24
30
|
|
31
|
+
##
|
32
|
+
# Class Methods
|
33
|
+
#
|
25
34
|
# Create a new client for the given service.
|
26
35
|
# See Client#initialize and ClientConnection::DEFAULT_OPTIONS
|
27
36
|
# for all available options.
|
@@ -54,6 +63,18 @@ module Protobuf
|
|
54
63
|
@_host = new_host
|
55
64
|
end
|
56
65
|
|
66
|
+
# An array of defined service classes that contain implementation
|
67
|
+
# code
|
68
|
+
def self.implemented_services
|
69
|
+
classes = (self.subclasses || []).select do |subclass|
|
70
|
+
subclass.rpcs.any? do |(name, _)|
|
71
|
+
subclass.method_defined? name
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
classes.map(&:name)
|
76
|
+
end
|
77
|
+
|
57
78
|
# Shorthand call to configure, passing a string formatted as hostname:port
|
58
79
|
# e.g. 127.0.0.1:9933
|
59
80
|
# e.g. localhost:0
|
@@ -96,36 +117,16 @@ module Protobuf
|
|
96
117
|
rpcs.key?(name)
|
97
118
|
end
|
98
119
|
|
99
|
-
# An array of defined service classes that contain implementation
|
100
|
-
# code
|
101
|
-
def self.implemented_services
|
102
|
-
classes = (self.subclasses || []).select do |subclass|
|
103
|
-
subclass.rpcs.any? do |(name, _)|
|
104
|
-
subclass.method_defined? name
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
classes.map(&:name)
|
109
|
-
end
|
110
|
-
|
111
120
|
##
|
112
121
|
# Instance Methods
|
113
122
|
#
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
#
|
118
|
-
# for the request.
|
119
|
-
def initialize(method_name, request_bytes, client_host = nil)
|
120
|
-
@method_name = method_name
|
121
|
-
@client_host = client_host
|
122
|
-
@_request_bytes = request_bytes
|
123
|
-
end
|
124
|
-
|
125
|
-
# Register a failure callback for use when rpc_failed is invoked.
|
123
|
+
# Get a callable object that will be used by the dispatcher
|
124
|
+
# to invoke the specified rpc method. Facilitates callback dispatch.
|
125
|
+
# The returned lambda is expected to be called at a later time (which
|
126
|
+
# is why we wrap the method call).
|
126
127
|
#
|
127
|
-
def
|
128
|
-
|
128
|
+
def callable_rpc_method(method_name)
|
129
|
+
lambda { run_filters(method_name) }
|
129
130
|
end
|
130
131
|
|
131
132
|
# Response object for this rpc cycle. Not assignable.
|
@@ -134,18 +135,6 @@ module Protobuf
|
|
134
135
|
@_response ||= response_type.new
|
135
136
|
end
|
136
137
|
|
137
|
-
# Request object for this rpc cycle. Not assignable.
|
138
|
-
#
|
139
|
-
def request
|
140
|
-
@_request ||= if @_request_bytes.present?
|
141
|
-
request_type.decode(@_request_bytes)
|
142
|
-
else
|
143
|
-
request_type.new
|
144
|
-
end
|
145
|
-
rescue => e
|
146
|
-
raise BadRequestProto, "Unable to parse request: #{e.message}"
|
147
|
-
end
|
148
|
-
|
149
138
|
# Convenience method to get back to class method.
|
150
139
|
#
|
151
140
|
def rpc_method?(name)
|
@@ -158,23 +147,10 @@ module Protobuf
|
|
158
147
|
self.class.rpcs
|
159
148
|
end
|
160
149
|
|
161
|
-
|
162
|
-
# to invoke the specified rpc method. Facilitates callback dispatch.
|
163
|
-
# The returned lambda is expected to be called at a later time (which
|
164
|
-
# is why we wrap the method call).
|
165
|
-
#
|
166
|
-
def callable_rpc_method(method_name)
|
167
|
-
lambda { run_filters(method_name) }
|
168
|
-
end
|
169
|
-
|
170
|
-
private
|
171
|
-
|
172
|
-
def response_type
|
173
|
-
@_response_type ||= rpcs[@method_name].response_type
|
174
|
-
end
|
150
|
+
private
|
175
151
|
|
176
152
|
def request_type
|
177
|
-
@_request_type ||=
|
153
|
+
@_request_type ||= env.request_type
|
178
154
|
end
|
179
155
|
|
180
156
|
# Sugar to make an rpc method feel like a controller method.
|
@@ -186,28 +162,18 @@ module Protobuf
|
|
186
162
|
end
|
187
163
|
alias_method :return_from_whence_you_came, :respond_with
|
188
164
|
|
189
|
-
|
190
|
-
|
191
|
-
def rpc
|
192
|
-
if ::Protobuf.print_deprecation_warnings?
|
193
|
-
$stderr.puts <<-ERROR
|
194
|
-
[WARNING] Service#rpc method has been deprecated
|
195
|
-
and will be removed in a future version of protobuf.
|
196
|
-
ERROR
|
197
|
-
end
|
198
|
-
@method_name
|
165
|
+
def response_type
|
166
|
+
@_response_type ||= env.response_type
|
199
167
|
end
|
200
168
|
|
201
169
|
# Automatically fail a service method.
|
202
170
|
#
|
203
171
|
def rpc_failed(message)
|
204
|
-
|
172
|
+
message = message.message if message.respond_to?(:message)
|
173
|
+
raise RpcFailed.new(message)
|
205
174
|
end
|
206
|
-
|
207
175
|
end
|
208
176
|
|
209
|
-
|
210
|
-
ActiveSupport.run_load_hooks(:protobuf_rpc_service, Service)
|
211
|
-
end
|
177
|
+
ActiveSupport.run_load_hooks(:protobuf_rpc_service, Service)
|
212
178
|
end
|
213
179
|
end
|
@@ -3,130 +3,42 @@ require 'protobuf/logger'
|
|
3
3
|
module Protobuf
|
4
4
|
module Rpc
|
5
5
|
class ServiceDispatcher
|
6
|
-
|
7
6
|
include ::Protobuf::Logger::LogMethods
|
8
7
|
|
9
|
-
|
10
|
-
attr_accessor :definition, :response, :error
|
11
|
-
|
12
|
-
def initialize(wrapper_request)
|
13
|
-
self.error = nil
|
14
|
-
self.outer_request = wrapper_request
|
15
|
-
|
16
|
-
init_service
|
17
|
-
init_method if service_klass.present?
|
18
|
-
register_rpc_failed if service.present?
|
19
|
-
end
|
20
|
-
|
21
|
-
# Call the given service method. If we get to this point and an error
|
22
|
-
# has already occurred, do not invoke the method and simply respond.
|
23
|
-
#
|
24
|
-
def invoke!
|
25
|
-
unless error?
|
26
|
-
callable_method.call
|
27
|
-
validate_response
|
28
|
-
end
|
29
|
-
|
30
|
-
return error || response
|
31
|
-
end
|
32
|
-
|
33
|
-
# We're successful if the error is not populated.
|
34
|
-
#
|
35
|
-
def success?
|
36
|
-
error.nil?
|
37
|
-
end
|
38
|
-
|
39
|
-
# We're in error if the error is populated.
|
40
|
-
#
|
41
|
-
def error?
|
42
|
-
! success?
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
8
|
+
attr_reader :env
|
46
9
|
|
47
|
-
def
|
48
|
-
|
10
|
+
def initialize(app)
|
11
|
+
# End of the line...
|
49
12
|
end
|
50
13
|
|
51
|
-
|
52
|
-
|
53
|
-
def coerced_response
|
54
|
-
candidate = service.response
|
14
|
+
def call(env)
|
15
|
+
@env = env
|
55
16
|
|
56
|
-
|
57
|
-
|
58
|
-
# no-op
|
59
|
-
when candidate.respond_to?(:to_proto) then
|
60
|
-
candidate = candidate.to_proto
|
61
|
-
when candidate.respond_to?(:to_proto_hash) then
|
62
|
-
candidate = definition.response_type.new(candidate.to_proto_hash)
|
63
|
-
when candidate.respond_to?(:to_hash) then
|
64
|
-
candidate = definition.response_type.new(candidate.to_hash)
|
65
|
-
end
|
66
|
-
|
67
|
-
candidate
|
17
|
+
env.response = dispatch_rpc_request
|
18
|
+
env
|
68
19
|
end
|
69
20
|
|
70
|
-
|
71
|
-
|
72
|
-
def init_method
|
73
|
-
method_name = outer_request.method_name.underscore.to_sym
|
74
|
-
request_proto = outer_request.has_field?(:request_proto) ? outer_request.request_proto : nil
|
75
|
-
|
76
|
-
if service_klass.rpc_method?(method_name)
|
77
|
-
self.service = service_klass.new(method_name, request_proto, outer_request.caller)
|
78
|
-
self.callable_method = service.callable_rpc_method(method_name)
|
79
|
-
self.definition = service.rpcs[method_name]
|
80
|
-
else
|
81
|
-
assign_error(MethodNotFound, "#{service.class.name}##{method_name} is not a defined rpc method.")
|
82
|
-
end
|
83
|
-
rescue NameError => e
|
84
|
-
# FIXME I think this is no longer applicable since the method extract
|
85
|
-
# is now wrapped in a lambda (@see Service#callable_rpc_method).
|
86
|
-
log_exception(e)
|
87
|
-
assign_error(MethodNotFound, "#{service.class.name}##{method_name} is not implemented.")
|
21
|
+
def rpc_service
|
22
|
+
@rpc_service ||= env.rpc_service.new(env)
|
88
23
|
end
|
89
24
|
|
90
|
-
|
91
|
-
# happens when we verify that the method is callable for this service.
|
92
|
-
#
|
93
|
-
def init_service
|
94
|
-
self.service_klass = outer_request.service_name.constantize
|
95
|
-
rescue NameError => e
|
96
|
-
log_exception(e)
|
97
|
-
assign_error(ServiceNotFound, "Service class #{outer_request.service_name} is not defined.")
|
98
|
-
end
|
25
|
+
private
|
99
26
|
|
100
|
-
#
|
101
|
-
|
102
|
-
|
103
|
-
|
27
|
+
# Call the given service method.
|
28
|
+
def dispatch_rpc_request
|
29
|
+
rpc_service.callable_rpc_method(method_name).call
|
30
|
+
rpc_service.response
|
31
|
+
rescue NoMethodError
|
32
|
+
raise MethodNotFound.new("#{service_name}##{method_name} is not implemented.")
|
104
33
|
end
|
105
34
|
|
106
|
-
|
107
|
-
|
108
|
-
#
|
109
|
-
def rpc_failed_callback(message)
|
110
|
-
assign_error(RpcFailed, (message.respond_to?(:message) ? message.message : message))
|
111
|
-
log_error { sign_message("RPC Failed: #{error.message}") }
|
35
|
+
def method_name
|
36
|
+
env.method_name
|
112
37
|
end
|
113
38
|
|
114
|
-
|
115
|
-
|
116
|
-
#
|
117
|
-
def validate_response
|
118
|
-
candidate = coerced_response
|
119
|
-
expected = definition.response_type
|
120
|
-
actual = candidate.class
|
121
|
-
|
122
|
-
if expected == actual
|
123
|
-
self.response = candidate
|
124
|
-
else
|
125
|
-
assign_error(BadResponseProto, "Response proto changed from #{expected.name} to #{actual.name}")
|
126
|
-
end
|
39
|
+
def service_name
|
40
|
+
env.service_name
|
127
41
|
end
|
128
|
-
|
129
42
|
end
|
130
43
|
end
|
131
44
|
end
|
132
|
-
|
data/lib/protobuf/version.rb
CHANGED
data/lib/protobuf.rb
CHANGED
@@ -2,25 +2,17 @@ require 'logger'
|
|
2
2
|
require 'socket'
|
3
3
|
require 'pp'
|
4
4
|
require 'stringio'
|
5
|
+
|
5
6
|
require 'active_support/core_ext/object/blank'
|
6
|
-
require 'active_support/
|
7
|
+
require 'active_support/core_ext/object/try'
|
7
8
|
require 'active_support/notifications'
|
8
|
-
|
9
|
-
if ActiveSupport::VERSION::MAJOR > 2
|
10
|
-
require 'active_support/core_ext/object/try'
|
11
|
-
else
|
12
|
-
require 'active_support/core_ext/module/delegation'
|
13
|
-
require 'active_support/core_ext/kernel/reporting'
|
14
|
-
require 'active_support/core_ext/try'
|
15
|
-
end
|
16
|
-
|
17
9
|
require 'active_support/inflector'
|
18
10
|
require 'active_support/json'
|
19
11
|
|
20
12
|
module Protobuf
|
21
13
|
|
22
14
|
# See Protobuf#connector_type documentation.
|
23
|
-
CONNECTORS = [ :socket, :zmq
|
15
|
+
CONNECTORS = [ :socket, :zmq ].freeze
|
24
16
|
|
25
17
|
# Default is Socket as it has no external dependencies.
|
26
18
|
DEFAULT_CONNECTOR = :socket
|
@@ -65,7 +57,7 @@ module Protobuf
|
|
65
57
|
# This optomization provides a huge boost in speed to rpc requests.
|
66
58
|
def self.gc_pause_server_request?
|
67
59
|
return @_gc_pause_server_request unless @_gc_pause_server_request.nil?
|
68
|
-
gc_pause_server_request = false
|
60
|
+
self.gc_pause_server_request = false
|
69
61
|
end
|
70
62
|
|
71
63
|
def self.gc_pause_server_request=(value)
|
@@ -84,7 +76,7 @@ module Protobuf
|
|
84
76
|
# The rpc_server option will override the ENV setting.
|
85
77
|
def self.print_deprecation_warnings?
|
86
78
|
return @_print_deprecation_warnings unless @_print_deprecation_warnings.nil?
|
87
|
-
print_deprecation_warnings = ENV.key?('PB_IGNORE_DEPRECATIONS') ? false : true
|
79
|
+
self.print_deprecation_warnings = ENV.key?('PB_IGNORE_DEPRECATIONS') ? false : true
|
88
80
|
end
|
89
81
|
|
90
82
|
def self.print_deprecation_warnings=(value)
|
data/protobuf.gemspec
CHANGED
@@ -8,8 +8,8 @@ require "protobuf/version"
|
|
8
8
|
s.date = ::Time.now.strftime('%Y-%m-%d')
|
9
9
|
s.license = 'WTFPL'
|
10
10
|
|
11
|
-
s.authors = ['BJ Neilsen', 'Brandon Dewitt', 'Devin Christensen']
|
12
|
-
s.email = ['bj.neilsen+protobuf@gmail.com', 'brandonsdewitt+protobuf@gmail.com', 'quixoten@gmail.com']
|
11
|
+
s.authors = ['BJ Neilsen', 'Brandon Dewitt', 'Devin Christensen', 'Adam Hutchison']
|
12
|
+
s.email = ['bj.neilsen+protobuf@gmail.com', 'brandonsdewitt+protobuf@gmail.com', 'quixoten@gmail.com', 'liveh2o@gmail.com']
|
13
13
|
s.homepage = 'https://github.com/localshred/protobuf'
|
14
14
|
s.summary = "Google Protocol Buffers serialization and RPC implementation for Ruby."
|
15
15
|
s.description = s.summary
|
@@ -19,11 +19,11 @@ require "protobuf/version"
|
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
-
s.add_dependency 'activesupport'
|
22
|
+
s.add_dependency 'activesupport', '>= 3.2'
|
23
|
+
s.add_dependency 'middleware'
|
23
24
|
s.add_dependency 'multi_json'
|
24
25
|
s.add_dependency 'thor'
|
25
26
|
|
26
|
-
s.add_development_dependency 'eventmachine'
|
27
27
|
s.add_development_dependency 'ffi-rzmq'
|
28
28
|
s.add_development_dependency 'pry-nav'
|
29
29
|
s.add_development_dependency 'rake'
|
@@ -31,5 +31,5 @@ require "protobuf/version"
|
|
31
31
|
s.add_development_dependency 'simplecov'
|
32
32
|
s.add_development_dependency 'yard'
|
33
33
|
s.add_development_dependency 'timecop'
|
34
|
-
|
34
|
+
s.add_development_dependency 'perftools.rb'
|
35
35
|
end
|