protobuffy 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.travis.yml +12 -0
  4. data/.yardopts +5 -0
  5. data/CHANGES.md +261 -0
  6. data/CONTRIBUTING.md +16 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE.txt +14 -0
  9. data/README.md +58 -0
  10. data/Rakefile +61 -0
  11. data/bin/protoc-gen-ruby +17 -0
  12. data/bin/rpc_server +4 -0
  13. data/examples/bin/reverse-client-http +4 -0
  14. data/examples/bin/reverse-client-socket +4 -0
  15. data/examples/bin/reverse-client-zmq +4 -0
  16. data/examples/config.ru +6 -0
  17. data/examples/definitions/example/reverse.proto +12 -0
  18. data/examples/lib/example/reverse-client.rb +23 -0
  19. data/examples/lib/example/reverse-service.rb +9 -0
  20. data/examples/lib/example/reverse.pb.rb +36 -0
  21. data/lib/protobuf.rb +106 -0
  22. data/lib/protobuf/cli.rb +249 -0
  23. data/lib/protobuf/code_generator.rb +41 -0
  24. data/lib/protobuf/decoder.rb +74 -0
  25. data/lib/protobuf/deprecator.rb +42 -0
  26. data/lib/protobuf/descriptors.rb +3 -0
  27. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +52 -0
  28. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +249 -0
  29. data/lib/protobuf/encoder.rb +62 -0
  30. data/lib/protobuf/enum.rb +319 -0
  31. data/lib/protobuf/exceptions.rb +9 -0
  32. data/lib/protobuf/field.rb +74 -0
  33. data/lib/protobuf/field/base_field.rb +280 -0
  34. data/lib/protobuf/field/bool_field.rb +53 -0
  35. data/lib/protobuf/field/bytes_field.rb +81 -0
  36. data/lib/protobuf/field/double_field.rb +26 -0
  37. data/lib/protobuf/field/enum_field.rb +57 -0
  38. data/lib/protobuf/field/field_array.rb +86 -0
  39. data/lib/protobuf/field/fixed32_field.rb +25 -0
  40. data/lib/protobuf/field/fixed64_field.rb +29 -0
  41. data/lib/protobuf/field/float_field.rb +38 -0
  42. data/lib/protobuf/field/int32_field.rb +22 -0
  43. data/lib/protobuf/field/int64_field.rb +22 -0
  44. data/lib/protobuf/field/integer_field.rb +24 -0
  45. data/lib/protobuf/field/message_field.rb +66 -0
  46. data/lib/protobuf/field/sfixed32_field.rb +28 -0
  47. data/lib/protobuf/field/sfixed64_field.rb +29 -0
  48. data/lib/protobuf/field/signed_integer_field.rb +30 -0
  49. data/lib/protobuf/field/sint32_field.rb +22 -0
  50. data/lib/protobuf/field/sint64_field.rb +22 -0
  51. data/lib/protobuf/field/string_field.rb +35 -0
  52. data/lib/protobuf/field/uint32_field.rb +22 -0
  53. data/lib/protobuf/field/uint64_field.rb +22 -0
  54. data/lib/protobuf/field/varint_field.rb +68 -0
  55. data/lib/protobuf/generators/base.rb +71 -0
  56. data/lib/protobuf/generators/enum_generator.rb +42 -0
  57. data/lib/protobuf/generators/extension_generator.rb +28 -0
  58. data/lib/protobuf/generators/field_generator.rb +132 -0
  59. data/lib/protobuf/generators/file_generator.rb +140 -0
  60. data/lib/protobuf/generators/group_generator.rb +113 -0
  61. data/lib/protobuf/generators/message_generator.rb +99 -0
  62. data/lib/protobuf/generators/printable.rb +161 -0
  63. data/lib/protobuf/generators/service_generator.rb +27 -0
  64. data/lib/protobuf/http.rb +20 -0
  65. data/lib/protobuf/lifecycle.rb +46 -0
  66. data/lib/protobuf/logger.rb +86 -0
  67. data/lib/protobuf/message.rb +182 -0
  68. data/lib/protobuf/message/fields.rb +122 -0
  69. data/lib/protobuf/message/serialization.rb +84 -0
  70. data/lib/protobuf/optionable.rb +23 -0
  71. data/lib/protobuf/rpc/buffer.rb +79 -0
  72. data/lib/protobuf/rpc/client.rb +168 -0
  73. data/lib/protobuf/rpc/connector.rb +21 -0
  74. data/lib/protobuf/rpc/connectors/base.rb +54 -0
  75. data/lib/protobuf/rpc/connectors/common.rb +172 -0
  76. data/lib/protobuf/rpc/connectors/http.rb +90 -0
  77. data/lib/protobuf/rpc/connectors/socket.rb +73 -0
  78. data/lib/protobuf/rpc/connectors/zmq.rb +205 -0
  79. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +47 -0
  80. data/lib/protobuf/rpc/env.rb +58 -0
  81. data/lib/protobuf/rpc/error.rb +28 -0
  82. data/lib/protobuf/rpc/error/client_error.rb +31 -0
  83. data/lib/protobuf/rpc/error/server_error.rb +43 -0
  84. data/lib/protobuf/rpc/middleware.rb +25 -0
  85. data/lib/protobuf/rpc/middleware/exception_handler.rb +36 -0
  86. data/lib/protobuf/rpc/middleware/logger.rb +91 -0
  87. data/lib/protobuf/rpc/middleware/request_decoder.rb +83 -0
  88. data/lib/protobuf/rpc/middleware/response_encoder.rb +88 -0
  89. data/lib/protobuf/rpc/middleware/runner.rb +18 -0
  90. data/lib/protobuf/rpc/rpc.pb.rb +53 -0
  91. data/lib/protobuf/rpc/server.rb +39 -0
  92. data/lib/protobuf/rpc/servers/http/server.rb +101 -0
  93. data/lib/protobuf/rpc/servers/http_runner.rb +34 -0
  94. data/lib/protobuf/rpc/servers/socket/server.rb +113 -0
  95. data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
  96. data/lib/protobuf/rpc/servers/socket_runner.rb +34 -0
  97. data/lib/protobuf/rpc/servers/zmq/broker.rb +155 -0
  98. data/lib/protobuf/rpc/servers/zmq/server.rb +313 -0
  99. data/lib/protobuf/rpc/servers/zmq/util.rb +47 -0
  100. data/lib/protobuf/rpc/servers/zmq/worker.rb +105 -0
  101. data/lib/protobuf/rpc/servers/zmq_runner.rb +51 -0
  102. data/lib/protobuf/rpc/service.rb +179 -0
  103. data/lib/protobuf/rpc/service_directory.rb +245 -0
  104. data/lib/protobuf/rpc/service_dispatcher.rb +46 -0
  105. data/lib/protobuf/rpc/service_filters.rb +273 -0
  106. data/lib/protobuf/rpc/stat.rb +148 -0
  107. data/lib/protobuf/socket.rb +22 -0
  108. data/lib/protobuf/tasks.rb +1 -0
  109. data/lib/protobuf/tasks/compile.rake +61 -0
  110. data/lib/protobuf/version.rb +3 -0
  111. data/lib/protobuf/wire_type.rb +10 -0
  112. data/lib/protobuf/zmq.rb +21 -0
  113. data/proto/dynamic_discovery.proto +44 -0
  114. data/proto/google/protobuf/compiler/plugin.proto +147 -0
  115. data/proto/google/protobuf/descriptor.proto +620 -0
  116. data/proto/rpc.proto +62 -0
  117. data/protobuffy.gemspec +37 -0
  118. data/spec/benchmark/tasks.rb +113 -0
  119. data/spec/bin/protoc-gen-ruby_spec.rb +18 -0
  120. data/spec/data/data.bin +3 -0
  121. data/spec/data/types.bin +0 -0
  122. data/spec/encoding/all_types_spec.rb +91 -0
  123. data/spec/encoding/extreme_values_spec.rb +0 -0
  124. data/spec/functional/socket_server_spec.rb +59 -0
  125. data/spec/functional/zmq_server_spec.rb +103 -0
  126. data/spec/lib/protobuf/cli_spec.rb +267 -0
  127. data/spec/lib/protobuf/code_generator_spec.rb +60 -0
  128. data/spec/lib/protobuf/enum_spec.rb +239 -0
  129. data/spec/lib/protobuf/field/int32_field_spec.rb +7 -0
  130. data/spec/lib/protobuf/field/string_field_spec.rb +46 -0
  131. data/spec/lib/protobuf/field_spec.rb +194 -0
  132. data/spec/lib/protobuf/generators/base_spec.rb +87 -0
  133. data/spec/lib/protobuf/generators/enum_generator_spec.rb +68 -0
  134. data/spec/lib/protobuf/generators/extension_generator_spec.rb +43 -0
  135. data/spec/lib/protobuf/generators/field_generator_spec.rb +99 -0
  136. data/spec/lib/protobuf/generators/file_generator_spec.rb +29 -0
  137. data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
  138. data/spec/lib/protobuf/generators/service_generator_spec.rb +43 -0
  139. data/spec/lib/protobuf/lifecycle_spec.rb +89 -0
  140. data/spec/lib/protobuf/logger_spec.rb +136 -0
  141. data/spec/lib/protobuf/message_spec.rb +368 -0
  142. data/spec/lib/protobuf/optionable_spec.rb +46 -0
  143. data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
  144. data/spec/lib/protobuf/rpc/connector_spec.rb +26 -0
  145. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +50 -0
  146. data/spec/lib/protobuf/rpc/connectors/common_spec.rb +170 -0
  147. data/spec/lib/protobuf/rpc/connectors/connector_spec.rb +13 -0
  148. data/spec/lib/protobuf/rpc/connectors/http_spec.rb +61 -0
  149. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +24 -0
  150. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +129 -0
  151. data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
  152. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
  153. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
  154. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +75 -0
  155. data/spec/lib/protobuf/rpc/servers/http/server_spec.rb +104 -0
  156. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
  157. data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +41 -0
  158. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
  159. data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
  160. data/spec/lib/protobuf/rpc/service_directory_spec.rb +295 -0
  161. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +52 -0
  162. data/spec/lib/protobuf/rpc/service_filters_spec.rb +484 -0
  163. data/spec/lib/protobuf/rpc/service_spec.rb +161 -0
  164. data/spec/lib/protobuf/rpc/stat_spec.rb +151 -0
  165. data/spec/lib/protobuf_spec.rb +78 -0
  166. data/spec/spec_helper.rb +57 -0
  167. data/spec/support/all.rb +7 -0
  168. data/spec/support/packed_field.rb +22 -0
  169. data/spec/support/server.rb +94 -0
  170. data/spec/support/test/all_types.data.bin +0 -0
  171. data/spec/support/test/all_types.data.txt +119 -0
  172. data/spec/support/test/defaults.pb.rb +25 -0
  173. data/spec/support/test/defaults.proto +9 -0
  174. data/spec/support/test/enum.pb.rb +59 -0
  175. data/spec/support/test/enum.proto +34 -0
  176. data/spec/support/test/extended.pb.rb +22 -0
  177. data/spec/support/test/extended.proto +10 -0
  178. data/spec/support/test/extreme_values.data.bin +0 -0
  179. data/spec/support/test/google_unittest.pb.rb +543 -0
  180. data/spec/support/test/google_unittest.proto +713 -0
  181. data/spec/support/test/google_unittest_import.pb.rb +37 -0
  182. data/spec/support/test/google_unittest_import.proto +64 -0
  183. data/spec/support/test/google_unittest_import_public.pb.rb +8 -0
  184. data/spec/support/test/google_unittest_import_public.proto +38 -0
  185. data/spec/support/test/multi_field_extensions.pb.rb +56 -0
  186. data/spec/support/test/multi_field_extensions.proto +33 -0
  187. data/spec/support/test/resource.pb.rb +117 -0
  188. data/spec/support/test/resource.proto +94 -0
  189. data/spec/support/test/resource_service.rb +26 -0
  190. data/spec/support/test_app_file.rb +2 -0
  191. data/spec/support/tolerance_matcher.rb +40 -0
  192. metadata +367 -0
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Before requiring protobuf, ensure that we will not load any
4
+ # server or client code.
5
+ #
6
+ ENV['PB_NO_NETWORKING'] = '1'
7
+
8
+ $LOAD_PATH << ::File.expand_path("../../lib", __FILE__)
9
+ require 'protobuf'
10
+ require 'protobuf/descriptors'
11
+ require 'protobuf/code_generator'
12
+
13
+ request_bytes = STDIN.read
14
+ code_generator = ::Protobuf::CodeGenerator.new(request_bytes)
15
+ response_bytes = code_generator.response_bytes
16
+ STDOUT.print(response_bytes)
17
+
data/bin/rpc_server ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'protobuf/cli'
4
+ ::Protobuf::CLI.start(ARGV)
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "protobuf/http"
4
+ require_relative "../lib/example/reverse-client.rb"
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "protobuf/socket"
4
+ require_relative "../lib/example/reverse-client.rb"
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "protobuf/zmq"
4
+ require_relative "../lib/example/reverse-client.rb"
@@ -0,0 +1,6 @@
1
+ require "protobuf"
2
+ require "protobuf/rpc/servers/http/server"
3
+
4
+ require_relative "lib/example/reverse-service"
5
+
6
+ run Protobuf::Rpc::Http::Server.new
@@ -0,0 +1,12 @@
1
+ // definitions/example/reverse.proto
2
+ package example;
3
+
4
+ message ReverseRequest {
5
+ required string input = 1;
6
+ }
7
+ message ReverseResponse {
8
+ required string reversed = 1;
9
+ }
10
+ service ReverseService {
11
+ rpc Reverse (ReverseRequest) returns (ReverseResponse);
12
+ }
@@ -0,0 +1,23 @@
1
+ require "protobuf"
2
+
3
+ require_relative "reverse.pb.rb"
4
+
5
+ # Protobuf::Logger.configure :level => Protobuf::Logger::DEBUG, :file => "./log/protobuf-client.log"
6
+
7
+ configuration = {
8
+ :host => "localhost",
9
+ :port => 9399
10
+ }
11
+
12
+ request = {
13
+ :input => (ARGV[0] or 'hello world')
14
+ }
15
+
16
+ Example::ReverseService.client(configuration).reverse(Example::ReverseRequest.new(request)) do |client|
17
+ client.on_success do |response|
18
+ puts response.reversed
19
+ end
20
+ client.on_failure do |error|
21
+ puts 'It failed: ' + error.message
22
+ end
23
+ end
@@ -0,0 +1,9 @@
1
+ require_relative "reverse.pb.rb"
2
+
3
+ module Example
4
+ class ReverseService
5
+ def reverse
6
+ respond_with :reversed => request.input.reverse
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,36 @@
1
+ ##
2
+ # This file is auto-generated. DO NOT EDIT!
3
+ #
4
+ require 'protobuf/message'
5
+ require 'protobuf/rpc/service'
6
+
7
+ module Example
8
+
9
+ ##
10
+ # Message Classes
11
+ #
12
+ class ReverseRequest < ::Protobuf::Message; end
13
+ class ReverseResponse < ::Protobuf::Message; end
14
+
15
+
16
+ ##
17
+ # Message Fields
18
+ #
19
+ class ReverseRequest
20
+ required :string, :input, 1
21
+ end
22
+
23
+ class ReverseResponse
24
+ required :string, :reversed, 1
25
+ end
26
+
27
+
28
+ ##
29
+ # Service Classes
30
+ #
31
+ class ReverseService < ::Protobuf::Rpc::Service
32
+ rpc :reverse, ::Example::ReverseRequest, ::Example::ReverseResponse
33
+ end
34
+
35
+ end
36
+
data/lib/protobuf.rb ADDED
@@ -0,0 +1,106 @@
1
+ require 'logger'
2
+ require 'socket'
3
+ require 'pp'
4
+ require 'stringio'
5
+
6
+ require 'active_support/core_ext/object/blank'
7
+ require 'active_support/core_ext/object/try'
8
+ require 'active_support/notifications'
9
+ require 'active_support/inflector'
10
+ require 'active_support/json'
11
+
12
+ module Protobuf
13
+
14
+ # See Protobuf#connector_type documentation.
15
+ CONNECTORS = [ :socket, :zmq, :http ].freeze
16
+
17
+ # Default is Socket as it has no external dependencies.
18
+ DEFAULT_CONNECTOR = :socket
19
+
20
+ module_function
21
+
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
29
+ end
30
+
31
+ def self.client_host=(host)
32
+ @_client_host = host
33
+ end
34
+
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
43
+ end
44
+
45
+ def self.connector_type=(type)
46
+ raise ArgumentError, 'Invalid connector type given' unless CONNECTORS.include?(type)
47
+ @_connector_type = type
48
+ end
49
+
50
+ # GC Pause during server requests
51
+ #
52
+ # Default: false
53
+ #
54
+ # Boolean value to tell the server to disable
55
+ # the Garbage Collector when handling an rpc request.
56
+ # Once the request is completed, the GC is enabled again.
57
+ # This optomization provides a huge boost in speed to rpc requests.
58
+ def self.gc_pause_server_request?
59
+ return @_gc_pause_server_request unless @_gc_pause_server_request.nil?
60
+ self.gc_pause_server_request = false
61
+ end
62
+
63
+ def self.gc_pause_server_request=(value)
64
+ @_gc_pause_server_request = !!value
65
+ end
66
+
67
+ # Print Deprecation Warnings
68
+ #
69
+ # Default: true
70
+ #
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
80
+ end
81
+
82
+ def self.print_deprecation_warnings=(value)
83
+ @_print_deprecation_warnings = !!value
84
+ end
85
+
86
+ end
87
+
88
+ unless ENV.key?('PB_NO_NETWORKING')
89
+ require 'protobuf/rpc/client'
90
+ require 'protobuf/rpc/service'
91
+
92
+ env_connector_type = ENV.fetch('PB_CLIENT_TYPE') {
93
+ ::Protobuf::DEFAULT_CONNECTOR
94
+ }.to_s.downcase.strip.to_sym
95
+
96
+ if ::Protobuf::CONNECTORS.include?(env_connector_type)
97
+ require "protobuf/#{env_connector_type}"
98
+ 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}"
105
+ end
106
+ end
@@ -0,0 +1,249 @@
1
+ require 'thor'
2
+ require 'protobuf/version'
3
+ require 'protobuf/logger'
4
+ require 'protobuf/rpc/servers/socket_runner'
5
+ require 'protobuf/rpc/servers/zmq_runner'
6
+ require 'protobuf/rpc/servers/http_runner'
7
+
8
+ module Protobuf
9
+ class CLI < ::Thor
10
+ include ::Thor::Actions
11
+
12
+ attr_accessor :runner, :mode
13
+
14
+ default_task :start
15
+
16
+ desc 'start APP_FILE', 'Run the RPC server in the given mode, preloading the given APP_FILE. This is the default task.'
17
+
18
+ option :host, :type => :string, :default => '127.0.0.1', :aliases => %w(-o), :desc => 'Host to bind.'
19
+ option :port, :type => :numeric, :default => 9399, :aliases => %w(-p), :desc => 'Master Port to bind.'
20
+
21
+ option :backlog, :type => :numeric, :default => 100, :aliases => %w(-b), :desc => 'Backlog for listening socket when using Socket Server.'
22
+ option :threshold, :type => :numeric, :default => 100, :aliases => %w(-t), :desc => 'Multi-threaded Socket Server cleanup threshold.'
23
+ option :threads, :type => :numeric, :default => 5, :aliases => %w(-r), :desc => 'Number of worker threads to run. Only applicable in --zmq mode.'
24
+
25
+ option :log, :type => :string, :aliases => %w(-l), :desc => 'Log file or device. Default is STDOUT.'
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/)'
27
+
28
+ option :socket, :type => :boolean, :aliases => %w(-s), :desc => 'Socket Mode for server and client connections.'
29
+ option :zmq, :type => :boolean, :aliases => %w(-z), :desc => 'ZeroMQ Socket Mode for server and client connections.'
30
+ option :http, :type => :boolean, :aliases => %w(), :desc => 'HTTP Server Mode for server and client connections.'
31
+
32
+ option :beacon_interval, :type => :numeric, :desc => 'Broadcast beacons every N seconds. (default: 5)'
33
+ option :beacon_port, :type => :numeric, :desc => 'Broadcast beacons to this port (default: value of ServiceDirectory.port)'
34
+ option :broadcast_beacons, :type => :boolean, :desc => 'Broadcast beacons for dynamic discovery (Currently only available with ZeroMQ).'
35
+ option :broadcast_busy, :type => :boolean, :default => false, :desc => 'Remove busy nodes from cluster when all workers are busy (Currently only available with ZeroMQ).'
36
+ 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.'
38
+ option :print_deprecation_warnings, :type => :boolean, :default => nil, :desc => 'Cause use of deprecated fields to be printed or ignored.'
39
+ option :workers_only, :type => :boolean, :default => false, :desc => "Starts process with only workers (no broker/frontend is started) only relevant for Zmq Server"
40
+ option :worker_port, :type => :numeric, :default => nil, :desc => "Port for 'backend' where workers connect (defaults to port + 1)"
41
+ option :zmq_inproc, :type => :boolean, :default => true, :desc => 'Use inproc protocol for zmq Server/Broker/Worker'
42
+
43
+ def start(app_file)
44
+ debug_say('Configuring the rpc_server process')
45
+
46
+ configure_logger
47
+ configure_traps
48
+ configure_runner_mode
49
+ create_runner
50
+ configure_process_name(app_file)
51
+ configure_gc
52
+ configure_deprecation_warnings
53
+
54
+ require_application(app_file) unless exit_requested?
55
+ start_server unless exit_requested?
56
+ rescue => e
57
+ say_and_exit('ERROR: RPC Server failed to start.', e)
58
+ end
59
+
60
+ desc 'version', 'Print ruby and protoc versions and exit.'
61
+ def version
62
+ say("Ruby Protobuf v#{::Protobuf::VERSION}")
63
+ end
64
+
65
+ no_tasks do
66
+
67
+ # Tell protobuf how to handle the printing of deprecated field usage.
68
+ 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
74
+ end
75
+
76
+ # If we pause during request we don't need to pause in serialization
77
+ def configure_gc
78
+ debug_say('Configuring gc')
79
+
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
86
+ end
87
+
88
+ # Setup the protobuf logger.
89
+ def configure_logger
90
+ debug_say('Configuring logger')
91
+ ::Protobuf::Logger.configure({ :file => options.log || STDOUT,
92
+ :level => options.debug? ? ::Logger::DEBUG : options.level })
93
+
94
+ # Debug output the server options to the log file.
95
+ ::Protobuf::Logger.debug { 'Debugging options:' }
96
+ ::Protobuf::Logger.debug { options.inspect }
97
+ end
98
+
99
+ # Re-write the $0 var to have a nice process name in ps.
100
+ def configure_process_name(app_file)
101
+ debug_say('Configuring process name')
102
+ $0 = "rpc_server --#{@runner_mode} #{options.host}:#{options.port} #{app_file}"
103
+ end
104
+
105
+ # Configure the mode of the server and the runner class.
106
+ def configure_runner_mode
107
+ 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
129
+ end
130
+
131
+ # Configure signal traps.
132
+ # TODO add signal handling for hot-reloading the application.
133
+ def configure_traps
134
+ debug_say('Configuring traps')
135
+
136
+ exit_signals = [:INT, :TERM]
137
+ exit_signals << :QUIT unless defined?(JRUBY_VERSION)
138
+
139
+ exit_signals.each do |signal|
140
+ debug_say("Registering trap for exit signal #{signal}", :blue)
141
+
142
+ trap(signal) do
143
+ @exit_requested = true
144
+ shutdown_server
145
+ end
146
+ end
147
+ end
148
+
149
+ # Create the runner for the configured mode
150
+ 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
162
+ end
163
+
164
+ # Say something if we're in debug mode.
165
+ def debug_say(message, color = :yellow)
166
+ say(message, color) if options.debug?
167
+ end
168
+
169
+ def exit_requested?
170
+ !!@exit_requested
171
+ end
172
+
173
+ # Internal helper to determine if the modes are multi-set which is not valid.
174
+ def multi_mode?
175
+ options.zmq? && options.socket?
176
+ end
177
+
178
+ # Require the application file given, exiting if the file doesn't exist.
179
+ def require_application(app_file)
180
+ debug_say('Requiring app file')
181
+ require app_file
182
+ rescue LoadError => e
183
+ say_and_exit("Failed to load application file #{app_file}", e)
184
+ end
185
+
186
+ def runner_options
187
+ # Symbolize keys
188
+ opt = options.inject({}) { |h, (k, v)| h[k.to_sym] = v; h }
189
+
190
+ opt[:workers_only] = (!!ENV['PB_WORKERS_ONLY']) || options.workers_only
191
+
192
+ opt
193
+ end
194
+
195
+ def say_and_exit(message, exception = nil)
196
+ message = set_color(message, :red) if ::Protobuf::Logger.file == STDOUT
197
+
198
+ ::Protobuf::Logger.error { message }
199
+ if exception
200
+ $stderr.puts "[#{exception.class.name}] #{exception.message}"
201
+ $stderr.puts exception.backtrace.join("\n")
202
+
203
+ ::Protobuf::Logger.error { "[#{exception.class.name}] #{exception.message}" }
204
+ ::Protobuf::Logger.debug { exception.backtrace.join("\n") }
205
+ end
206
+
207
+ exit(1)
208
+ end
209
+
210
+ def create_socket_runner
211
+ require 'protobuf/socket'
212
+
213
+ @runner = ::Protobuf::Rpc::SocketRunner.new(runner_options)
214
+ end
215
+
216
+ def create_zmq_runner
217
+ require 'protobuf/zmq'
218
+
219
+ @runner = ::Protobuf::Rpc::ZmqRunner.new(runner_options)
220
+ end
221
+
222
+ def create_http_runner
223
+ require 'protobuf/http'
224
+
225
+ @runner = ::Protobuf::Rpc::HttpRunner.new(runner_options)
226
+ end
227
+
228
+ def shutdown_server
229
+ ::Protobuf::Logger.info { 'RPC Server shutting down...' }
230
+ @runner.try(:stop)
231
+ ::Protobuf::Rpc::ServiceDirectory.instance.stop
232
+ ::Protobuf::Logger.info { 'Shutdown complete' }
233
+ end
234
+
235
+ # Start the runner and log the relevant options.
236
+ def start_server
237
+ debug_say('Running server')
238
+
239
+ @runner.run do
240
+ ::Protobuf::Logger.info {
241
+ "pid #{::Process.pid} -- #{@runner_mode} RPC Server listening at #{options.host}:#{options.port}"
242
+ }
243
+
244
+ ::ActiveSupport::Notifications.instrument("after_server_bind")
245
+ end
246
+ end
247
+ end
248
+ end
249
+ end