protobuf 3.2.1 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
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