protobuf 2.0.0.rc3 → 2.0.0.rc4

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.
Files changed (43) hide show
  1. data/lib/protobuf/cli.rb +1 -2
  2. data/lib/protobuf/{common/exceptions.rb → exceptions.rb} +0 -0
  3. data/lib/protobuf/field/base_field.rb +1 -1
  4. data/lib/protobuf/{common/logger.rb → logger.rb} +21 -0
  5. data/lib/protobuf/message/decoder.rb +2 -2
  6. data/lib/protobuf/message/encoder.rb +6 -4
  7. data/lib/protobuf/rpc/buffer.rb +2 -2
  8. data/lib/protobuf/rpc/client.rb +18 -18
  9. data/lib/protobuf/rpc/connectors/base.rb +3 -8
  10. data/lib/protobuf/rpc/connectors/common.rb +29 -28
  11. data/lib/protobuf/rpc/connectors/em_client.rb +9 -9
  12. data/lib/protobuf/rpc/connectors/eventmachine.rb +11 -9
  13. data/lib/protobuf/rpc/connectors/socket.rb +13 -17
  14. data/lib/protobuf/rpc/connectors/zmq.rb +13 -17
  15. data/lib/protobuf/rpc/error.rb +3 -3
  16. data/lib/protobuf/rpc/server.rb +41 -93
  17. data/lib/protobuf/rpc/servers/evented/server.rb +7 -9
  18. data/lib/protobuf/rpc/servers/evented_runner.rb +0 -11
  19. data/lib/protobuf/rpc/servers/socket/server.rb +8 -7
  20. data/lib/protobuf/rpc/servers/socket/worker.rb +22 -15
  21. data/lib/protobuf/rpc/servers/zmq/server.rb +3 -3
  22. data/lib/protobuf/rpc/servers/zmq/util.rb +1 -1
  23. data/lib/protobuf/rpc/servers/zmq/worker.rb +6 -15
  24. data/lib/protobuf/rpc/service.rb +145 -228
  25. data/lib/protobuf/rpc/service_dispatcher.rb +114 -0
  26. data/lib/protobuf/rpc/stat.rb +46 -33
  27. data/lib/protobuf/version.rb +1 -1
  28. data/lib/protobuf/{common/wire_type.rb → wire_type.rb} +0 -0
  29. data/spec/benchmark/tasks.rb +18 -18
  30. data/spec/functional/evented_server_spec.rb +3 -4
  31. data/spec/functional/socket_server_spec.rb +3 -3
  32. data/spec/functional/zmq_server_spec.rb +3 -3
  33. data/spec/lib/protobuf/{common/logger_spec.rb → logger_spec.rb} +46 -36
  34. data/spec/lib/protobuf/rpc/client_spec.rb +10 -58
  35. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +1 -39
  36. data/spec/lib/protobuf/rpc/connectors/common_spec.rb +3 -6
  37. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +0 -12
  38. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +1 -6
  39. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +94 -0
  40. data/spec/lib/protobuf/rpc/service_spec.rb +132 -45
  41. data/spec/spec_helper.rb +4 -3
  42. data/spec/support/server.rb +8 -4
  43. metadata +41 -35
@@ -1,7 +1,6 @@
1
1
  require 'thor'
2
- require 'pry'
3
2
  require 'protobuf/version'
4
- require 'protobuf/common/logger'
3
+ require 'protobuf/logger'
5
4
  require 'protobuf/rpc/servers/evented_runner'
6
5
  require 'protobuf/rpc/servers/socket_runner'
7
6
  require 'protobuf/rpc/servers/zmq_runner'
@@ -1,4 +1,4 @@
1
- require 'protobuf/common/wire_type'
1
+ require 'protobuf/wire_type'
2
2
  require 'protobuf/field/field_array'
3
3
 
4
4
  module Protobuf
@@ -53,13 +53,34 @@ module Protobuf
53
53
  module LogMethods
54
54
  [:debug, :info, :warn, :error, :fatal, :any, :add, :log].each do |m|
55
55
  define_method("log_#{m}") do |*params, &block|
56
+ params.map! { |message| sign_message(message) }
56
57
  Protobuf::Logger.__send__(m, *params, &block)
57
58
  end
58
59
  end
59
60
 
61
+ # When included, also extend the LogMethods module for class access.
60
62
  def self.included(base)
61
63
  base.extend(LogMethods)
62
64
  end
65
+
66
+ # We often want to log an exception, so let's make that a core
67
+ # concern of the logger.
68
+ #
69
+ def log_exception(ex)
70
+ log_error { ex.message }
71
+ log_error { ex.backtrace[0..5].join("\n") }
72
+ log_debug { ex.backtrace.join("\n") }
73
+ end
74
+
75
+ def log_signature
76
+ @_log_signature ||= "[#{self.class == Class ? self.name : self.class.name}]"
77
+ end
78
+
79
+ def sign_message(message)
80
+ "#{log_signature} #{message}"
81
+ end
82
+
63
83
  end
84
+
64
85
  end
65
86
  end
@@ -1,5 +1,5 @@
1
- require 'protobuf/common/wire_type'
2
- require 'protobuf/common/exceptions'
1
+ require 'protobuf/wire_type'
2
+ require 'protobuf/exceptions'
3
3
 
4
4
  module Protobuf
5
5
 
@@ -1,5 +1,5 @@
1
- require 'protobuf/common/wire_type'
2
- require 'protobuf/common/exceptions'
1
+ require 'protobuf/wire_type'
2
+ require 'protobuf/exceptions'
3
3
 
4
4
  module Protobuf
5
5
 
@@ -10,8 +10,10 @@ module Protobuf
10
10
  # Encode +message+ and write to +stream+.
11
11
  def encode(stream, message)
12
12
  # FIXME make this not as ghetto
13
- raise NotInitializedError, "Message %s is not initialized (one or more fields is improperly set): %s" % [message.class.name, JSON.parse(message.to_json)] unless message.initialized?
14
-
13
+ unless message.initialized?
14
+ raise NotInitializedError, "Message #{message.class.name} is not initialized (one or more fields is improperly set): #{JSON.parse(message.to_json)}"
15
+ end
16
+
15
17
  message.each_field do |field, value|
16
18
  next unless message.has_field?(field.name)
17
19
 
@@ -32,7 +32,7 @@ module Protobuf
32
32
  end
33
33
 
34
34
  @size = @data.length
35
- '%d-%s' % [@size, @data]
35
+ "#{@size}-#{@data}"
36
36
  end
37
37
 
38
38
  def <<(data)
@@ -63,7 +63,7 @@ module Protobuf
63
63
  def get_data_size
64
64
  if @size == 0 || @data.match(SIZE_REGEX)
65
65
  sliced_size = @data.slice!(SIZE_REGEX)
66
- @size = sliced_size.gsub('-', '').to_i unless(sliced_size.nil?)
66
+ @size = sliced_size.gsub('-', '').to_i unless sliced_size.nil?
67
67
  end
68
68
  end
69
69
 
@@ -1,6 +1,6 @@
1
1
  require 'forwardable'
2
2
  require 'protobuf'
3
- require 'protobuf/common/logger'
3
+ require 'protobuf/logger'
4
4
  require 'protobuf/rpc/error'
5
5
  require 'protobuf/rpc/connector'
6
6
 
@@ -10,7 +10,7 @@ module Protobuf
10
10
  extend Forwardable
11
11
  include Protobuf::Logger::LogMethods
12
12
 
13
- delegate [:options, :complete_cb, :success_cb, :failure_cb, :async?] => :@connector
13
+ delegate [:options, :complete_cb, :success_cb, :failure_cb] => :@connector
14
14
  attr_reader :connector
15
15
 
16
16
  # Create a new client with default options (defined in ClientConnection)
@@ -29,15 +29,14 @@ module Protobuf
29
29
  def initialize(opts={})
30
30
  raise "Invalid client configuration. Service must be defined." if opts[:service].nil?
31
31
  @connector = Connector.connector_for_client.new(opts)
32
- log_debug { "[#{log_signature}] Initialized with options: %s" % opts.inspect }
32
+ log_debug { sign_message("Initialized with options: #{opts.inspect}") }
33
33
  end
34
34
 
35
35
  def log_signature
36
- @log_signature ||= "client-#{self.class}"
36
+ @_log_signature ||= "client-#{self.class}"
37
37
  end
38
38
 
39
39
  # Set a complete callback on the client to return the object (self).
40
- # Callback is called regardless of :async setting.
41
40
  #
42
41
  # client = Client.new(:service => WidgetService)
43
42
  # client.on_complete {|obj| ... }
@@ -57,7 +56,6 @@ module Protobuf
57
56
  # Set a failure callback on the client to return the
58
57
  # error returned by the service, if any. If this callback
59
58
  # is called, success_cb will NOT be called.
60
- # Callback is called regardless of :async setting.
61
59
  #
62
60
  # client = Client.new(:service => WidgetService)
63
61
  # client.on_failure {|err| ... }
@@ -68,7 +66,7 @@ module Protobuf
68
66
 
69
67
  def on_failure=(callable)
70
68
  if callable != nil && !callable.respond_to?(:call) && callable.arity != 1
71
- raise "callable must take a single argument and respond to :call"
69
+ raise "Callable must take a single argument and respond to :call"
72
70
  end
73
71
 
74
72
  @connector.failure_cb = callable
@@ -77,7 +75,6 @@ module Protobuf
77
75
  # Set a success callback on the client to return the
78
76
  # successful response from the service when it is returned.
79
77
  # If this callback is called, failure_cb will NOT be called.
80
- # Callback is called regardless of :async setting.
81
78
  #
82
79
  # client = Client.new(:service => WidgetService)
83
80
  # client.on_success {|res| ... }
@@ -88,7 +85,7 @@ module Protobuf
88
85
 
89
86
  def on_success=(callable)
90
87
  if callable != nil && !callable.respond_to?(:call) && callable.arity != 1
91
- raise "callable must take a single argument and respond to :call"
88
+ raise "Callable must take a single argument and respond to :call"
92
89
  end
93
90
 
94
91
  @connector.success_cb = callable
@@ -108,26 +105,29 @@ module Protobuf
108
105
  #
109
106
  def method_missing(method, *params)
110
107
  service = options[:service]
111
- unless service.rpcs[service].keys.include?(method)
112
- log_error { "[#{log_signature}] %s#%s not rpc method, passing to super" % [service.name, method.to_s] }
108
+ unless service.rpc_method?(method)
109
+ log_error { sign_message("#{service.name}##{method.to_s} not rpc method, passing to super") }
113
110
  super(method, *params)
114
111
  else
115
- log_debug { "[#{log_signature}] %s#%s" % [service.name, method.to_s] }
116
- rpc = service.rpcs[service][method.to_sym]
112
+ log_debug { sign_message("#{service.name}##{method.to_s}") }
113
+ rpc = service.rpcs[method.to_sym]
114
+
117
115
  options[:request_type] = rpc.request_type
118
- log_debug { "[#{log_signature}] Request Type: %s" % options[:request_type].name }
116
+ log_debug { sign_message("Request Type: #{options[:request_type].name}") }
117
+
119
118
  options[:response_type] = rpc.response_type
120
- log_debug { "[#{log_signature}] Response Type: %s" % options[:response_type].name }
119
+ log_debug { sign_message("Response Type: #{options[:response_type].name}") }
120
+
121
121
  options[:method] = method.to_s
122
122
  options[:request] = params[0].is_a?(Hash) ? options[:request_type].new(params[0]) : params[0]
123
- log_debug { "[#{log_signature}] Request Data: %s" % options[:request].inspect }
123
+ log_debug { sign_message("Request Data: #{options[:request].inspect}") }
124
124
 
125
125
  # Call client to setup on_success and on_failure event callbacks
126
126
  if block_given?
127
- log_debug { "[#{log_signature}] client setup callback given, invoking" }
127
+ log_debug { sign_message("client setup callback given, invoking") }
128
128
  yield(self)
129
129
  else
130
- log_debug { "[#{log_signature}] no block given for callbacks" }
130
+ log_debug { sign_message("no block given for callbacks") }
131
131
  end
132
132
 
133
133
  send_request
@@ -1,4 +1,4 @@
1
- require 'protobuf/common/logger'
1
+ require 'protobuf/logger'
2
2
  require 'protobuf/rpc/rpc.pb'
3
3
  require 'protobuf/rpc/buffer'
4
4
  require 'protobuf/rpc/error'
@@ -16,27 +16,22 @@ module Protobuf
16
16
  :request => nil, # The request object sent by the client
17
17
  :request_type => nil, # The request type expected by the client
18
18
  :response_type => nil, # The response type expected by the client
19
- :async => false, # Whether or not to block a client call, this is actually handled by client.rb
20
19
  :timeout => 30 # The default timeout for the request, also handled by client.rb
21
20
  }
22
21
 
23
22
  class Base
24
23
  include Protobuf::Logger::LogMethods
25
-
24
+
26
25
  attr_reader :options
27
26
  attr_accessor :success_cb, :failure_cb, :complete_cb
28
27
 
29
28
  def initialize(options)
30
29
  @options = DEFAULT_OPTIONS.merge(options)
31
30
  end
32
-
31
+
33
32
  def send_request
34
33
  raise 'If you inherit a Connector from Base you must implement send_request'
35
34
  end
36
-
37
- def async?
38
- !!@options[:async]
39
- end
40
35
  end
41
36
  end
42
37
  end
@@ -12,23 +12,23 @@ module Protobuf
12
12
  end
13
13
 
14
14
  def complete
15
- @stats.end
16
- @stats.log_stats
17
- log_debug { "[#{log_signature}] Response proceessing complete" }
15
+ @stats.stop
16
+ log_info { @stats.to_s }
17
+ log_debug { sign_message('Response proceessing complete') }
18
18
  @complete_cb.call(self) unless @complete_cb.nil?
19
- rescue
20
- log_error { "[#{log_signature}] Complete callback error encountered: %s" % $!.message }
21
- log_error { "[#{log_signature}] %s" % $!.backtrace.join("\n") }
19
+ rescue => e
20
+ log_error { sign_message('Complete callback error encountered') }
21
+ log_exception(e)
22
22
  raise
23
23
  end
24
24
 
25
25
  def data_callback(data)
26
- log_debug { "[#{log_signature}] Using data_callback" }
26
+ log_debug { sign_message('Using data_callback') }
27
27
  @used_data_callback = true
28
28
  @data = data
29
29
  end
30
30
 
31
- # All failures should be routed through this method
31
+ # All failures should be routed through this method.
32
32
  #
33
33
  # @param [Symbol] code The code we're using (see ::Protobuf::Socketrpc::ErrorReason)
34
34
  # @param [String] message The error message
@@ -36,35 +36,36 @@ module Protobuf
36
36
  @error = ClientError.new
37
37
  @error.code = code.is_a?(Symbol) ? Protobuf::Socketrpc::ErrorReason.values[code] : code
38
38
  @error.message = message
39
- log_debug { "[#{log_signature}] Server failed request (invoking on_failure): %s" % @error.inspect }
39
+ log_debug { sign_message("Server failed request (invoking on_failure): #{@error.inspect}") }
40
40
 
41
41
  @failure_cb.call(@error) unless @failure_cb.nil?
42
- rescue
43
- log_error { "[#{log_signature}] Failure callback error encountered: %s" % $!.message }
44
- log_error { "[#{log_signature}] %s" % $!.backtrace.join("\n") }
42
+ rescue => e
43
+ log_error { sign_message("Failure callback error encountered") }
44
+ log_exception(e)
45
45
  raise
46
46
  ensure
47
47
  complete
48
48
  end
49
49
 
50
50
  def initialize_stats
51
- @stats = Protobuf::Rpc::Stat.new(:CLIENT, true)
51
+ @stats = Protobuf::Rpc::Stat.new(:CLIENT)
52
52
  @stats.server = [@options[:port], @options[:host]]
53
53
  @stats.service = @options[:service].name
54
54
  @stats.method = @options[:method].to_s
55
55
  rescue => ex
56
+ log_exception(ex)
56
57
  fail(:RPC_ERROR, "Invalid stats configuration. #{ex.message}")
57
58
  end
58
59
 
59
60
  def log_signature
60
- @log_signature ||= "client-#{self.class}"
61
+ @_log_signature ||= "client-#{self.class}"
61
62
  end
62
63
 
63
64
  def parse_response
64
65
  # Close up the connection as we no longer need it
65
66
  close_connection
66
67
 
67
- log_debug { "[#{log_signature}] Parsing response from server (connection closed)" }
68
+ log_debug { sign_message("Parsing response from server (connection closed)") }
68
69
 
69
70
  # Parse out the raw response
70
71
  response_wrapper = Protobuf::Socketrpc::Response.new
@@ -72,13 +73,13 @@ module Protobuf
72
73
 
73
74
  # Determine success or failure based on parsed data
74
75
  if response_wrapper.has_field?(:error_reason)
75
- log_debug { "[#{log_signature}] Error response parsed" }
76
+ log_debug { sign_message("Error response parsed") }
76
77
 
77
78
  # fail the call if we already know the client is failed
78
79
  # (don't try to parse out the response payload)
79
80
  fail(response_wrapper.error_reason, response_wrapper.error)
80
81
  else
81
- log_debug { "[#{log_signature}] Successful response parsed" }
82
+ log_debug { sign_message("Successful response parsed") }
82
83
 
83
84
  # Ensure client_response is an instance
84
85
  response_type = @options[:response_type].new
@@ -96,8 +97,8 @@ module Protobuf
96
97
 
97
98
  def post_init
98
99
  send_data unless error?
99
- rescue
100
- fail(:RPC_ERROR, 'Connection error: %s' % $!.message)
100
+ rescue => e
101
+ fail(:RPC_ERROR, "Connection error: #{e.message}")
101
102
  end
102
103
 
103
104
  def rpc_request_data
@@ -108,8 +109,8 @@ module Protobuf
108
109
  :method_name => @options[:method].to_s,
109
110
  :request_proto => @options[:request].serialize_to_string
110
111
  ).serialize_to_string
111
- rescue
112
- fail :INVALID_REQUEST_PROTO, "Could not set request proto: #{$!.message}"
112
+ rescue => e
113
+ fail(:INVALID_REQUEST_PROTO, "Could not set request proto: #{e.message}")
113
114
  end
114
115
 
115
116
  def setup_connection
@@ -118,12 +119,12 @@ module Protobuf
118
119
  end
119
120
 
120
121
  def succeed(response)
121
- log_debug { "[#{log_signature}] Server succeeded request (invoking on_success)" }
122
+ log_debug { sign_message("Server succeeded request (invoking on_success)") }
122
123
  @success_cb.call(response) unless @success_cb.nil?
123
- rescue
124
- log_error { "[#{log_signature}] Success callback error encountered: %s" % $!.message }
125
- log_error { "[#{log_signature}] %s" % $!.backtrace.join("\n") }
126
- fail :RPC_ERROR, 'An exception occurred while calling on_success: %s' % $!.message
124
+ rescue => e
125
+ log_error { sign_message("Success callback error encountered") }
126
+ log_exception(e)
127
+ fail(:RPC_ERROR, "An exception occurred while calling on_success: #{e.message}")
127
128
  ensure
128
129
  complete
129
130
  end
@@ -132,13 +133,13 @@ module Protobuf
132
133
  unless @options[:request].class == @options[:request_type]
133
134
  expected = @options[:request_type].name
134
135
  actual = @options[:request].class.name
135
- fail :INVALID_REQUEST_PROTO, 'Expected request type to be type of %s, got %s instead' % [expected, actual]
136
+ fail(:INVALID_REQUEST_PROTO, "Expected request type to be type of #{expected}, got #{actual} instead")
136
137
  end
137
138
  end
138
139
 
139
140
  def verify_callbacks
140
141
  if !any_callbacks?
141
- log_debug { "[#{log_signature}] No callbacks set, using data_callback" }
142
+ log_debug { sign_message("No callbacks set, using data_callback") }
142
143
  @success_cb = @failure_cb = self.method(:data_callback)
143
144
  end
144
145
  end
@@ -19,9 +19,9 @@ module Protobuf
19
19
  @response_buffer = ::Protobuf::Rpc::Buffer.new(:read)
20
20
  verify_options
21
21
 
22
- log_debug { "[#{log_signature}] Client Initialized: %s" % options.inspect }
23
- rescue
24
- fail(:RPC_ERROR, 'Failed to initialize connection: %s' % $!.message)
22
+ log_debug { sign_message("Client Initialized: #{options.inspect}") }
23
+ rescue => e
24
+ fail(:RPC_ERROR, "Failed to initialize connection: #{e.message}")
25
25
  end
26
26
 
27
27
  ##
@@ -29,7 +29,7 @@ module Protobuf
29
29
  #
30
30
  def self.connect(options={})
31
31
  options = DEFAULT_OPTIONS.merge(options)
32
- log_debug { "[client-#{self}] Connecting to server: %s" % options.inspect }
32
+ log_debug { sign_message("Connecting to server: #{options.inspect}") }
33
33
  EM.connect(options[:host], options[:port], self, options)
34
34
  end
35
35
 
@@ -56,19 +56,19 @@ module Protobuf
56
56
  end
57
57
 
58
58
  def receive_data(data)
59
- log_debug { "[#{log_signature}] receive_data: %s" % data }
59
+ log_debug { sign_message("receive_data: #{data}") }
60
60
  @response_buffer << data
61
61
  @response_data = @response_buffer.data
62
- parse_response if(!@response_data.nil? && @response_buffer.flushed?)
62
+ parse_response if !@response_data.nil? && @response_buffer.flushed?
63
63
  end
64
64
 
65
65
  def send_data
66
66
  request_buffer = ::Protobuf::Rpc::Buffer.new(:write)
67
67
  request_buffer.set_data(@request_data)
68
- log_debug { "[#{log_signature}] sending data: #{request_buffer.inspect}" }
68
+ log_debug { sign_message("sending data: #{request_buffer.inspect}") }
69
69
  super(request_buffer.write)
70
- rescue
71
- fail(:RPC_ERROR, 'Connection error: %s' % $!.message)
70
+ rescue => e
71
+ fail(:RPC_ERROR, "Connection error: #{e.message}")
72
72
  end
73
73
 
74
74
  # overwriting this method for java because it's broken in eventmachine. See https://github.com/eventmachine/eventmachine/issues/14
@@ -11,17 +11,17 @@ module Protobuf
11
11
  f = Fiber.current
12
12
 
13
13
  ::EM.next_tick do
14
- log_debug { "[#{log_signature}] Scheduling EventMachine client request to be created on next tick" }
14
+ log_debug { sign_message('Scheduling EventMachine client request to be created on next tick') }
15
15
  cnxn = EMClient.connect(options, &ensure_cb)
16
16
  cnxn.on_success(&success_cb) if success_cb
17
17
  cnxn.on_failure(&ensure_cb)
18
- cnxn.on_complete { resume_fiber(f) } unless async?
18
+ cnxn.on_complete { resume_fiber(f) }
19
19
  cnxn.setup_connection
20
20
  cnxn.send_data
21
- log_debug { "[#{log_signature}] Connection scheduled" }
21
+ log_debug { sign_message('Connection scheduled') }
22
22
  end
23
23
 
24
- async? ? true : set_timeout_and_validate_fiber
24
+ set_timeout_and_validate_fiber
25
25
  end
26
26
  end
27
27
 
@@ -32,11 +32,11 @@ module Protobuf
32
32
  # don't want to swallow the black holes.
33
33
  #
34
34
  def ensure_cb
35
- @ensure_cb ||= (@failure_cb || lambda { |error| raise '%s: %s' % [error.code.name, error.message] } )
35
+ @ensure_cb ||= (@failure_cb || lambda { |error| raise "#{error.code.name}: #{error.message}" })
36
36
  end
37
37
 
38
38
  def log_signature
39
- @log_signature ||= "client-#{self.class}"
39
+ @_log_signature ||= "client-#{self.class}"
40
40
  end
41
41
 
42
42
  private
@@ -58,18 +58,20 @@ module Protobuf
58
58
  ::EM::cancel_timer(@timeout_timer)
59
59
  fib.resume(true)
60
60
  rescue => ex
61
- message = 'Synchronous client failed: %s' % ex.message
61
+ log_exception(ex)
62
+ message = "Synchronous client failed: #{ex.message}"
62
63
  error_stop_reactor(message)
63
64
  end
64
65
 
65
66
  def set_timeout_and_validate_fiber
66
67
  @timeout_timer = ::EM::add_timer(@options[:timeout]) do
67
- message = 'Client timeout of %d seconds expired' % @options[:timeout]
68
+ message = "Client timeout of #{@options[:timeout]} seconds expired"
68
69
  error_stop_reactor(message)
69
70
  end
70
71
 
71
72
  Fiber.yield
72
- rescue FiberError
73
+ rescue FiberError => ex
74
+ log_exception(ex)
73
75
  message = "Synchronous calls must be in 'EM.fiber_run' block"
74
76
  error_stop_reactor(message)
75
77
  end