protobuf 2.8.13 → 3.0.0.rc1
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/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
|