protobuffy 3.6.0 → 4.0.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.
Files changed (209) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +67 -0
  4. data/.rubocop_todo.yml +145 -0
  5. data/.travis.yml +25 -5
  6. data/CHANGES.md +55 -0
  7. data/CONTRIBUTING.md +1 -1
  8. data/LICENSE.txt +17 -9
  9. data/README.md +13 -12
  10. data/Rakefile +15 -11
  11. data/bin/protoc-gen-ruby +8 -3
  12. data/bin/rpc_server +1 -0
  13. data/examples/lib/example/reverse-client.rb +2 -2
  14. data/install-protobuf.sh +28 -0
  15. data/lib/protobuf.rb +57 -53
  16. data/lib/protobuf/cli.rb +94 -74
  17. data/lib/protobuf/code_generator.rb +60 -9
  18. data/lib/protobuf/decoder.rb +19 -65
  19. data/lib/protobuf/deprecation.rb +117 -0
  20. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +11 -1
  21. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +55 -3
  22. data/lib/protobuf/encoder.rb +13 -53
  23. data/lib/protobuf/enum.rb +58 -63
  24. data/lib/protobuf/field.rb +4 -4
  25. data/lib/protobuf/field/base_field.rb +101 -173
  26. data/lib/protobuf/field/bool_field.rb +17 -11
  27. data/lib/protobuf/field/bytes_field.rb +21 -35
  28. data/lib/protobuf/field/double_field.rb +0 -1
  29. data/lib/protobuf/field/enum_field.rb +23 -22
  30. data/lib/protobuf/field/field_array.rb +5 -4
  31. data/lib/protobuf/field/fixed32_field.rb +1 -1
  32. data/lib/protobuf/field/fixed64_field.rb +0 -1
  33. data/lib/protobuf/field/float_field.rb +4 -1
  34. data/lib/protobuf/field/int32_field.rb +0 -1
  35. data/lib/protobuf/field/int64_field.rb +0 -1
  36. data/lib/protobuf/field/integer_field.rb +0 -1
  37. data/lib/protobuf/field/message_field.rb +13 -28
  38. data/lib/protobuf/field/sfixed32_field.rb +0 -1
  39. data/lib/protobuf/field/sfixed64_field.rb +0 -1
  40. data/lib/protobuf/field/signed_integer_field.rb +0 -1
  41. data/lib/protobuf/field/sint32_field.rb +0 -1
  42. data/lib/protobuf/field/sint64_field.rb +0 -1
  43. data/lib/protobuf/field/string_field.rb +2 -4
  44. data/lib/protobuf/field/uint32_field.rb +0 -1
  45. data/lib/protobuf/field/uint64_field.rb +0 -1
  46. data/lib/protobuf/field/varint_field.rb +30 -13
  47. data/lib/protobuf/generators/base.rb +30 -16
  48. data/lib/protobuf/generators/enum_generator.rb +6 -9
  49. data/lib/protobuf/generators/extension_generator.rb +1 -2
  50. data/lib/protobuf/generators/field_generator.rb +25 -13
  51. data/lib/protobuf/generators/file_generator.rb +157 -35
  52. data/lib/protobuf/generators/group_generator.rb +22 -17
  53. data/lib/protobuf/generators/message_generator.rb +13 -14
  54. data/lib/protobuf/generators/option_generator.rb +17 -0
  55. data/lib/protobuf/generators/printable.rb +12 -13
  56. data/lib/protobuf/generators/service_generator.rb +2 -3
  57. data/lib/protobuf/http.rb +2 -2
  58. data/lib/protobuf/lifecycle.rb +20 -33
  59. data/lib/protobuf/logging.rb +39 -0
  60. data/lib/protobuf/message.rb +114 -47
  61. data/lib/protobuf/message/fields.rb +170 -88
  62. data/lib/protobuf/message/serialization.rb +19 -18
  63. data/lib/protobuf/optionable.rb +53 -6
  64. data/lib/protobuf/rpc/buffer.rb +18 -19
  65. data/lib/protobuf/rpc/client.rb +22 -50
  66. data/lib/protobuf/rpc/connectors/base.rb +177 -12
  67. data/lib/protobuf/rpc/connectors/http.rb +14 -9
  68. data/lib/protobuf/rpc/connectors/ping.rb +89 -0
  69. data/lib/protobuf/rpc/connectors/socket.rb +13 -8
  70. data/lib/protobuf/rpc/connectors/zmq.rb +178 -73
  71. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +4 -1
  72. data/lib/protobuf/rpc/env.rb +12 -12
  73. data/lib/protobuf/rpc/error.rb +3 -3
  74. data/lib/protobuf/rpc/error/client_error.rb +4 -4
  75. data/lib/protobuf/rpc/error/server_error.rb +9 -9
  76. data/lib/protobuf/rpc/middleware/exception_handler.rb +6 -2
  77. data/lib/protobuf/rpc/middleware/logger.rb +8 -4
  78. data/lib/protobuf/rpc/middleware/request_decoder.rb +17 -21
  79. data/lib/protobuf/rpc/middleware/response_encoder.rb +22 -27
  80. data/lib/protobuf/rpc/middleware/statsd.rb +3 -3
  81. data/lib/protobuf/rpc/rpc.pb.rb +4 -1
  82. data/lib/protobuf/rpc/server.rb +1 -1
  83. data/lib/protobuf/rpc/servers/http/server.rb +19 -17
  84. data/lib/protobuf/rpc/servers/socket/server.rb +78 -70
  85. data/lib/protobuf/rpc/servers/socket/worker.rb +4 -4
  86. data/lib/protobuf/rpc/servers/socket_runner.rb +27 -15
  87. data/lib/protobuf/rpc/servers/zmq/broker.rb +70 -31
  88. data/lib/protobuf/rpc/servers/zmq/server.rb +55 -47
  89. data/lib/protobuf/rpc/servers/zmq/util.rb +14 -13
  90. data/lib/protobuf/rpc/servers/zmq/worker.rb +16 -16
  91. data/lib/protobuf/rpc/servers/zmq_runner.rb +26 -7
  92. data/lib/protobuf/rpc/service.rb +21 -27
  93. data/lib/protobuf/rpc/service_directory.rb +43 -27
  94. data/lib/protobuf/rpc/service_dispatcher.rb +9 -10
  95. data/lib/protobuf/rpc/service_filters.rb +32 -55
  96. data/lib/protobuf/rpc/stat.rb +4 -8
  97. data/lib/protobuf/socket.rb +1 -2
  98. data/lib/protobuf/tasks/compile.rake +3 -4
  99. data/lib/protobuf/varint.rb +9 -0
  100. data/lib/protobuf/varint_pure.rb +13 -0
  101. data/lib/protobuf/version.rb +1 -1
  102. data/lib/protobuf/zmq.rb +2 -2
  103. data/proto/google/protobuf/descriptor.proto +190 -31
  104. data/protobuffy.gemspec +30 -17
  105. data/spec/benchmark/tasks.rb +27 -19
  106. data/spec/bin/protoc-gen-ruby_spec.rb +11 -6
  107. data/spec/encoding/all_types_spec.rb +96 -84
  108. data/spec/encoding/extreme_values_spec.rb +0 -0
  109. data/spec/functional/class_inheritance_spec.rb +52 -0
  110. data/spec/functional/code_generator_spec.rb +38 -0
  111. data/spec/functional/socket_server_spec.rb +15 -15
  112. data/spec/functional/zmq_server_spec.rb +29 -27
  113. data/spec/lib/protobuf/cli_spec.rb +82 -67
  114. data/spec/lib/protobuf/code_generator_spec.rb +37 -10
  115. data/spec/lib/protobuf/enum_spec.rb +77 -46
  116. data/spec/lib/protobuf/field/bool_field_spec.rb +91 -0
  117. data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
  118. data/spec/lib/protobuf/field/enum_field_spec.rb +26 -0
  119. data/spec/lib/protobuf/field/field_array_spec.rb +69 -0
  120. data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
  121. data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
  122. data/spec/lib/protobuf/field/float_field_spec.rb +90 -0
  123. data/spec/lib/protobuf/field/int32_field_spec.rb +114 -1
  124. data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
  125. data/spec/lib/protobuf/field/message_field_spec.rb +132 -0
  126. data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
  127. data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
  128. data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
  129. data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
  130. data/spec/lib/protobuf/field/string_field_spec.rb +44 -11
  131. data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
  132. data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
  133. data/spec/lib/protobuf/field_spec.rb +4 -6
  134. data/spec/lib/protobuf/generators/base_spec.rb +80 -13
  135. data/spec/lib/protobuf/generators/enum_generator_spec.rb +35 -21
  136. data/spec/lib/protobuf/generators/extension_generator_spec.rb +12 -13
  137. data/spec/lib/protobuf/generators/field_generator_spec.rb +73 -21
  138. data/spec/lib/protobuf/generators/file_generator_spec.rb +89 -6
  139. data/spec/lib/protobuf/generators/service_generator_spec.rb +25 -13
  140. data/spec/lib/protobuf/lifecycle_spec.rb +25 -20
  141. data/spec/lib/protobuf/message_spec.rb +578 -79
  142. data/spec/lib/protobuf/optionable_spec.rb +202 -26
  143. data/spec/lib/protobuf/rpc/client_spec.rb +16 -16
  144. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +167 -13
  145. data/spec/lib/protobuf/rpc/connectors/connector_spec.rb +4 -5
  146. data/spec/lib/protobuf/rpc/connectors/http_spec.rb +13 -11
  147. data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +69 -0
  148. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +6 -7
  149. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +35 -52
  150. data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +10 -10
  151. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +11 -11
  152. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +23 -23
  153. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +11 -11
  154. data/spec/lib/protobuf/rpc/middleware/statsd_spec.rb +6 -6
  155. data/spec/lib/protobuf/rpc/servers/http/server_spec.rb +47 -44
  156. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +6 -6
  157. data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +12 -10
  158. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +11 -11
  159. data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +7 -7
  160. data/spec/lib/protobuf/rpc/service_directory_spec.rb +47 -49
  161. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +8 -25
  162. data/spec/lib/protobuf/rpc/service_filters_spec.rb +102 -69
  163. data/spec/lib/protobuf/rpc/service_spec.rb +37 -36
  164. data/spec/lib/protobuf/rpc/stat_spec.rb +7 -9
  165. data/spec/lib/protobuf/varint_spec.rb +29 -0
  166. data/spec/lib/protobuf_spec.rb +55 -28
  167. data/spec/spec_helper.rb +12 -27
  168. data/spec/support/all.rb +0 -1
  169. data/spec/support/packed_field.rb +4 -3
  170. data/spec/support/{test → protos}/all_types.data.bin +0 -0
  171. data/spec/support/{test → protos}/all_types.data.txt +0 -0
  172. data/spec/support/{test → protos}/enum.pb.rb +8 -4
  173. data/spec/support/{test → protos}/enum.proto +4 -1
  174. data/spec/support/{test → protos}/extreme_values.data.bin +0 -0
  175. data/spec/support/protos/google_unittest.bin +0 -0
  176. data/spec/support/protos/google_unittest.pb.rb +798 -0
  177. data/spec/support/{test → protos}/google_unittest.proto +237 -66
  178. data/spec/support/protos/google_unittest_custom_options.bin +0 -0
  179. data/spec/support/protos/google_unittest_custom_options.pb.rb +268 -0
  180. data/spec/support/protos/google_unittest_custom_options.proto +424 -0
  181. data/spec/support/protos/google_unittest_import.pb.rb +55 -0
  182. data/spec/support/{test → protos}/google_unittest_import.proto +19 -10
  183. data/spec/support/protos/google_unittest_import_public.pb.rb +31 -0
  184. data/spec/support/{test → protos}/google_unittest_import_public.proto +8 -5
  185. data/spec/support/{test → protos}/multi_field_extensions.pb.rb +5 -2
  186. data/spec/support/{test → protos}/multi_field_extensions.proto +2 -0
  187. data/spec/support/{test → protos}/resource.pb.rb +47 -11
  188. data/spec/support/{test → protos}/resource.proto +24 -1
  189. data/spec/support/resource_service.rb +23 -0
  190. data/spec/support/server.rb +32 -61
  191. metadata +119 -59
  192. data/lib/protobuf/deprecator.rb +0 -42
  193. data/lib/protobuf/logger.rb +0 -93
  194. data/lib/protobuf/rpc/connector.rb +0 -21
  195. data/lib/protobuf/rpc/connectors/common.rb +0 -172
  196. data/spec/data/data.bin +0 -3
  197. data/spec/data/types.bin +0 -0
  198. data/spec/lib/protobuf/logger_spec.rb +0 -145
  199. data/spec/lib/protobuf/rpc/connector_spec.rb +0 -26
  200. data/spec/lib/protobuf/rpc/connectors/common_spec.rb +0 -170
  201. data/spec/support/test/defaults.pb.rb +0 -25
  202. data/spec/support/test/defaults.proto +0 -9
  203. data/spec/support/test/extended.pb.rb +0 -22
  204. data/spec/support/test/extended.proto +0 -10
  205. data/spec/support/test/google_unittest.pb.rb +0 -543
  206. data/spec/support/test/google_unittest_import.pb.rb +0 -37
  207. data/spec/support/test/google_unittest_import_public.pb.rb +0 -8
  208. data/spec/support/test/resource_service.rb +0 -26
  209. data/spec/support/tolerance_matcher.rb +0 -40
data/bin/protoc-gen-ruby CHANGED
@@ -10,8 +10,13 @@ require 'protobuf'
10
10
  require 'protobuf/descriptors'
11
11
  require 'protobuf/code_generator'
12
12
 
13
+ # Ensure that no encoding conversions are done on STDIN and STDOUT since
14
+ # we are passing binary data back and forth. Otherwise these streams
15
+ # will be mangled on Windows.
16
+ STDIN.binmode
17
+ STDOUT.binmode
18
+
13
19
  request_bytes = STDIN.read
14
20
  code_generator = ::Protobuf::CodeGenerator.new(request_bytes)
15
- response_bytes = code_generator.response_bytes
16
- STDOUT.print(response_bytes)
17
-
21
+ code_generator.eval_unknown_extensions!
22
+ STDOUT.print(code_generator.response_bytes)
data/bin/rpc_server CHANGED
@@ -2,3 +2,4 @@
2
2
 
3
3
  require 'protobuf/cli'
4
4
  ::Protobuf::CLI.start(ARGV)
5
+ exit
@@ -6,11 +6,11 @@ require_relative "reverse.pb.rb"
6
6
 
7
7
  configuration = {
8
8
  :host => "localhost",
9
- :port => 9399
9
+ :port => 9399,
10
10
  }
11
11
 
12
12
  request = {
13
- :input => (ARGV[0] or 'hello world')
13
+ :input => (ARGV[0] || 'hello world'),
14
14
  }
15
15
 
16
16
  Example::ReverseService.client(configuration).reverse(Example::ReverseRequest.new(request)) do |client|
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env sh
2
+
3
+ set -ex
4
+
5
+ gdie() {
6
+ echo "$@" >&2
7
+ exit 1
8
+ }
9
+
10
+ test -n "$PROTOBUF_VERSION" || die "PROTOBUF_VERSION env var is undefined"
11
+
12
+ case "$PROTOBUF_VERSION" in
13
+ 2*)
14
+ basename=protobuf-$PROTOBUF_VERSION
15
+ ;;
16
+ 3*)
17
+ basename=protobuf-cpp-$PROTOBUF_VERSION
18
+ ;;
19
+ *)
20
+ die "unknown protobuf version: $PROTOBUF_VERSION"
21
+ ;;
22
+ esac
23
+
24
+ curl -sL https://github.com/google/protobuf/releases/download/v$PROTOBUF_VERSION/$basename.tar.gz | tar zx
25
+
26
+ cd protobuf-$PROTOBUF_VERSION
27
+
28
+ ./configure --prefix=/usr && make -j2 && make install
data/lib/protobuf.rb CHANGED
@@ -5,46 +5,50 @@ require 'stringio'
5
5
 
6
6
  require 'active_support/core_ext/object/blank'
7
7
  require 'active_support/core_ext/object/try'
8
- require 'active_support/notifications'
9
8
  require 'active_support/inflector'
10
9
  require 'active_support/json'
10
+ require 'active_support/notifications'
11
11
 
12
- module Protobuf
12
+ # All top-level run time code requires, ordered by necessity
13
+ require 'protobuf/wire_type'
13
14
 
14
- # See Protobuf#connector_type documentation.
15
- CONNECTORS = [ :socket, :zmq, :http ].freeze
15
+ require 'protobuf/varint_pure'
16
+ require 'protobuf/varint'
16
17
 
17
- # Default is Socket as it has no external dependencies.
18
- DEFAULT_CONNECTOR = :socket
18
+ require 'protobuf/exceptions'
19
+ require 'protobuf/deprecation'
20
+ require 'protobuf/logging'
19
21
 
20
- module_function
22
+ require 'protobuf/encoder'
23
+ require 'protobuf/decoder'
21
24
 
22
- # Client Host
23
- #
24
- # Default: `hostname` of the system
25
- #
26
- # The name or address of the host to use during client RPC calls.
27
- def self.client_host
28
- @_client_host ||= `hostname`.chomp
25
+ require 'protobuf/optionable'
26
+ require 'protobuf/field'
27
+ require 'protobuf/enum'
28
+ require 'protobuf/message'
29
+ require 'protobuf/descriptors'
30
+
31
+ module Protobuf
32
+
33
+ class << self
34
+ # Client Host
35
+ #
36
+ # Default: `hostname` of the system
37
+ #
38
+ # The name or address of the host to use during client RPC calls.
39
+ attr_writer :client_host
29
40
  end
30
41
 
31
- def self.client_host=(host)
32
- @_client_host = host
42
+ def self.client_host
43
+ @client_host ||= Socket.gethostname
33
44
  end
34
45
 
35
- # Connector Type
36
- #
37
- # Default: socket
38
- #
39
- # Symbol value which denotes the type of connector to use
40
- # during client requests to an RPC server.
41
- def self.connector_type
42
- @_connector_type ||= DEFAULT_CONNECTOR
46
+ def self.connector_type_class
47
+ @connector_type_class ||= ::Protobuf::Rpc::Connectors::Socket
43
48
  end
44
49
 
45
- def self.connector_type=(type)
46
- raise ArgumentError, 'Invalid connector type given' unless CONNECTORS.include?(type)
47
- @_connector_type = type
50
+ def self.connector_type_class=(type_class)
51
+ @connector_type_class = type_class
48
52
  end
49
53
 
50
54
  # GC Pause during server requests
@@ -56,51 +60,51 @@ module Protobuf
56
60
  # Once the request is completed, the GC is enabled again.
57
61
  # This optomization provides a huge boost in speed to rpc requests.
58
62
  def self.gc_pause_server_request?
59
- return @_gc_pause_server_request unless @_gc_pause_server_request.nil?
63
+ return @gc_pause_server_request unless @gc_pause_server_request.nil?
60
64
  self.gc_pause_server_request = false
61
65
  end
62
66
 
63
67
  def self.gc_pause_server_request=(value)
64
- @_gc_pause_server_request = !!value
68
+ @gc_pause_server_request = !!value
65
69
  end
66
70
 
67
- # Print Deprecation Warnings
71
+ # Permit unknown field on Message initialization
68
72
  #
69
73
  # Default: true
70
74
  #
71
- # Simple boolean to define whether we want field deprecation warnings to
72
- # be printed to stderr or not. The rpc_server has an option to set this value
73
- # explicitly, or you can turn this option off by setting
74
- # ENV['PB_IGNORE_DEPRECATIONS'] to a non-empty value.
75
- #
76
- # The rpc_server option will override the ENV setting.
77
- def self.print_deprecation_warnings?
78
- return @_print_deprecation_warnings unless @_print_deprecation_warnings.nil?
79
- self.print_deprecation_warnings = ENV.key?('PB_IGNORE_DEPRECATIONS') ? false : true
75
+ # Simple boolean to define whether we want to permit unknown fields
76
+ # on Message intialization; otherwise a ::Protobuf::FieldNotDefinedError is thrown.
77
+ def self.ignore_unknown_fields?
78
+ !defined?(@ignore_unknown_fields) || @ignore_unknown_fields
80
79
  end
81
80
 
82
- def self.print_deprecation_warnings=(value)
83
- @_print_deprecation_warnings = !!value
81
+ def self.ignore_unknown_fields=(value)
82
+ @ignore_unknown_fields = !!value
84
83
  end
85
-
86
84
  end
87
85
 
88
86
  unless ENV.key?('PB_NO_NETWORKING')
89
87
  require 'protobuf/rpc/client'
90
88
  require 'protobuf/rpc/service'
91
89
 
92
- env_connector_type = ENV.fetch('PB_CLIENT_TYPE') {
93
- ::Protobuf::DEFAULT_CONNECTOR
94
- }.to_s.downcase.strip.to_sym
90
+ env_connector_type = ENV.fetch('PB_CLIENT_TYPE') do
91
+ :socket
92
+ end
95
93
 
96
- if ::Protobuf::CONNECTORS.include?(env_connector_type)
97
- require "protobuf/#{env_connector_type}"
94
+ symbolized_connector_type = env_connector_type.to_s.downcase.strip.to_sym
95
+ if [:zmq, :socket].include?(symbolized_connector_type)
96
+ require "protobuf/#{symbolized_connector_type}"
97
+
98
+ ::Protobuf.connector_type_class =
99
+ case symbolized_connector_type
100
+ when :zmq
101
+ ::Protobuf::Rpc::Connectors::Zmq
102
+ else
103
+ ::Protobuf::Rpc::Connectors::Socket
104
+ end
98
105
  else
99
- $stderr.puts <<-WARN
100
- [WARNING] Require attempted on an invalid connector type '#{env_connector_type}'.
101
- Falling back to default '#{::Protobuf::DEFAULT_CONNECTOR}' connector.
102
- WARN
103
-
104
- require "protobuf/#{::Protobuf::DEFAULT_CONNECTOR}"
106
+ require "#{env_connector_type}" # rubocop:disable Style/UnneededInterpolation
107
+ classified = env_connector_type.classify
108
+ ::Protobuf.connector_type_class = classified.constantize
105
109
  end
106
110
  end
data/lib/protobuf/cli.rb CHANGED
@@ -1,6 +1,9 @@
1
+ require 'active_support/core_ext/hash/keys'
2
+ require 'active_support/inflector'
3
+
1
4
  require 'thor'
2
5
  require 'protobuf/version'
3
- require 'protobuf/logger'
6
+ require 'protobuf/logging'
4
7
  require 'protobuf/rpc/servers/socket_runner'
5
8
  require 'protobuf/rpc/servers/zmq_runner'
6
9
  require 'protobuf/rpc/servers/http_runner'
@@ -8,8 +11,13 @@ require 'protobuf/rpc/servers/http_runner'
8
11
  module Protobuf
9
12
  class CLI < ::Thor
10
13
  include ::Thor::Actions
14
+ include ::Protobuf::Logging
15
+
16
+ attr_accessor :runner, :mode, :exit_requested
11
17
 
12
- attr_accessor :runner, :mode
18
+ no_commands do
19
+ alias_method :exit_requested?, :exit_requested
20
+ end
13
21
 
14
22
  default_task :start
15
23
 
@@ -22,7 +30,7 @@ module Protobuf
22
30
  option :threshold, :type => :numeric, :default => 100, :aliases => %w(-t), :desc => 'Multi-threaded Socket Server cleanup threshold.'
23
31
  option :threads, :type => :numeric, :default => 5, :aliases => %w(-r), :desc => 'Number of worker threads to run. Only applicable in --zmq mode.'
24
32
 
25
- option :log, :type => :string, :aliases => %w(-l), :desc => 'Log file or device. Default is STDOUT.'
33
+ option :log, :type => :string, :default => STDOUT, :aliases => %w(-l), :desc => 'Log file or device. Default is STDOUT.'
26
34
  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/)'
27
35
 
28
36
  option :socket, :type => :boolean, :aliases => %w(-s), :desc => 'Socket Mode for server and client connections.'
@@ -34,7 +42,7 @@ module Protobuf
34
42
  option :broadcast_beacons, :type => :boolean, :desc => 'Broadcast beacons for dynamic discovery (Currently only available with ZeroMQ).'
35
43
  option :broadcast_busy, :type => :boolean, :default => false, :desc => 'Remove busy nodes from cluster when all workers are busy (Currently only available with ZeroMQ).'
36
44
  option :debug, :type => :boolean, :default => false, :aliases => %w(-d), :desc => 'Debug Mode. Override log level to DEBUG.'
37
- option :gc_pause_request, :type => :boolean, :default => false, :desc => 'Enable/Disable GC pause during request.'
45
+ option :gc_pause_request, :type => :boolean, :default => false, :desc => 'DEPRECATED: Enable/Disable GC pause during request.'
38
46
  option :print_deprecation_warnings, :type => :boolean, :default => nil, :desc => 'Cause use of deprecated fields to be printed or ignored.'
39
47
  option :workers_only, :type => :boolean, :default => false, :desc => "Starts process with only workers (no broker/frontend is started) only relevant for Zmq Server"
40
48
  option :worker_port, :type => :numeric, :default => nil, :desc => "Port for 'backend' where workers connect (defaults to port + 1)"
@@ -66,70 +74,77 @@ module Protobuf
66
74
 
67
75
  # Tell protobuf how to handle the printing of deprecated field usage.
68
76
  def configure_deprecation_warnings
69
- if options.print_deprecation_warnings.nil?
70
- ::Protobuf.print_deprecation_warnings = !ENV.key?("PB_IGNORE_DEPRECATIONS")
71
- else
72
- ::Protobuf.print_deprecation_warnings = options.print_deprecation_warnings?
73
- end
77
+ ::Protobuf.print_deprecation_warnings =
78
+ if options.print_deprecation_warnings.nil?
79
+ !ENV.key?("PB_IGNORE_DEPRECATIONS")
80
+ else
81
+ options.print_deprecation_warnings?
82
+ end
74
83
  end
75
84
 
76
85
  # If we pause during request we don't need to pause in serialization
77
86
  def configure_gc
87
+ say "DEPRECATED: The gc_pause_request option is deprecated and will be removed in 4.0." if options.gc_pause_request?
88
+
78
89
  debug_say('Configuring gc')
79
90
 
80
- if defined?(JRUBY_VERSION)
81
- # GC.enable/disable are noop's on Jruby
82
- ::Protobuf.gc_pause_server_request = false
83
- else
84
- ::Protobuf.gc_pause_server_request = options.gc_pause_request?
85
- end
91
+ ::Protobuf.gc_pause_server_request =
92
+ if defined?(JRUBY_VERSION)
93
+ # GC.enable/disable are noop's on Jruby
94
+ false
95
+ else
96
+ options.gc_pause_request?
97
+ end
86
98
  end
87
99
 
88
100
  # Setup the protobuf logger.
89
101
  def configure_logger
90
102
  debug_say('Configuring logger')
91
- ::Protobuf::Logger.configure({ :file => options.log || STDOUT,
92
- :level => options.debug? ? ::Logger::DEBUG : options.level })
103
+
104
+ log_level = options.debug? ? ::Logger::DEBUG : options.level
105
+
106
+ ::Protobuf::Logging.initialize_logger(options.log, log_level)
93
107
 
94
108
  # Debug output the server options to the log file.
95
- ::Protobuf::Logger.debug { 'Debugging options:' }
96
- ::Protobuf::Logger.debug { options.inspect }
109
+ logger.debug { 'Debugging options:' }
110
+ logger.debug { options.inspect }
97
111
  end
98
112
 
99
113
  # Re-write the $0 var to have a nice process name in ps.
100
114
  def configure_process_name(app_file)
101
115
  debug_say('Configuring process name')
102
- $0 = "rpc_server --#{@runner_mode} #{options.host}:#{options.port} #{app_file}"
116
+ $0 = "rpc_server --#{mode} #{options.host}:#{options.port} #{app_file}"
103
117
  end
104
118
 
105
119
  # Configure the mode of the server and the runner class.
106
120
  def configure_runner_mode
107
121
  debug_say('Configuring runner mode')
108
-
109
- if multi_mode?
110
- say('WARNING: You have provided multiple mode options. Defaulting to socket mode.', :yellow)
111
- @runner_mode = :socket
112
- elsif options.zmq?
113
- @runner_mode = :zmq
114
- elsif options.http?
115
- @runner_mode = :http
116
- else
117
- case server_type = ENV["PB_SERVER_TYPE"]
118
- when nil, /socket/i
119
- @runner_mode = :socket
120
- when /zmq/i
121
- @runner_mode = :zmq
122
- when /http/i
123
- @runner_mode = :http
124
- else
125
- say "WARNING: You have provided incorrect option 'PB_SERVER_TYPE=#{server_type}'. Defaulting to socket mode.", :yellow
126
- @runner_mode = :socket
127
- end
128
- end
122
+ server_type = ENV["PB_SERVER_TYPE"]
123
+
124
+ self.mode = if multi_mode?
125
+ say('WARNING: You have provided multiple mode options. Defaulting to socket mode.', :yellow)
126
+ :socket
127
+ elsif options.zmq?
128
+ :zmq
129
+ elsif options.http?
130
+ :http
131
+ else
132
+ case server_type
133
+ when nil, /\Asocket[[:space:]]*\z/i
134
+ :socket
135
+ when /\Azmq[[:space:]]*\z/i
136
+ :zmq
137
+ when /http/i
138
+ :http
139
+ else
140
+ require server_type.to_s
141
+ server_type
142
+ end
143
+ end
129
144
  end
130
145
 
131
146
  # Configure signal traps.
132
- # TODO add signal handling for hot-reloading the application.
147
+ # TODO: add signal handling for hot-reloading the application.
133
148
  def configure_traps
134
149
  debug_say('Configuring traps')
135
150
 
@@ -140,7 +155,7 @@ module Protobuf
140
155
  debug_say("Registering trap for exit signal #{signal}", :blue)
141
156
 
142
157
  trap(signal) do
143
- @exit_requested = true
158
+ self.exit_requested = true
144
159
  shutdown_server
145
160
  end
146
161
  end
@@ -148,17 +163,18 @@ module Protobuf
148
163
 
149
164
  # Create the runner for the configured mode
150
165
  def create_runner
151
- debug_say("Creating #{@runner_mode} runner")
152
- @runner = case @runner_mode
153
- when :zmq
154
- create_zmq_runner
155
- when :socket
156
- create_socket_runner
157
- when :http
158
- create_http_runner
159
- else
160
- say_and_exit("Unknown runner mode: #{@runner_mode}")
161
- end
166
+ debug_say("Creating #{mode} runner")
167
+ self.runner = case mode
168
+ when :zmq
169
+ create_zmq_runner
170
+ when :socket
171
+ create_socket_runner
172
+ when :http
173
+ create_http_runner
174
+ else
175
+ say("Extension runner mode: #{mode}")
176
+ create_extension_server_runner
177
+ end
162
178
  end
163
179
 
164
180
  # Say something if we're in debug mode.
@@ -166,10 +182,6 @@ module Protobuf
166
182
  say(message, color) if options.debug?
167
183
  end
168
184
 
169
- def exit_requested?
170
- !!@exit_requested
171
- end
172
-
173
185
  # Internal helper to determine if the modes are multi-set which is not valid.
174
186
  def multi_mode?
175
187
  options.zmq? && options.socket?
@@ -184,8 +196,7 @@ module Protobuf
184
196
  end
185
197
 
186
198
  def runner_options
187
- # Symbolize keys
188
- opt = options.inject({}) { |h, (k, v)| h[k.to_sym] = v; h }
199
+ opt = options.to_hash.symbolize_keys
189
200
 
190
201
  opt[:workers_only] = (!!ENV['PB_WORKERS_ONLY']) || options.workers_only
191
202
 
@@ -193,56 +204,65 @@ module Protobuf
193
204
  end
194
205
 
195
206
  def say_and_exit(message, exception = nil)
196
- message = set_color(message, :red) if ::Protobuf::Logger.file == STDOUT
207
+ message = set_color(message, :red) if options.log == STDOUT
208
+
209
+ logger.error { message }
197
210
 
198
- ::Protobuf::Logger.error { message }
199
211
  if exception
200
212
  $stderr.puts "[#{exception.class.name}] #{exception.message}"
201
213
  $stderr.puts exception.backtrace.join("\n")
202
214
 
203
- ::Protobuf::Logger.error { "[#{exception.class.name}] #{exception.message}" }
204
- ::Protobuf::Logger.debug { exception.backtrace.join("\n") }
215
+ logger.error { "[#{exception.class.name}] #{exception.message}" }
216
+ logger.debug { exception.backtrace.join("\n") }
205
217
  end
206
218
 
207
219
  exit(1)
208
220
  end
209
221
 
222
+ def create_extension_server_runner
223
+ classified = mode.classify
224
+ extension_server_class = classified.constantize
225
+
226
+ self.runner = extension_server_class.new(runner_options)
227
+ end
228
+
210
229
  def create_socket_runner
211
230
  require 'protobuf/socket'
212
231
 
213
- @runner = ::Protobuf::Rpc::SocketRunner.new(runner_options)
232
+ self.runner = ::Protobuf::Rpc::SocketRunner.new(runner_options)
214
233
  end
215
234
 
216
235
  def create_zmq_runner
217
236
  require 'protobuf/zmq'
218
237
 
219
- @runner = ::Protobuf::Rpc::ZmqRunner.new(runner_options)
238
+ self.runner = ::Protobuf::Rpc::ZmqRunner.new(runner_options)
220
239
  end
221
240
 
222
241
  def create_http_runner
223
242
  require 'protobuf/http'
224
243
 
225
- @runner = ::Protobuf::Rpc::HttpRunner.new(runner_options)
244
+ self.runner = ::Protobuf::Rpc::HttpRunner.new(runner_options)
226
245
  end
227
246
 
228
247
  def shutdown_server
229
- ::Protobuf::Logger.info { 'RPC Server shutting down...' }
230
- @runner.try(:stop)
248
+ logger.info { 'RPC Server shutting down...' }
249
+ runner.stop
231
250
  ::Protobuf::Rpc::ServiceDirectory.instance.stop
232
- ::Protobuf::Logger.info { 'Shutdown complete' }
233
251
  end
234
252
 
235
253
  # Start the runner and log the relevant options.
236
254
  def start_server
237
255
  debug_say('Running server')
238
256
 
239
- @runner.run do
240
- ::Protobuf::Logger.info {
241
- "pid #{::Process.pid} -- #{@runner_mode} RPC Server listening at #{options.host}:#{options.port}"
242
- }
257
+ runner.run do
258
+ logger.info do
259
+ "pid #{::Process.pid} -- #{mode} RPC Server listening at #{options.host}:#{options.port}"
260
+ end
243
261
 
244
262
  ::ActiveSupport::Notifications.instrument("after_server_bind")
245
263
  end
264
+
265
+ logger.info { 'Shutdown complete' }
246
266
  end
247
267
  end
248
268
  end