protobuf 1.0.0 → 1.0.1
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.
- data/Gemfile.lock +1 -1
- data/README.md +138 -126
- data/bin/rpc_server +2 -2
- data/bin/rprotoc +2 -2
- data/examples/reading_a_message.rb +3 -3
- data/examples/writing_a_message.rb +3 -3
- data/lib/protobuf.rb +3 -0
- data/lib/protobuf/compiler/nodes.rb +1 -1
- data/lib/protobuf/compiler/proto_parser.rb +16 -16
- data/lib/protobuf/compiler/visitors.rb +11 -25
- data/lib/protobuf/descriptor/descriptor_builder.rb +58 -58
- data/lib/protobuf/descriptor/field_descriptor.rb +2 -2
- data/lib/protobuf/ext/eventmachine.rb +16 -0
- data/lib/protobuf/message/decoder.rb +6 -6
- data/lib/protobuf/message/field.rb +14 -14
- data/lib/protobuf/message/message.rb +4 -4
- data/lib/protobuf/rpc/client.rb +42 -183
- data/lib/protobuf/rpc/connector.rb +19 -0
- data/lib/protobuf/rpc/connectors/base.rb +29 -0
- data/lib/protobuf/rpc/connectors/em_client.rb +227 -0
- data/lib/protobuf/rpc/connectors/eventmachine.rb +84 -0
- data/lib/protobuf/rpc/connectors/socket.rb +14 -0
- data/lib/protobuf/rpc/service.rb +4 -4
- data/lib/protobuf/version.rb +1 -1
- data/protobuf.gemspec +3 -3
- data/spec/helper/all.rb +13 -0
- data/spec/helper/server.rb +36 -0
- data/spec/helper/tolerance_matcher.rb +40 -0
- data/spec/spec_helper.rb +3 -5
- data/spec/unit/rpc/client_spec.rb +174 -0
- data/spec/unit/rpc/connector_spec.rb +36 -0
- data/spec/unit/rpc/connectors/base_spec.rb +77 -0
- data/spec/unit/rpc/connectors/eventmachine/client_spec.rb +0 -0
- data/spec/unit/rpc/connectors/eventmachine_spec.rb +0 -0
- data/spec/unit/{server_spec.rb → rpc/server_spec.rb} +0 -0
- data/spec/unit/{service_spec.rb → rpc/service_spec.rb} +0 -0
- metadata +79 -63
- data/lib/protobuf/compiler/template/rpc_bin.erb +0 -4
- data/lib/protobuf/compiler/template/rpc_client.erb +0 -18
- data/lib/protobuf/compiler/template/rpc_service.erb +0 -25
- data/lib/protobuf/rpc/client_connection.rb +0 -225
- data/spec/unit/client_spec.rb +0 -128
@@ -168,13 +168,6 @@ module Protobuf
|
|
168
168
|
@file_contents
|
169
169
|
end
|
170
170
|
|
171
|
-
def create_bin(out_dir, underscored_name, module_name, service_name, default_port)
|
172
|
-
bin_filename = "#{out_dir}/bin/start_#{underscored_name}"
|
173
|
-
bin_contents = template_erb('rpc_bin').result(binding)
|
174
|
-
create_file_with_backup(bin_filename, bin_contents, true) if @create_file
|
175
|
-
@file_contents[bin_filename] = bin_contents
|
176
|
-
end
|
177
|
-
|
178
171
|
def create_service(message_file, out_dir, underscored_name, module_name, service_name, default_port, rpcs, required_file)
|
179
172
|
service_filename = "#{out_dir}/#{Util.module_to_path(module_name)}/#{underscored_name}.rb"
|
180
173
|
service_contents = template_erb('rpc_service_implementation').result(binding)
|
@@ -182,13 +175,6 @@ module Protobuf
|
|
182
175
|
@file_contents[service_filename] = service_contents
|
183
176
|
end
|
184
177
|
|
185
|
-
def create_client(out_dir, underscored_name, default_port, name, request, response, message_module, required_file)
|
186
|
-
client_filename = "#{out_dir}/clients/#{Util.module_to_path(message_module)}_client_#{underscore name}.rb"
|
187
|
-
client_contents = template_erb('rpc_client').result binding
|
188
|
-
create_file_with_backup(client_filename, client_contents, true) if @create_file
|
189
|
-
@file_contents[client_filename] = client_contents
|
190
|
-
end
|
191
|
-
|
192
178
|
private
|
193
179
|
|
194
180
|
def underscore(str)
|
@@ -232,19 +218,19 @@ module Protobuf
|
|
232
218
|
def add_option(name, value)
|
233
219
|
options =
|
234
220
|
case current_descriptor
|
235
|
-
when Google::Protobuf::FileDescriptorProto
|
221
|
+
when Google::Protobuf::FileDescriptorProto then
|
236
222
|
Google::Protobuf::FileOptions.new
|
237
|
-
when Google::Protobuf::DescriptorProto
|
223
|
+
when Google::Protobuf::DescriptorProto then
|
238
224
|
Google::Protobuf::MessageOptions.new
|
239
|
-
when Google::Protobuf::FieldDescriptorProto
|
225
|
+
when Google::Protobuf::FieldDescriptorProto then
|
240
226
|
Google::Protobuf::FieldOptions.new
|
241
|
-
when Google::Protobuf::EnumDescriptorProto
|
227
|
+
when Google::Protobuf::EnumDescriptorProto then
|
242
228
|
Google::Protobuf::EnumOptions.new
|
243
|
-
when Google::Protobuf::EnumValueDescriptorProto
|
229
|
+
when Google::Protobuf::EnumValueDescriptorProto then
|
244
230
|
Google::Protobuf::EnumValueOptions.new
|
245
|
-
when Google::Protobuf::ServiceDescriptorProto
|
231
|
+
when Google::Protobuf::ServiceDescriptorProto then
|
246
232
|
Google::Protobuf::ServiceOptions.new
|
247
|
-
when Google::Protobuf::MethodDescriptorProto
|
233
|
+
when Google::Protobuf::MethodDescriptorProto then
|
248
234
|
Google::Protobuf::MethodOptions.new
|
249
235
|
else
|
250
236
|
raise ArgumentError, 'Invalid context'
|
@@ -255,9 +241,9 @@ module Protobuf
|
|
255
241
|
|
256
242
|
def descriptor=(descriptor)
|
257
243
|
case current_descriptor
|
258
|
-
when Google::Protobuf::FileDescriptorProto
|
244
|
+
when Google::Protobuf::FileDescriptorProto then
|
259
245
|
current_descriptor.message_type << descriptor
|
260
|
-
when Google::Protobuf::DescriptorProto
|
246
|
+
when Google::Protobuf::DescriptorProto then
|
261
247
|
current_descriptor.nested_type << descriptor
|
262
248
|
else
|
263
249
|
raise ArgumentError, 'Invalid context'
|
@@ -283,9 +269,9 @@ module Protobuf
|
|
283
269
|
|
284
270
|
def field_descriptor=(descriptor)
|
285
271
|
case current_descriptor
|
286
|
-
when Google::Protobuf::FileDescriptorProto
|
272
|
+
when Google::Protobuf::FileDescriptorProto then
|
287
273
|
current_descriptor.extension << descriptor
|
288
|
-
when Google::Protobuf::DescriptorProto
|
274
|
+
when Google::Protobuf::DescriptorProto then
|
289
275
|
current_descriptor.field << descriptor
|
290
276
|
#TODO: how should i distiguish between field and extension
|
291
277
|
#current_descriptor.extension << descriptor
|
@@ -5,41 +5,41 @@ module Protobuf
|
|
5
5
|
def self.id2type(type_id)
|
6
6
|
require 'protobuf/descriptor/descriptor_proto'
|
7
7
|
case type_id
|
8
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_DOUBLE
|
8
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_DOUBLE then
|
9
9
|
:double
|
10
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_FLOAT
|
10
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_FLOAT then
|
11
11
|
:float
|
12
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT64
|
12
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT64 then
|
13
13
|
:int64
|
14
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT64
|
14
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT64 then
|
15
15
|
:unit64
|
16
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT32
|
16
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT32 then
|
17
17
|
:int64
|
18
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_FIXED64
|
18
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_FIXED64 then
|
19
19
|
:fixed64
|
20
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_FIXED32
|
20
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_FIXED32 then
|
21
21
|
:fixed32
|
22
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_BOOL
|
22
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_BOOL then
|
23
23
|
:bool
|
24
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING
|
24
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING then
|
25
25
|
:string
|
26
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_GROUP
|
26
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_GROUP then
|
27
27
|
:group
|
28
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_MESSAGE
|
28
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_MESSAGE then
|
29
29
|
:message
|
30
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_BYTES
|
30
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_BYTES then
|
31
31
|
:bytes
|
32
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT32
|
32
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT32 then
|
33
33
|
:uint32
|
34
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_ENUM
|
34
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_ENUM then
|
35
35
|
:enum
|
36
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_SFIXED32
|
36
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_SFIXED32 then
|
37
37
|
:sfixed32
|
38
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_SFIXED64
|
38
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_SFIXED64 then
|
39
39
|
:sfixed64
|
40
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_SINT32
|
40
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_SINT32 then
|
41
41
|
:sint32
|
42
|
-
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_SINT64
|
42
|
+
when Google::Protobuf::FieldDescriptorProto::Type::TYPE_SINT64 then
|
43
43
|
:sint64
|
44
44
|
else
|
45
45
|
raise ArgumentError, "Invalid type: #{proto.type}"
|
@@ -49,42 +49,42 @@ module Protobuf
|
|
49
49
|
def self.type2id(type)
|
50
50
|
require 'protobuf/descriptor/descriptor_proto'
|
51
51
|
case type
|
52
|
-
when :double
|
53
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_DOUBLE
|
54
|
-
when :float
|
52
|
+
when :double then
|
53
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_DOUBLE
|
54
|
+
when :float then
|
55
55
|
Google::Protobuf::FieldDescriptorProto::Type::TYPE_FLOAT
|
56
|
-
when :int64
|
57
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT64
|
58
|
-
when :unit64
|
59
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT64
|
60
|
-
when :int64
|
61
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT32
|
62
|
-
when :fixed64
|
63
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_FIXED64
|
64
|
-
when :fixed32
|
65
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_FIXED32
|
66
|
-
when
|
67
|
-
|
68
|
-
when :string
|
69
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING
|
70
|
-
when :group
|
71
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_GROUP
|
72
|
-
when :message
|
73
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_MESSAGE
|
74
|
-
when :bytes
|
56
|
+
when :int64 then
|
57
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT64
|
58
|
+
when :unit64 then
|
59
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT64
|
60
|
+
when :int64 then
|
61
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT32
|
62
|
+
when :fixed64 then
|
63
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_FIXED64
|
64
|
+
when :fixed32 then
|
65
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_FIXED32
|
66
|
+
when :bool then
|
67
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_BOOL
|
68
|
+
when :string then
|
69
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING
|
70
|
+
when :group then
|
71
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_GROUP
|
72
|
+
when :message then
|
73
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_MESSAGE
|
74
|
+
when :bytes then
|
75
75
|
Google::Protobuf::FieldDescriptorProto::Type::TYPE_BYTES
|
76
|
-
when :uint32
|
77
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT32
|
78
|
-
when :enum
|
79
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_ENUM
|
80
|
-
when :sfixed32
|
81
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_SFIXED32
|
82
|
-
when :sfixed64
|
83
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_SFIXED64
|
84
|
-
when :sint32
|
85
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_SINT32
|
86
|
-
when :sint64
|
87
|
-
Google::Protobuf::FieldDescriptorProto::Type::TYPE_SINT64
|
76
|
+
when :uint32 then
|
77
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT32
|
78
|
+
when :enum then
|
79
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_ENUM
|
80
|
+
when :sfixed32 then
|
81
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_SFIXED32
|
82
|
+
when :sfixed64 then
|
83
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_SFIXED64
|
84
|
+
when :sint32 then
|
85
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_SINT32
|
86
|
+
when :sint64 then
|
87
|
+
Google::Protobuf::FieldDescriptorProto::Type::TYPE_SINT64
|
88
88
|
else
|
89
89
|
Google::Protobuf::FieldDescriptorProto::Type::TYPE_MESSAGE
|
90
90
|
end
|
@@ -93,11 +93,11 @@ module Protobuf
|
|
93
93
|
def self.id2label(label_id)
|
94
94
|
require 'protobuf/descriptor/descriptor_proto'
|
95
95
|
case label_id
|
96
|
-
when Google::Protobuf::FieldDescriptorProto::Label::LABEL_REQUIRED
|
96
|
+
when Google::Protobuf::FieldDescriptorProto::Label::LABEL_REQUIRED then
|
97
97
|
:required
|
98
|
-
when Google::Protobuf::FieldDescriptorProto::Label::LABEL_OPTIONAL
|
98
|
+
when Google::Protobuf::FieldDescriptorProto::Label::LABEL_OPTIONAL then
|
99
99
|
:optional
|
100
|
-
when Google::Protobuf::FieldDescriptorProto::Label::LABEL_REPEATED
|
100
|
+
when Google::Protobuf::FieldDescriptorProto::Label::LABEL_REPEATED then
|
101
101
|
:repeated
|
102
102
|
else
|
103
103
|
raise ArgumentError, "Invalid label: #{proto.label}"
|
@@ -108,11 +108,11 @@ module Protobuf
|
|
108
108
|
require 'protobuf/descriptor/descriptor_proto'
|
109
109
|
case label
|
110
110
|
when :required
|
111
|
-
Google::Protobuf::FieldDescriptorProto::Label::LABEL_REQUIRED
|
111
|
+
Google::Protobuf::FieldDescriptorProto::Label::LABEL_REQUIRED then
|
112
112
|
when :optional
|
113
|
-
Google::Protobuf::FieldDescriptorProto::Label::LABEL_OPTIONAL
|
113
|
+
Google::Protobuf::FieldDescriptorProto::Label::LABEL_OPTIONAL then
|
114
114
|
when :repeated
|
115
|
-
Google::Protobuf::FieldDescriptorProto::Label::LABEL_REPEATED
|
115
|
+
Google::Protobuf::FieldDescriptorProto::Label::LABEL_REPEATED then
|
116
116
|
else
|
117
117
|
raise ArgumentError, "Invalid label: #{label}"
|
118
118
|
end
|
@@ -32,9 +32,9 @@ module Protobuf
|
|
32
32
|
field_proto.default_value = @field_instance.default.to_s if @field_instance.default
|
33
33
|
|
34
34
|
case parent_proto
|
35
|
-
when Google::Protobuf::FileDescriptorProto
|
35
|
+
when Google::Protobuf::FileDescriptorProto then
|
36
36
|
parent_proto.extension << field_proto
|
37
|
-
when Google::Protobuf::DescriptorProto
|
37
|
+
when Google::Protobuf::DescriptorProto then
|
38
38
|
if extension
|
39
39
|
parent_proto.extension << field_proto
|
40
40
|
else
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'fiber'
|
2
|
+
|
3
|
+
# Method and concept from em-synchrony
|
4
|
+
# https://github.com/igrigorik/em-synchrony
|
5
|
+
#
|
6
|
+
# A convenience method for wrapping EM.run body within
|
7
|
+
# a Ruby Fiber such that async operations can be transparently
|
8
|
+
# paused and resumed based on IO scheduling
|
9
|
+
module EventMachine
|
10
|
+
def self.fiber_run(blk=nil, tail=nil, &block)
|
11
|
+
blk ||= block
|
12
|
+
context = Proc.new{ Fiber.new{ blk.call }.resume }
|
13
|
+
|
14
|
+
self.run(context, tail)
|
15
|
+
end
|
16
|
+
end
|
@@ -13,17 +13,17 @@ module Protobuf
|
|
13
13
|
tag, wire_type = read_key(stream)
|
14
14
|
bytes =
|
15
15
|
case wire_type
|
16
|
-
when WireType::VARINT
|
16
|
+
when WireType::VARINT then
|
17
17
|
read_varint(stream)
|
18
|
-
when WireType::FIXED64
|
18
|
+
when WireType::FIXED64 then
|
19
19
|
read_fixed64(stream)
|
20
|
-
when WireType::LENGTH_DELIMITED
|
20
|
+
when WireType::LENGTH_DELIMITED then
|
21
21
|
read_length_delimited(stream)
|
22
|
-
when WireType::START_GROUP
|
22
|
+
when WireType::START_GROUP then
|
23
23
|
read_start_group(stream)
|
24
|
-
when WireType::END_GROUP
|
24
|
+
when WireType::END_GROUP then
|
25
25
|
read_end_group(stream)
|
26
|
-
when WireType::FIXED32
|
26
|
+
when WireType::FIXED32 then
|
27
27
|
read_fixed32(stream)
|
28
28
|
else
|
29
29
|
raise InvalidWireType, wire_type
|
@@ -59,11 +59,11 @@ module Protobuf
|
|
59
59
|
|
60
60
|
@default_value = \
|
61
61
|
case @rule
|
62
|
-
when :repeated
|
62
|
+
when :repeated then
|
63
63
|
FieldArray.new(self).freeze
|
64
|
-
when :required
|
64
|
+
when :required then
|
65
65
|
nil
|
66
|
-
when :optional
|
66
|
+
when :optional then
|
67
67
|
typed_default_value
|
68
68
|
end
|
69
69
|
|
@@ -77,11 +77,11 @@ module Protobuf
|
|
77
77
|
def initialized?(message_instance)
|
78
78
|
value = message_instance.__send__(@name)
|
79
79
|
case @rule
|
80
|
-
when :required
|
80
|
+
when :required then
|
81
81
|
! value.nil? && (! kind_of?(MessageField) || value.initialized?)
|
82
|
-
when :repeated
|
82
|
+
when :repeated then
|
83
83
|
value.all? {|msg| ! kind_of?(MessageField) || msg.initialized? }
|
84
|
-
when :optional
|
84
|
+
when :optional then
|
85
85
|
value.nil? || ! kind_of?(MessageField) || value.initialized?
|
86
86
|
end
|
87
87
|
end
|
@@ -625,11 +625,11 @@ module Protobuf
|
|
625
625
|
@message_class.class_eval do
|
626
626
|
define_method("#{field.name}=") do |val|
|
627
627
|
case val
|
628
|
-
when nil
|
628
|
+
when nil then
|
629
629
|
@values.delete(field.name)
|
630
|
-
when Hash
|
630
|
+
when Hash then
|
631
631
|
@values[field.name] = field.type.new(val)
|
632
|
-
when field.type
|
632
|
+
when field.type then
|
633
633
|
@values[field.name] = val
|
634
634
|
else
|
635
635
|
raise TypeError, "Expected value of type '#{field.type}', but got '#{val.class}'"
|
@@ -647,9 +647,9 @@ module Protobuf
|
|
647
647
|
class EnumField < VarintField
|
648
648
|
def acceptable?(val)
|
649
649
|
case val
|
650
|
-
when Symbol
|
650
|
+
when Symbol then
|
651
651
|
raise TypeError unless @type.const_defined?(val)
|
652
|
-
when EnumValue
|
652
|
+
when EnumValue then
|
653
653
|
raise TypeError if val.parent_class != @type
|
654
654
|
else
|
655
655
|
raise TypeError unless @type.valid_tag?(val)
|
@@ -680,11 +680,11 @@ module Protobuf
|
|
680
680
|
else
|
681
681
|
val = \
|
682
682
|
case val
|
683
|
-
when Symbol
|
683
|
+
when Symbol then
|
684
684
|
field.type.const_get(val) rescue nil
|
685
|
-
when Integer
|
685
|
+
when Integer then
|
686
686
|
field.type.const_get(field.type.name_by_value(val)) rescue nil
|
687
|
-
when EnumValue
|
687
|
+
when EnumValue then
|
688
688
|
raise TypeError, "Invalid value: #{val.inspect}" if val.parent_class != field.type
|
689
689
|
val
|
690
690
|
end
|
@@ -213,13 +213,13 @@ module Protobuf
|
|
213
213
|
''
|
214
214
|
else
|
215
215
|
case field
|
216
|
-
when Field::MessageField
|
216
|
+
when Field::MessageField then
|
217
217
|
if value.nil?
|
218
218
|
"#{i}#{field.name} {}\n"
|
219
219
|
else
|
220
220
|
"#{i}#{field.name} {\n#{value.inspect(indent + 1)}#{i}}\n"
|
221
221
|
end
|
222
|
-
when Field::EnumField
|
222
|
+
when Field::EnumField then
|
223
223
|
if value.is_a?(EnumValue)
|
224
224
|
"#{i}#{field.name}: #{value.name}\n"
|
225
225
|
else
|
@@ -368,9 +368,9 @@ module Protobuf
|
|
368
368
|
build_value = lambda {|field, value|
|
369
369
|
if !field.optional? || (field.optional? && has_field?(field.name))
|
370
370
|
case field
|
371
|
-
when Field::MessageField
|
371
|
+
when Field::MessageField then
|
372
372
|
value.to_hash
|
373
|
-
when Field::EnumField
|
373
|
+
when Field::EnumField then
|
374
374
|
if value.is_a?(EnumValue)
|
375
375
|
value.to_i
|
376
376
|
elsif value.is_a?(Symbol)
|
data/lib/protobuf/rpc/client.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
require '
|
1
|
+
require 'forwardable'
|
2
2
|
require 'protobuf/common/logger'
|
3
|
-
require 'protobuf/rpc/client_connection'
|
4
|
-
require 'protobuf/rpc/buffer'
|
5
3
|
require 'protobuf/rpc/error'
|
6
|
-
require '
|
4
|
+
require 'protobuf/rpc/connector'
|
7
5
|
|
8
6
|
module Protobuf
|
9
7
|
module Rpc
|
10
8
|
class Client
|
9
|
+
extend Forwardable
|
11
10
|
include Protobuf::Logger::LogMethods
|
12
11
|
|
13
|
-
|
12
|
+
delegate [:options, :success_cb, :failure_cb, :async?] => :@connector
|
13
|
+
attr_reader :connector
|
14
14
|
|
15
15
|
# Create a new client with default options (defined in ClientConnection)
|
16
16
|
# See Service#client for a more convenient way to create a client, as well
|
@@ -25,83 +25,68 @@ module Protobuf
|
|
25
25
|
# :request => request
|
26
26
|
# })
|
27
27
|
#
|
28
|
-
def initialize
|
29
|
-
raise "Invalid client configuration. Service must be defined." if !
|
30
|
-
@
|
31
|
-
|
32
|
-
@success_callback = nil
|
33
|
-
@failure_callback = nil
|
34
|
-
@do_block = !@options[:async]
|
35
|
-
log_debug '[client] Initialized with options: %s' % @options.inspect
|
28
|
+
def initialize opts={}
|
29
|
+
raise "Invalid client configuration. Service must be defined." if !opts[:service] || opts[:service].nil?
|
30
|
+
@connector = Connector.connector_for_platform.new(opts)
|
31
|
+
log_debug '[client] Initialized with options: %s' % opts.inspect
|
36
32
|
end
|
37
33
|
|
38
34
|
# Set a success callback on the client to return the
|
39
35
|
# successful response from the service when it is returned.
|
40
|
-
# If this callback is called,
|
36
|
+
# If this callback is called, failure_cb will NOT be called.
|
41
37
|
# Callback is called regardless of :async setting.
|
42
38
|
#
|
43
|
-
# Client(:service => WidgetService)
|
44
|
-
#
|
45
|
-
# end
|
39
|
+
# client = Client.new(:service => WidgetService)
|
40
|
+
# client.on_success {|res| ... }
|
46
41
|
#
|
47
|
-
def on_success &
|
48
|
-
@
|
42
|
+
def on_success &success_cb
|
43
|
+
@connector.success_cb = success_cb
|
49
44
|
end
|
50
45
|
|
51
46
|
# Set a failure callback on the client to return the
|
52
47
|
# error returned by the service, if any. If this callback
|
53
|
-
# is called,
|
48
|
+
# is called, success_cb will NOT be called.
|
54
49
|
# Callback is called regardless of :async setting.
|
55
50
|
#
|
56
|
-
# Client(:service => WidgetService)
|
57
|
-
#
|
58
|
-
# end
|
51
|
+
# client = Client.new(:service => WidgetService)
|
52
|
+
# client.on_failure {|err| ... }
|
59
53
|
#
|
60
|
-
def on_failure &
|
61
|
-
@
|
54
|
+
def on_failure &failure_cb
|
55
|
+
@connector.failure_cb = failure_cb
|
62
56
|
end
|
63
57
|
|
64
58
|
# Provides a mechanism to call the service method against the client
|
65
|
-
#
|
59
|
+
# which will automatically setup the service_class and method_name
|
66
60
|
# in the wrapper protobuf request.
|
67
61
|
#
|
68
|
-
# # find is not defined by Client which will trigger method_missing
|
69
|
-
# Client(:service => WidgetService).
|
62
|
+
# # The :find method is not defined by Client which will trigger method_missing
|
63
|
+
# Client.new(:service => WidgetService).find do |c|
|
64
|
+
# # This block will be invoked before the request is made
|
65
|
+
# # `c` in this case is the client object you created above
|
66
|
+
# c.on_success {|res| ... }
|
67
|
+
# c.on_failure {|err| ... }
|
68
|
+
# end
|
70
69
|
#
|
71
|
-
def method_missing method, *params
|
72
|
-
service =
|
70
|
+
def method_missing method, *params
|
71
|
+
service = options[:service]
|
73
72
|
unless service.rpcs[service].keys.include?(method)
|
74
73
|
log_error '[client] %s#%s not rpc method, passing to super' % [service.name, method.to_s]
|
75
74
|
super method, *params
|
76
75
|
else
|
77
76
|
log_debug '[client] %s#%s' % [service.name, method.to_s]
|
78
77
|
rpc = service.rpcs[service][method.to_sym]
|
79
|
-
|
80
|
-
log_debug '[client] Request Type: %s' %
|
81
|
-
|
82
|
-
log_debug '[client] Response Type: %s' %
|
83
|
-
|
84
|
-
|
85
|
-
log_debug '[client] Request Data: %s' %
|
78
|
+
options[:request_type] = rpc.request_type
|
79
|
+
log_debug '[client] Request Type: %s' % options[:request_type].name
|
80
|
+
options[:response_type] = rpc.response_type
|
81
|
+
log_debug '[client] Response Type: %s' % options[:response_type].name
|
82
|
+
options[:method] = method.to_s
|
83
|
+
options[:request] = params[0].is_a?(Hash) ? options[:request_type].new(params[0]) : params[0]
|
84
|
+
log_debug '[client] Request Data: %s' % options[:request].inspect
|
86
85
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
log_debug '[client] version = 1.0'
|
92
|
-
|
93
|
-
log_warn deprecation_warning
|
94
|
-
STDOUT.puts deprecation_warning unless Protobuf::Logger.configured?
|
95
|
-
|
96
|
-
on_success {|res| client_callback.call(self, res) }
|
97
|
-
on_failure {|err| client_callback.call(self, nil) }
|
98
|
-
else
|
99
|
-
### TODO Replace block above with this once all client definitions use new event driven approach
|
100
|
-
# Call client to setup on_success and on_failure event callbacks
|
101
|
-
@options[:version] = 2.0
|
102
|
-
log_debug '[client] version = 2.0'
|
103
|
-
client_callback.call(self)
|
104
|
-
end
|
86
|
+
# Call client to setup on_success and on_failure event callbacks
|
87
|
+
if block_given?
|
88
|
+
log_debug '[client] client setup callback given, invoking'
|
89
|
+
yield(self)
|
105
90
|
else
|
106
91
|
log_debug '[client] no callbacks given'
|
107
92
|
end
|
@@ -134,135 +119,9 @@ module Protobuf
|
|
134
119
|
# client.send_request
|
135
120
|
#
|
136
121
|
def send_request
|
137
|
-
|
138
|
-
|
139
|
-
EM.schedule do
|
140
|
-
log_debug '[client] Scheduling client connection to be created on next tick'
|
141
|
-
connection = ClientConnection.connect @options, &ensure_callback
|
142
|
-
connection.on_success &@success_callback unless @success_callback.nil?
|
143
|
-
connection.on_failure &ensure_callback
|
144
|
-
connection.on_complete { @do_block = false } if @do_block
|
145
|
-
log_debug '[client] Connection scheduled'
|
146
|
-
end
|
147
|
-
|
148
|
-
return synchronize_or_return
|
149
|
-
end
|
150
|
-
|
151
|
-
# Block the client call to send_request from returning if
|
152
|
-
# async is false, otherwise do nothing.
|
153
|
-
# Simple blocking algorithm to sleep while @do_block is set to true.
|
154
|
-
# The eventmachine connection has a registered callback to flip
|
155
|
-
# @do_block to false as soon as the response has been received and processed.
|
156
|
-
# If any errors are returned an appropriate RPC_ERROR is sent back to the client
|
157
|
-
# through the failure callback.
|
158
|
-
#
|
159
|
-
def synchronize_or_return
|
160
|
-
if @do_block
|
161
|
-
begin
|
162
|
-
Timeout.timeout(@options[:timeout]) do
|
163
|
-
sleep 0.5 while @do_block
|
164
|
-
true
|
165
|
-
end
|
166
|
-
rescue => ex
|
167
|
-
log_error 'An exception occurred while waiting for server response:'
|
168
|
-
log_error ex.message
|
169
|
-
log_error ex.backtrace.join("\n")
|
170
|
-
|
171
|
-
if ex.is_a?(Timeout::Error)
|
172
|
-
message = 'Client timeout of %d seconds expired' % @options[:timeout]
|
173
|
-
else
|
174
|
-
message = 'Client failed: %s' % ex.message
|
175
|
-
end
|
176
|
-
|
177
|
-
err = ClientError.new(Protobuf::Socketrpc::ErrorReason::RPC_ERROR, message)
|
178
|
-
ensure_callback.call(err)
|
179
|
-
end
|
180
|
-
else
|
181
|
-
true
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
# Returns a proc that ensures any errors will be returned to the client
|
186
|
-
#
|
187
|
-
# If a failure callback was set, just use that as a direct assignment
|
188
|
-
# otherwise implement one here that simply throws an exception, since we
|
189
|
-
# don't want to swallow the black holes.
|
190
|
-
#
|
191
|
-
# TODO: remove "else" portion below once 1.0 is gone
|
192
|
-
#
|
193
|
-
def ensure_callback
|
194
|
-
@ensure_callback ||= begin
|
195
|
-
if @options[:version] == 2.0
|
196
|
-
if @failure_callback.nil?
|
197
|
-
cbk = proc do |error|
|
198
|
-
raise '%s: %s' % [error.code.name, error.message]
|
199
|
-
end
|
200
|
-
else
|
201
|
-
cbk = @failure_callback
|
202
|
-
end
|
203
|
-
else
|
204
|
-
cbk = proc do |error|
|
205
|
-
@error = error
|
206
|
-
@failure_callback ? @failure_callback.call(self) : raise('%s: %s' % [error.code.name, error.message])
|
207
|
-
end
|
208
|
-
end
|
209
|
-
cbk
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
# Annoying deprecation warning to print if you are still on v1 DSL
|
214
|
-
def deprecation_warning
|
215
|
-
%Q{
|
216
|
-
##################################################
|
217
|
-
# Deprecation Warning - Upgrade Client Callbacks
|
218
|
-
# ==============================================
|
219
|
-
#
|
220
|
-
# You are attempting to use two block arguments (presumably client and response)
|
221
|
-
# in your client callback for the call to #{@options[:service].name}.client.#{@options[:method]}.
|
222
|
-
#
|
223
|
-
# The next version of ruby-protobuf will completely remove the
|
224
|
-
# style of client calls that accepts two arguments in favor of a more explicit evented approach.
|
225
|
-
#
|
226
|
-
# You should refactor the code before upgrading to the next version of this gem. An example of callback style v1:
|
227
|
-
#
|
228
|
-
# #{@options[:service]}.client.#{@options[:method]}(request) do |client, response|
|
229
|
-
# if client.failed?
|
230
|
-
# # do something with client.error or client.message
|
231
|
-
# else
|
232
|
-
# # do something with response
|
233
|
-
# end
|
234
|
-
# end
|
235
|
-
#
|
236
|
-
# Refactor the previous example of callback style v1 usage to v2 with the following:
|
237
|
-
#
|
238
|
-
# #{@options[:service]}.client.#{@options[:method]}(request) do |c|
|
239
|
-
# c.on_failure do |error|
|
240
|
-
# # do something with error.code or error.message
|
241
|
-
# end
|
242
|
-
# c.on_success do |response|
|
243
|
-
# # do something with response
|
244
|
-
# end
|
245
|
-
# end
|
246
|
-
#
|
247
|
-
##################################################
|
248
|
-
}
|
249
|
-
end
|
250
|
-
|
251
|
-
# Controller error/failure methods
|
252
|
-
# TODO remove these when v1 is gone
|
253
|
-
def failed?
|
254
|
-
!@error.nil? and !@error[:code].nil?
|
255
|
-
end
|
256
|
-
def error
|
257
|
-
@error[:message] if failed?
|
258
|
-
end
|
259
|
-
def error_reason
|
260
|
-
Protobuf::Socketrpc::ErrorReason.name_by_value(@error[:code]).to_s if failed?
|
261
|
-
end
|
262
|
-
def error_message
|
263
|
-
"%s: %s" % [error_reason, error] if failed?
|
122
|
+
@connector.send_request
|
264
123
|
end
|
265
124
|
|
266
125
|
end
|
267
126
|
end
|
268
|
-
end
|
127
|
+
end
|