protobuf 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/Gemfile.lock +1 -1
  2. data/README.md +138 -126
  3. data/bin/rpc_server +2 -2
  4. data/bin/rprotoc +2 -2
  5. data/examples/reading_a_message.rb +3 -3
  6. data/examples/writing_a_message.rb +3 -3
  7. data/lib/protobuf.rb +3 -0
  8. data/lib/protobuf/compiler/nodes.rb +1 -1
  9. data/lib/protobuf/compiler/proto_parser.rb +16 -16
  10. data/lib/protobuf/compiler/visitors.rb +11 -25
  11. data/lib/protobuf/descriptor/descriptor_builder.rb +58 -58
  12. data/lib/protobuf/descriptor/field_descriptor.rb +2 -2
  13. data/lib/protobuf/ext/eventmachine.rb +16 -0
  14. data/lib/protobuf/message/decoder.rb +6 -6
  15. data/lib/protobuf/message/field.rb +14 -14
  16. data/lib/protobuf/message/message.rb +4 -4
  17. data/lib/protobuf/rpc/client.rb +42 -183
  18. data/lib/protobuf/rpc/connector.rb +19 -0
  19. data/lib/protobuf/rpc/connectors/base.rb +29 -0
  20. data/lib/protobuf/rpc/connectors/em_client.rb +227 -0
  21. data/lib/protobuf/rpc/connectors/eventmachine.rb +84 -0
  22. data/lib/protobuf/rpc/connectors/socket.rb +14 -0
  23. data/lib/protobuf/rpc/service.rb +4 -4
  24. data/lib/protobuf/version.rb +1 -1
  25. data/protobuf.gemspec +3 -3
  26. data/spec/helper/all.rb +13 -0
  27. data/spec/helper/server.rb +36 -0
  28. data/spec/helper/tolerance_matcher.rb +40 -0
  29. data/spec/spec_helper.rb +3 -5
  30. data/spec/unit/rpc/client_spec.rb +174 -0
  31. data/spec/unit/rpc/connector_spec.rb +36 -0
  32. data/spec/unit/rpc/connectors/base_spec.rb +77 -0
  33. data/spec/unit/rpc/connectors/eventmachine/client_spec.rb +0 -0
  34. data/spec/unit/rpc/connectors/eventmachine_spec.rb +0 -0
  35. data/spec/unit/{server_spec.rb → rpc/server_spec.rb} +0 -0
  36. data/spec/unit/{service_spec.rb → rpc/service_spec.rb} +0 -0
  37. metadata +79 -63
  38. data/lib/protobuf/compiler/template/rpc_bin.erb +0 -4
  39. data/lib/protobuf/compiler/template/rpc_client.erb +0 -18
  40. data/lib/protobuf/compiler/template/rpc_service.erb +0 -25
  41. data/lib/protobuf/rpc/client_connection.rb +0 -225
  42. 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 Google::Protobuf::FieldDescriptorProto::Type::TYPE_BOOL
67
- :bool
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)
@@ -1,16 +1,16 @@
1
- require 'eventmachine'
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 'timeout'
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
- attr_reader :error, :options, :do_block
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 options={}
29
- raise "Invalid client configuration. Service must be defined." if !options[:service] || options[:service].nil?
30
- @error = {}
31
- @options = ClientConnection::DEFAULT_OPTIONS.merge(options)
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, failure_callback will NOT be 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).new.find do |c|
44
- # c.on_success {|res| ... }
45
- # end
39
+ # client = Client.new(:service => WidgetService)
40
+ # client.on_success {|res| ... }
46
41
  #
47
- def on_success &success_callback
48
- @success_callback = success_callback
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, success_callback will NOT be 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).new.find do |c|
57
- # c.on_failure {|err| ... }
58
- # end
51
+ # client = Client.new(:service => WidgetService)
52
+ # client.on_failure {|err| ... }
59
53
  #
60
- def on_failure &failure_callback
61
- @failure_callback = failure_callback
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
- # and will automatically setup the service_class and method_name
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).new.find
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, &client_callback
72
- service = @options[: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
- @options[:request_type] = rpc.request_type
80
- log_debug '[client] Request Type: %s' % @options[:request_type].name
81
- @options[:response_type] = rpc.response_type
82
- log_debug '[client] Response Type: %s' % @options[:response_type].name
83
- @options[:method] = method.to_s
84
- @options[:request] = params[0].is_a?(Hash) ? @options[:request_type].new(params[0]) : params[0]
85
- log_debug '[client] Request Data: %s' % @options[:request].inspect
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
- #### TODO remove first part here once we are able to convert everything to the new event based way of handling success/failure
88
- unless client_callback.nil?
89
- if client_callback.arity == 2
90
- @options[:version] = 1.0
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
- Thread.new { EM.run } unless EM.reactor_running?
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