protobuf 3.2.1 → 3.3.0

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/lib/protobuf/cli.rb CHANGED
@@ -1,12 +1,13 @@
1
1
  require 'thor'
2
2
  require 'protobuf/version'
3
- require 'protobuf/logger'
3
+ require 'protobuf/logging'
4
4
  require 'protobuf/rpc/servers/socket_runner'
5
5
  require 'protobuf/rpc/servers/zmq_runner'
6
6
 
7
7
  module Protobuf
8
8
  class CLI < ::Thor
9
9
  include ::Thor::Actions
10
+ include ::Protobuf::Logging
10
11
 
11
12
  attr_accessor :runner, :mode
12
13
 
@@ -21,7 +22,7 @@ module Protobuf
21
22
  option :threshold, :type => :numeric, :default => 100, :aliases => %w(-t), :desc => 'Multi-threaded Socket Server cleanup threshold.'
22
23
  option :threads, :type => :numeric, :default => 5, :aliases => %w(-r), :desc => 'Number of worker threads to run. Only applicable in --zmq mode.'
23
24
 
24
- option :log, :type => :string, :aliases => %w(-l), :desc => 'Log file or device. Default is STDOUT.'
25
+ option :log, :type => :string, :default => STDOUT, :aliases => %w(-l), :desc => 'Log file or device. Default is STDOUT.'
25
26
  option :level, :type => :numeric, :default => ::Logger::INFO, :aliases => %w(-v), :desc => 'Log level to use, 0-5 (see http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc/)'
26
27
 
27
28
  option :socket, :type => :boolean, :aliases => %w(-s), :desc => 'Socket Mode for server and client connections.'
@@ -86,12 +87,14 @@ module Protobuf
86
87
  # Setup the protobuf logger.
87
88
  def configure_logger
88
89
  debug_say('Configuring logger')
89
- ::Protobuf::Logger.configure({ :file => options.log || STDOUT,
90
- :level => options.debug? ? ::Logger::DEBUG : options.level })
90
+
91
+ log_level = options.debug? ? ::Logger::DEBUG : options.level
92
+
93
+ ::Protobuf::Logging.initialize_logger(options.log, log_level)
91
94
 
92
95
  # Debug output the server options to the log file.
93
- ::Protobuf::Logger.debug { 'Debugging options:' }
94
- ::Protobuf::Logger.debug { options.inspect }
96
+ logger.debug { 'Debugging options:' }
97
+ logger.debug { options.inspect }
95
98
  end
96
99
 
97
100
  # Re-write the $0 var to have a nice process name in ps.
@@ -185,15 +188,16 @@ module Protobuf
185
188
  end
186
189
 
187
190
  def say_and_exit(message, exception = nil)
188
- message = set_color(message, :red) if ::Protobuf::Logger.file == STDOUT
191
+ message = set_color(message, :red) if options.log == STDOUT
192
+
193
+ logger.error { message }
189
194
 
190
- ::Protobuf::Logger.error { message }
191
195
  if exception
192
196
  $stderr.puts "[#{exception.class.name}] #{exception.message}"
193
197
  $stderr.puts exception.backtrace.join("\n")
194
198
 
195
- ::Protobuf::Logger.error { "[#{exception.class.name}] #{exception.message}" }
196
- ::Protobuf::Logger.debug { exception.backtrace.join("\n") }
199
+ logger.error { "[#{exception.class.name}] #{exception.message}" }
200
+ logger.debug { exception.backtrace.join("\n") }
197
201
  end
198
202
 
199
203
  exit(1)
@@ -212,10 +216,10 @@ module Protobuf
212
216
  end
213
217
 
214
218
  def shutdown_server
215
- ::Protobuf::Logger.info { 'RPC Server shutting down...' }
219
+ logger.info { 'RPC Server shutting down...' }
216
220
  @runner.try(:stop)
217
221
  ::Protobuf::Rpc::ServiceDirectory.instance.stop
218
- ::Protobuf::Logger.info { 'Shutdown complete' }
222
+ logger.info { 'Shutdown complete' }
219
223
  end
220
224
 
221
225
  # Start the runner and log the relevant options.
@@ -223,7 +227,7 @@ module Protobuf
223
227
  debug_say('Running server')
224
228
 
225
229
  @runner.run do
226
- ::Protobuf::Logger.info {
230
+ logger.info {
227
231
  "pid #{::Process.pid} -- #{@runner_mode} RPC Server listening at #{options.host}:#{options.port}"
228
232
  }
229
233
 
@@ -1,9 +1,11 @@
1
- require 'protobuf/wire_type'
2
1
  require 'protobuf/field/field_array'
2
+ require 'protobuf/logging'
3
+ require 'protobuf/wire_type'
3
4
 
4
5
  module Protobuf
5
6
  module Field
6
7
  class BaseField
8
+ include ::Protobuf::Logging
7
9
 
8
10
  ##
9
11
  # Constants
@@ -67,8 +67,8 @@ module Protobuf
67
67
  raise TypeError, "Unacceptable value #{val} for field #{field.name} of type #{field.type_class}"
68
68
  end
69
69
  rescue NoMethodError => ex
70
- ::Protobuf::Logger.error { ex.message }
71
- ::Protobuf::Logger.error { ex.backtrace.join("\n") }
70
+ logger.error { ex.message }
71
+ logger.error { ex.backtrace.join("\n") }
72
72
  raise TypeError, "Got NoMethodError attempting to set #{val} for field #{field.name} of type #{field.type_class}: #{ex.message}"
73
73
  end
74
74
  end
@@ -1,6 +1,6 @@
1
1
  module Protobuf
2
2
  class Lifecycle
3
- include ::Protobuf::Logger::LogMethods
3
+ include ::Protobuf::Logging
4
4
 
5
5
  def self.register(event_name, &blk)
6
6
  raise "Lifecycle register must have a block" unless block_given?
@@ -0,0 +1,49 @@
1
+ module Protobuf
2
+ module Logging
3
+ def self.initialize_logger(log_target=$stdout, log_level=::Logger::INFO)
4
+ @counter ||= 0
5
+ @counter = @counter + 1
6
+ old_logger = defined?(@logger) ? @logger : nil
7
+ @logger = Logger.new(log_target)
8
+ @logger.level = log_level
9
+ old_logger.close if old_logger and close_old_logger?
10
+ @logger
11
+ end
12
+
13
+ def self.close_old_logger=(boolean)
14
+ @close_old_logger = !!boolean
15
+ end
16
+
17
+ def self.close_old_logger?
18
+ defined?(@close_old_logger) ? @close_old_logger : true
19
+ end
20
+
21
+ def self.logger
22
+ defined?(@logger) ? @logger : initialize_logger
23
+ end
24
+
25
+ def self.logger=(new_logger)
26
+ @logger = new_logger
27
+ end
28
+
29
+ def logger
30
+ ::Protobuf::Logging.logger
31
+ end
32
+
33
+ def log_exception(ex)
34
+ logger.error { ex.message }
35
+ logger.error { ex.backtrace[0..5].join("\n") }
36
+ logger.debug { ex.backtrace.join("\n") }
37
+ end
38
+
39
+ def log_signature
40
+ @_log_signature ||= "[#{self.class == Class ? self.name : self.class.name}]"
41
+ end
42
+
43
+ def sign_message(message)
44
+ "#{log_signature} #{message}"
45
+ end
46
+ end
47
+ end
48
+
49
+ # Inspired by [mperham](https://github.com/mperham/sidekiq)
@@ -1,6 +1,6 @@
1
1
  require 'forwardable'
2
2
  require 'protobuf'
3
- require 'protobuf/logger'
3
+ require 'protobuf/logging'
4
4
  require 'protobuf/rpc/error'
5
5
  require 'protobuf/rpc/connector'
6
6
 
@@ -8,7 +8,7 @@ module Protobuf
8
8
  module Rpc
9
9
  class Client
10
10
  extend Forwardable
11
- include Protobuf::Logger::LogMethods
11
+ include Protobuf::Logging
12
12
 
13
13
  def_delegators :@connector, :options, :complete_cb, :success_cb, :failure_cb
14
14
  attr_reader :connector
@@ -29,7 +29,7 @@ module Protobuf
29
29
  def initialize(options = {})
30
30
  raise "Invalid client configuration. Service must be defined." if options[:service].nil?
31
31
  @connector = Connector.connector_for_client.new(options)
32
- log_debug { sign_message("Initialized with options: #{options.inspect}") }
32
+ logger.debug { sign_message("Initialized with options: #{options.inspect}") }
33
33
  end
34
34
 
35
35
  def log_signature
@@ -106,28 +106,28 @@ module Protobuf
106
106
  def method_missing(method_name, *params)
107
107
  service = options[:service]
108
108
  unless service.rpc_method?(method_name)
109
- log_error { sign_message("#{service.name}##{method_name.to_s} not rpc method, passing to super") }
109
+ logger.error { sign_message("#{service.name}##{method_name.to_s} not rpc method, passing to super") }
110
110
  super(method_name, *params)
111
111
  else
112
- log_debug { sign_message("#{service.name}##{method_name.to_s}") }
112
+ logger.debug { sign_message("#{service.name}##{method_name.to_s}") }
113
113
  rpc = service.rpcs[method_name.to_sym]
114
114
 
115
115
  options[:request_type] = rpc.request_type
116
- log_debug { sign_message("Request Type: #{options[:request_type].name}") }
116
+ logger.debug { sign_message("Request Type: #{options[:request_type].name}") }
117
117
 
118
118
  options[:response_type] = rpc.response_type
119
- log_debug { sign_message("Response Type: #{options[:response_type].name}") }
119
+ logger.debug { sign_message("Response Type: #{options[:response_type].name}") }
120
120
 
121
121
  options[:method] = method_name.to_s
122
122
  options[:request] = params[0].is_a?(Hash) ? options[:request_type].new(params[0]) : params[0]
123
- log_debug { sign_message("Request Data: #{options[:request].inspect}") }
123
+ logger.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 { sign_message("client setup callback given, invoking") }
127
+ logger.debug { sign_message("client setup callback given, invoking") }
128
128
  yield(self)
129
129
  else
130
- log_debug { sign_message("no block given for callbacks") }
130
+ logger.debug { sign_message("no block given for callbacks") }
131
131
  end
132
132
 
133
133
  send_request
@@ -1,5 +1,5 @@
1
1
  require 'timeout'
2
- require 'protobuf/logger'
2
+ require 'protobuf/logging'
3
3
  require 'protobuf/rpc/rpc.pb'
4
4
  require 'protobuf/rpc/buffer'
5
5
  require 'protobuf/rpc/error'
@@ -23,7 +23,7 @@ module Protobuf
23
23
  }
24
24
 
25
25
  class Base
26
- include Protobuf::Logger::LogMethods
26
+ include Protobuf::Logging
27
27
 
28
28
  attr_reader :options
29
29
  attr_accessor :success_cb, :failure_cb, :complete_cb
@@ -19,17 +19,17 @@ module Protobuf
19
19
 
20
20
  def complete
21
21
  @stats.stop
22
- log_info { @stats.to_s }
23
- log_debug { sign_message('Response proceessing complete') }
22
+ logger.info { @stats.to_s }
23
+ logger.debug { sign_message('Response proceessing complete') }
24
24
  @complete_cb.call(self) unless @complete_cb.nil?
25
25
  rescue => e
26
- log_error { sign_message('Complete callback error encountered') }
26
+ logger.error { sign_message('Complete callback error encountered') }
27
27
  log_exception(e)
28
28
  raise
29
29
  end
30
30
 
31
31
  def data_callback(data)
32
- log_debug { sign_message('Using data_callback') }
32
+ logger.debug { sign_message('Using data_callback') }
33
33
  @used_data_callback = true
34
34
  @data = data
35
35
  end
@@ -42,11 +42,11 @@ module Protobuf
42
42
  @error = ClientError.new
43
43
  @error.code = Protobuf::Socketrpc::ErrorReason.fetch(code)
44
44
  @error.message = message
45
- log_debug { sign_message("Server failed request (invoking on_failure): #{@error.inspect}") }
45
+ logger.debug { sign_message("Server failed request (invoking on_failure): #{@error.inspect}") }
46
46
 
47
47
  @failure_cb.call(@error) unless @failure_cb.nil?
48
48
  rescue => e
49
- log_error { sign_message("Failure callback error encountered") }
49
+ logger.error { sign_message("Failure callback error encountered") }
50
50
  log_exception(e)
51
51
  raise
52
52
  ensure
@@ -71,7 +71,7 @@ module Protobuf
71
71
  # Close up the connection as we no longer need it
72
72
  close_connection
73
73
 
74
- log_debug { sign_message("Parsing response from server (connection closed)") }
74
+ logger.debug { sign_message("Parsing response from server (connection closed)") }
75
75
 
76
76
  # Parse out the raw response
77
77
  @stats.response_size = @response_data.size unless @response_data.nil?
@@ -79,13 +79,13 @@ module Protobuf
79
79
 
80
80
  # Determine success or failure based on parsed data
81
81
  if response_wrapper.has_field?(:error_reason)
82
- log_debug { sign_message("Error response parsed") }
82
+ logger.debug { sign_message("Error response parsed") }
83
83
 
84
84
  # fail the call if we already know the client is failed
85
85
  # (don't try to parse out the response payload)
86
86
  fail(response_wrapper.error_reason, response_wrapper.error)
87
87
  else
88
- log_debug { sign_message("Successful response parsed") }
88
+ logger.debug { sign_message("Successful response parsed") }
89
89
 
90
90
  # Ensure client_response is an instance
91
91
  parsed = @options[:response_type].decode(response_wrapper.response_proto.to_s)
@@ -125,10 +125,10 @@ module Protobuf
125
125
  end
126
126
 
127
127
  def succeed(response)
128
- log_debug { sign_message("Server succeeded request (invoking on_success)") }
128
+ logger.debug { sign_message("Server succeeded request (invoking on_success)") }
129
129
  @success_cb.call(response) unless @success_cb.nil?
130
130
  rescue => e
131
- log_error { sign_message("Success callback error encountered") }
131
+ logger.error { sign_message("Success callback error encountered") }
132
132
  log_exception(e)
133
133
  fail(:RPC_ERROR, "An exception occurred while calling on_success: #{e.message}")
134
134
  ensure
@@ -153,7 +153,7 @@ module Protobuf
153
153
 
154
154
  def verify_callbacks
155
155
  unless any_callbacks?
156
- log_debug { sign_message("No callbacks set, using data_callback") }
156
+ logger.debug { sign_message("No callbacks set, using data_callback") }
157
157
  @success_cb = @failure_cb = self.method(:data_callback)
158
158
  end
159
159
  end
@@ -5,7 +5,7 @@ module Protobuf
5
5
  module Connectors
6
6
  class Socket < Base
7
7
  include Protobuf::Rpc::Connectors::Common
8
- include Protobuf::Logger::LogMethods
8
+ include Protobuf::Logging
9
9
 
10
10
  def send_request
11
11
  timeout_wrap do
@@ -24,18 +24,18 @@ module Protobuf
24
24
 
25
25
  def close_connection
26
26
  @socket.close
27
- log_debug { sign_message('Connector closed') }
27
+ logger.debug { sign_message('Connector closed') }
28
28
  end
29
29
 
30
30
  def connect_to_rpc_server
31
31
  @socket = TCPSocket.new(options[:host], options[:port])
32
- log_debug { sign_message("Connection established #{options[:host]}:#{options[:port]}") }
32
+ logger.debug { sign_message("Connection established #{options[:host]}:#{options[:port]}") }
33
33
  end
34
34
 
35
35
  # Method to determine error state, must be used with Connector api
36
36
  def error?
37
37
  return true if @error
38
- log_debug { sign_message("Error state : #{@socket.closed?}") }
38
+ logger.debug { sign_message("Error state : #{@socket.closed?}") }
39
39
  @socket.closed?
40
40
  end
41
41
 
@@ -51,7 +51,7 @@ module Protobuf
51
51
  end
52
52
 
53
53
  def read_response
54
- log_debug { sign_message("error? is #{error?}") }
54
+ logger.debug { sign_message("error? is #{error?}") }
55
55
  return if error?
56
56
  response_buffer = ::Protobuf::Rpc::Buffer.new(:read)
57
57
  response_buffer << read_data
@@ -65,7 +65,7 @@ module Protobuf
65
65
  request_buffer.set_data(@request_data)
66
66
  @socket.write(request_buffer.write)
67
67
  @socket.flush
68
- log_debug { sign_message("write closed") }
68
+ logger.debug { sign_message("write closed") }
69
69
  end
70
70
  end
71
71
  end
@@ -12,7 +12,7 @@ module Protobuf
12
12
  # Included Modules
13
13
  #
14
14
  include Protobuf::Rpc::Connectors::Common
15
- include Protobuf::Logger::LogMethods
15
+ include Protobuf::Logging
16
16
 
17
17
  ##
18
18
  # Class Constants
@@ -71,9 +71,9 @@ module Protobuf
71
71
  if socket # Make sure the context builds the socket
72
72
  socket.setsockopt(::ZMQ::LINGER, 0)
73
73
 
74
- log_debug { sign_message("Establishing connection: #{server_uri}") }
74
+ logger.debug { sign_message("Establishing connection: #{server_uri}") }
75
75
  zmq_error_check(socket.connect(server_uri), :socket_connect)
76
- log_debug { sign_message("Connection established to #{server_uri}") }
76
+ logger.debug { sign_message("Connection established to #{server_uri}") }
77
77
 
78
78
  if first_alive_load_balance?
79
79
  begin
@@ -123,6 +123,8 @@ module Protobuf
123
123
  def host_alive?(host)
124
124
  return true unless ping_port_enabled?
125
125
  socket = TCPSocket.new(host, ping_port.to_i)
126
+ socket.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
127
+ socket.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_LINGER, [1,0].pack('ii'))
126
128
 
127
129
  true
128
130
  rescue
@@ -155,21 +157,21 @@ module Protobuf
155
157
  poller = ::ZMQ::Poller.new
156
158
  poller.register_readable(socket)
157
159
 
158
- log_debug { sign_message("Sending Request (attempt #{attempt}, #{socket})") }
160
+ logger.debug { sign_message("Sending Request (attempt #{attempt}, #{socket})") }
159
161
  zmq_error_check(socket.send_string(@request_data), :socket_send_string)
160
- log_debug { sign_message("Waiting #{timeout} seconds for response (attempt #{attempt}, #{socket})") }
162
+ logger.debug { sign_message("Waiting #{timeout} seconds for response (attempt #{attempt}, #{socket})") }
161
163
 
162
164
  if poller.poll(timeout * 1000) == 1
163
165
  zmq_error_check(socket.recv_string(@response_data = ""), :socket_recv_string)
164
- log_debug { sign_message("Response received (attempt #{attempt}, #{socket})") }
166
+ logger.debug { sign_message("Response received (attempt #{attempt}, #{socket})") }
165
167
  else
166
- log_debug { sign_message("Timed out waiting for response (attempt #{attempt}, #{socket})") }
168
+ logger.debug { sign_message("Timed out waiting for response (attempt #{attempt}, #{socket})") }
167
169
  raise RequestTimeout
168
170
  end
169
171
  ensure
170
- log_debug { sign_message("Closing Socket") }
172
+ logger.debug { sign_message("Closing Socket") }
171
173
  zmq_error_check(socket.close, :socket_close) if socket
172
- log_debug { sign_message("Socket closed") }
174
+ logger.debug { sign_message("Socket closed") }
173
175
  end
174
176
 
175
177
  # The service we're attempting to connect to
@@ -2,7 +2,7 @@ module Protobuf
2
2
  module Rpc
3
3
  module Middleware
4
4
  class ExceptionHandler
5
- include ::Protobuf::Logger::LogMethods
5
+ include ::Protobuf::Logging
6
6
 
7
7
  attr_reader :app
8
8
 
@@ -42,7 +42,7 @@ module Protobuf
42
42
  attr_reader :env
43
43
 
44
44
  def flush(env)
45
- Protobuf::Logger.info { to_s(env) }
45
+ ::Protobuf::Logging.logger.info { to_s(env) }
46
46
  end
47
47
 
48
48
  def start