prepor-protobuf 3.5.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 (182) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rubocop.yml +51 -0
  4. data/.rubocop_todo.yml +89 -0
  5. data/.travis.yml +25 -0
  6. data/.yardopts +5 -0
  7. data/CHANGES.md +256 -0
  8. data/CONTRIBUTING.md +16 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE.txt +22 -0
  11. data/README.md +33 -0
  12. data/Rakefile +64 -0
  13. data/bin/protoc-gen-ruby +16 -0
  14. data/bin/rpc_server +5 -0
  15. data/install-protobuf.sh +28 -0
  16. data/lib/protobuf.rb +100 -0
  17. data/lib/protobuf/cli.rb +242 -0
  18. data/lib/protobuf/code_generator.rb +44 -0
  19. data/lib/protobuf/decoder.rb +73 -0
  20. data/lib/protobuf/deprecation.rb +112 -0
  21. data/lib/protobuf/descriptors.rb +3 -0
  22. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +48 -0
  23. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +251 -0
  24. data/lib/protobuf/encoder.rb +67 -0
  25. data/lib/protobuf/enum.rb +303 -0
  26. data/lib/protobuf/exceptions.rb +9 -0
  27. data/lib/protobuf/field.rb +74 -0
  28. data/lib/protobuf/field/base_field.rb +267 -0
  29. data/lib/protobuf/field/bool_field.rb +59 -0
  30. data/lib/protobuf/field/bytes_field.rb +82 -0
  31. data/lib/protobuf/field/double_field.rb +25 -0
  32. data/lib/protobuf/field/enum_field.rb +68 -0
  33. data/lib/protobuf/field/field_array.rb +87 -0
  34. data/lib/protobuf/field/fixed32_field.rb +25 -0
  35. data/lib/protobuf/field/fixed64_field.rb +28 -0
  36. data/lib/protobuf/field/float_field.rb +41 -0
  37. data/lib/protobuf/field/int32_field.rb +21 -0
  38. data/lib/protobuf/field/int64_field.rb +21 -0
  39. data/lib/protobuf/field/integer_field.rb +23 -0
  40. data/lib/protobuf/field/message_field.rb +65 -0
  41. data/lib/protobuf/field/sfixed32_field.rb +27 -0
  42. data/lib/protobuf/field/sfixed64_field.rb +28 -0
  43. data/lib/protobuf/field/signed_integer_field.rb +29 -0
  44. data/lib/protobuf/field/sint32_field.rb +21 -0
  45. data/lib/protobuf/field/sint64_field.rb +21 -0
  46. data/lib/protobuf/field/string_field.rb +34 -0
  47. data/lib/protobuf/field/uint32_field.rb +21 -0
  48. data/lib/protobuf/field/uint64_field.rb +21 -0
  49. data/lib/protobuf/field/varint_field.rb +73 -0
  50. data/lib/protobuf/generators/base.rb +70 -0
  51. data/lib/protobuf/generators/enum_generator.rb +41 -0
  52. data/lib/protobuf/generators/extension_generator.rb +27 -0
  53. data/lib/protobuf/generators/field_generator.rb +131 -0
  54. data/lib/protobuf/generators/file_generator.rb +135 -0
  55. data/lib/protobuf/generators/group_generator.rb +112 -0
  56. data/lib/protobuf/generators/message_generator.rb +98 -0
  57. data/lib/protobuf/generators/printable.rb +160 -0
  58. data/lib/protobuf/generators/service_generator.rb +26 -0
  59. data/lib/protobuf/lifecycle.rb +33 -0
  60. data/lib/protobuf/logging.rb +39 -0
  61. data/lib/protobuf/message.rb +193 -0
  62. data/lib/protobuf/message/fields.rb +133 -0
  63. data/lib/protobuf/message/serialization.rb +89 -0
  64. data/lib/protobuf/optionable.rb +23 -0
  65. data/lib/protobuf/rpc/buffer.rb +77 -0
  66. data/lib/protobuf/rpc/client.rb +168 -0
  67. data/lib/protobuf/rpc/connector.rb +19 -0
  68. data/lib/protobuf/rpc/connectors/base.rb +55 -0
  69. data/lib/protobuf/rpc/connectors/common.rb +176 -0
  70. data/lib/protobuf/rpc/connectors/socket.rb +73 -0
  71. data/lib/protobuf/rpc/connectors/zmq.rb +322 -0
  72. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +49 -0
  73. data/lib/protobuf/rpc/env.rb +58 -0
  74. data/lib/protobuf/rpc/error.rb +28 -0
  75. data/lib/protobuf/rpc/error/client_error.rb +31 -0
  76. data/lib/protobuf/rpc/error/server_error.rb +43 -0
  77. data/lib/protobuf/rpc/middleware.rb +25 -0
  78. data/lib/protobuf/rpc/middleware/exception_handler.rb +36 -0
  79. data/lib/protobuf/rpc/middleware/logger.rb +91 -0
  80. data/lib/protobuf/rpc/middleware/request_decoder.rb +83 -0
  81. data/lib/protobuf/rpc/middleware/response_encoder.rb +88 -0
  82. data/lib/protobuf/rpc/middleware/runner.rb +18 -0
  83. data/lib/protobuf/rpc/rpc.pb.rb +55 -0
  84. data/lib/protobuf/rpc/server.rb +39 -0
  85. data/lib/protobuf/rpc/servers/socket/server.rb +123 -0
  86. data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
  87. data/lib/protobuf/rpc/servers/socket_runner.rb +40 -0
  88. data/lib/protobuf/rpc/servers/zmq/broker.rb +193 -0
  89. data/lib/protobuf/rpc/servers/zmq/server.rb +320 -0
  90. data/lib/protobuf/rpc/servers/zmq/util.rb +48 -0
  91. data/lib/protobuf/rpc/servers/zmq/worker.rb +104 -0
  92. data/lib/protobuf/rpc/servers/zmq_runner.rb +62 -0
  93. data/lib/protobuf/rpc/service.rb +179 -0
  94. data/lib/protobuf/rpc/service_directory.rb +253 -0
  95. data/lib/protobuf/rpc/service_dispatcher.rb +46 -0
  96. data/lib/protobuf/rpc/service_filters.rb +272 -0
  97. data/lib/protobuf/rpc/stat.rb +97 -0
  98. data/lib/protobuf/socket.rb +21 -0
  99. data/lib/protobuf/tasks.rb +1 -0
  100. data/lib/protobuf/tasks/compile.rake +61 -0
  101. data/lib/protobuf/version.rb +3 -0
  102. data/lib/protobuf/wire_type.rb +10 -0
  103. data/lib/protobuf/zmq.rb +21 -0
  104. data/proto/dynamic_discovery.proto +44 -0
  105. data/proto/google/protobuf/compiler/plugin.proto +147 -0
  106. data/proto/google/protobuf/descriptor.proto +620 -0
  107. data/proto/rpc.proto +62 -0
  108. data/protobuf.gemspec +51 -0
  109. data/spec/benchmark/tasks.rb +139 -0
  110. data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
  111. data/spec/data/data.bin +3 -0
  112. data/spec/data/types.bin +0 -0
  113. data/spec/encoding/all_types_spec.rb +105 -0
  114. data/spec/encoding/extreme_values_spec.rb +0 -0
  115. data/spec/functional/class_inheritance_spec.rb +52 -0
  116. data/spec/functional/socket_server_spec.rb +59 -0
  117. data/spec/functional/zmq_server_spec.rb +105 -0
  118. data/spec/lib/protobuf/cli_spec.rb +273 -0
  119. data/spec/lib/protobuf/code_generator_spec.rb +60 -0
  120. data/spec/lib/protobuf/enum_spec.rb +265 -0
  121. data/spec/lib/protobuf/field/bool_field_spec.rb +51 -0
  122. data/spec/lib/protobuf/field/field_array_spec.rb +69 -0
  123. data/spec/lib/protobuf/field/float_field_spec.rb +55 -0
  124. data/spec/lib/protobuf/field/int32_field_spec.rb +89 -0
  125. data/spec/lib/protobuf/field/string_field_spec.rb +45 -0
  126. data/spec/lib/protobuf/field_spec.rb +191 -0
  127. data/spec/lib/protobuf/generators/base_spec.rb +84 -0
  128. data/spec/lib/protobuf/generators/enum_generator_spec.rb +73 -0
  129. data/spec/lib/protobuf/generators/extension_generator_spec.rb +42 -0
  130. data/spec/lib/protobuf/generators/field_generator_spec.rb +102 -0
  131. data/spec/lib/protobuf/generators/file_generator_spec.rb +32 -0
  132. data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
  133. data/spec/lib/protobuf/generators/service_generator_spec.rb +46 -0
  134. data/spec/lib/protobuf/lifecycle_spec.rb +94 -0
  135. data/spec/lib/protobuf/message_spec.rb +526 -0
  136. data/spec/lib/protobuf/optionable_spec.rb +46 -0
  137. data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
  138. data/spec/lib/protobuf/rpc/connector_spec.rb +26 -0
  139. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +50 -0
  140. data/spec/lib/protobuf/rpc/connectors/common_spec.rb +170 -0
  141. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +36 -0
  142. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +117 -0
  143. data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
  144. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
  145. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
  146. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +75 -0
  147. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
  148. data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +43 -0
  149. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
  150. data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
  151. data/spec/lib/protobuf/rpc/service_directory_spec.rb +293 -0
  152. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +52 -0
  153. data/spec/lib/protobuf/rpc/service_filters_spec.rb +517 -0
  154. data/spec/lib/protobuf/rpc/service_spec.rb +162 -0
  155. data/spec/lib/protobuf/rpc/stat_spec.rb +68 -0
  156. data/spec/lib/protobuf_spec.rb +98 -0
  157. data/spec/spec_helper.rb +44 -0
  158. data/spec/support/all.rb +6 -0
  159. data/spec/support/packed_field.rb +22 -0
  160. data/spec/support/server.rb +64 -0
  161. data/spec/support/test/all_types.data.bin +0 -0
  162. data/spec/support/test/all_types.data.txt +119 -0
  163. data/spec/support/test/defaults.pb.rb +27 -0
  164. data/spec/support/test/defaults.proto +9 -0
  165. data/spec/support/test/enum.pb.rb +55 -0
  166. data/spec/support/test/enum.proto +34 -0
  167. data/spec/support/test/extended.pb.rb +18 -0
  168. data/spec/support/test/extended.proto +10 -0
  169. data/spec/support/test/extreme_values.data.bin +0 -0
  170. data/spec/support/test/google_unittest.pb.rb +537 -0
  171. data/spec/support/test/google_unittest.proto +713 -0
  172. data/spec/support/test/google_unittest_import.pb.rb +39 -0
  173. data/spec/support/test/google_unittest_import.proto +64 -0
  174. data/spec/support/test/google_unittest_import_public.pb.rb +10 -0
  175. data/spec/support/test/google_unittest_import_public.proto +38 -0
  176. data/spec/support/test/multi_field_extensions.pb.rb +58 -0
  177. data/spec/support/test/multi_field_extensions.proto +33 -0
  178. data/spec/support/test/resource.pb.rb +119 -0
  179. data/spec/support/test/resource.proto +94 -0
  180. data/spec/support/test/resource_service.rb +23 -0
  181. data/spec/support/test_app_file.rb +2 -0
  182. metadata +502 -0
@@ -0,0 +1,16 @@
1
+ # Contributing
2
+
3
+ I love accepting issues and pull requests. I only ask for a few guidelines to
4
+ be followed that will make it much easier for me to solve your issue or get
5
+ your code merged.
6
+
7
+ 1. Use GitHub Issues or Pull Requests over sending an email. It's much easier for me to keep track of your issue through GitHub.
8
+ 2. For __compiler issues__, please provide both a gist for the __source definition(s)__ as well as the __generated output__ (if any).
9
+ 3. For __existing issues or functionality__, please use __`2-8-stable`__ as the base branch for the pull request. This helps us maintain a stable gem release strategy. All commits merged to `2-8-stable` will also be merged down to `master`.
10
+ 4. For __new functionality__, please use __`master`__ as the base branch for the pull request. The `master` branch is used to stage all "next iteration" work.
11
+ 5. Be patient with me as I work on your issue.
12
+
13
+ Following these simple guidelines really will help me help you. And really,
14
+ that's what we're here for. I'm on @localshred on twitter, let's be friends. :)
15
+
16
+ ## Happy Contributing!
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 BJ Neilsen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
22
+
@@ -0,0 +1,33 @@
1
+ # protobuf
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/protobuf.svg)](http://badge.fury.io/rb/protobuf)
4
+ [![Build Status](https://secure.travis-ci.org/localshred/protobuf.svg?branch=master)](https://travis-ci.org/localshred/protobuf)
5
+ [![Gitter chat](https://badges.gitter.im/localshred/protobuf.svg)](https://gitter.im/localshred/protobuf)
6
+ [![protobuf API Documentation](https://www.omniref.com/ruby/gems/protobuf.png)](https://www.omniref.com/ruby/gems/protobuf)
7
+
8
+ Protobuf is an implementation of [Google's protocol buffers][google-pb] in ruby, version 2.5.0 is currently supported.
9
+
10
+ ## Install
11
+
12
+ See our [Installation Guide][] on the [wiki][].
13
+
14
+ ## Usage
15
+
16
+ The [wiki][] contains in-depth guides on the various ways to use this gem
17
+ including [compiling definitions][], [object APIs][], [services][], [clients][], and even
18
+ an [API roadmap][].
19
+
20
+ ## Changelog
21
+
22
+ See recent changes in the [release notes][] or the [changelog][].
23
+
24
+ [google-pb]: http://code.google.com/p/protobuf "Google Protocol Buffers"
25
+ [wiki]: https://github.com/localshred/protobuf/wiki "Wiki home page"
26
+ [Installation Guide]: https://github.com/localshred/protobuf/wiki/Installation "Installation guide"
27
+ [compiling definitions]: https://github.com/localshred/protobuf/wiki/Compiling-Definitions "Compiling guide"
28
+ [object APIs]: https://github.com/localshred/protobuf/wiki/Messages-&-Enums "Message & Enum object APIs guide"
29
+ [services]: https://github.com/localshred/protobuf/wiki/Services "Services object API guide"
30
+ [clients]: https://github.com/localshred/protobuf/wiki/Clients "Client object API guide"
31
+ [API roadmap]: https://github.com/localshred/protobuf/wiki/API-Roadmap "API Roadmap guide"
32
+ [release notes]: https://github.com/localshred/protobuf/releases "Release notes"
33
+ [changelog]: https://github.com/localshred/protobuf/blob/master/CHANGES.md "CHANGES.md"
@@ -0,0 +1,64 @@
1
+ $LOAD_PATH << ::File.expand_path('../', __FILE__)
2
+ $LOAD_PATH << ::File.expand_path('../spec', __FILE__)
3
+
4
+ require 'fileutils'
5
+ require 'rubygems'
6
+ require 'rubygems/package_task'
7
+ require 'bundler/gem_tasks'
8
+ require 'benchmark/tasks'
9
+
10
+ require 'rspec/core/rake_task'
11
+ require 'rubocop/rake_task'
12
+
13
+ RSpec::Core::RakeTask.new(:spec)
14
+ RuboCop::RakeTask.new
15
+
16
+ task :default => ['compile:spec', 'compile:rpc', :spec, :rubocop]
17
+
18
+ desc 'Run specs'
19
+ namespace :compile do
20
+
21
+ desc 'Compile spec protos in spec/supprt/ directory'
22
+ task :spec do
23
+ proto_path = ::File.expand_path('../spec/support/', __FILE__)
24
+ proto_files = Dir[File.join(proto_path, '**', '*.proto')]
25
+ cmd = %(protoc --plugin=./bin/protoc-gen-ruby --ruby_out=#{proto_path} -I #{proto_path} #{proto_files.join(' ')})
26
+
27
+ puts cmd
28
+ system(cmd)
29
+ end
30
+
31
+ desc 'Compile rpc protos in protos/ directory'
32
+ task :rpc do
33
+ proto_path = ::File.expand_path('../proto', __FILE__)
34
+ proto_files = Dir[File.join(proto_path, '**', '*.proto')]
35
+ output_dir = ::File.expand_path('../tmp/rpc', __FILE__)
36
+ ::FileUtils.mkdir_p(output_dir)
37
+
38
+ cmd = %(protoc --plugin=./bin/protoc-gen-ruby --ruby_out=#{output_dir} -I #{proto_path} #{proto_files.join(' ')})
39
+
40
+ puts cmd
41
+ system(cmd)
42
+
43
+ files = {
44
+ 'tmp/rpc/dynamic_discovery.pb.rb' => 'lib/protobuf/rpc',
45
+ 'tmp/rpc/rpc.pb.rb' => 'lib/protobuf/rpc',
46
+ 'tmp/rpc/google/protobuf/descriptor.pb.rb' => 'lib/protobuf/descriptors/google/protobuf',
47
+ 'tmp/rpc/google/protobuf/compiler/plugin.pb.rb' => 'lib/protobuf/descriptors/google/protobuf/compiler',
48
+ }
49
+
50
+ files.each_pair do |source_file, destination_dir|
51
+ source_file = ::File.expand_path("../#{source_file}", __FILE__)
52
+ destination_dir = ::File.expand_path("../#{destination_dir}", __FILE__)
53
+ ::FileUtils::Verbose.cp(source_file, destination_dir)
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ task :console do
60
+ require 'pry'
61
+ require 'protobuf'
62
+ ARGV.clear
63
+ ::Pry.start
64
+ end
@@ -0,0 +1,16 @@
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)
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'protobuf/cli'
4
+ ::Protobuf::CLI.start(ARGV)
5
+ exit
@@ -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
@@ -0,0 +1,100 @@
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/inflector'
9
+ require 'active_support/json'
10
+ require 'active_support/notifications'
11
+
12
+ require 'protobuf/deprecation'
13
+
14
+ module Protobuf
15
+
16
+ # See Protobuf#connector_type documentation.
17
+ CONNECTORS = [:socket, :zmq].freeze
18
+
19
+ # Default is Socket as it has no external dependencies.
20
+ DEFAULT_CONNECTOR = :socket
21
+
22
+ module_function
23
+
24
+ class << self
25
+ # Client Host
26
+ #
27
+ # Default: `hostname` of the system
28
+ #
29
+ # The name or address of the host to use during client RPC calls.
30
+ attr_accessor :client_host
31
+ end
32
+
33
+ self.client_host = Socket.gethostname
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
+ fail 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
+ # Permit unknown field on Message initialization
68
+ #
69
+ # Default: true
70
+ #
71
+ # Simple boolean to define whether we want to permit unknown fields
72
+ # on Message intialization; otherwise a ::Protobuf::FieldNotDefinedError is thrown.
73
+ def self.ignore_unknown_fields?
74
+ !defined?(@ignore_unknown_fields) || @ignore_unknown_fields
75
+ end
76
+
77
+ def self.ignore_unknown_fields=(value)
78
+ @ignore_unknown_fields = !!value
79
+ end
80
+ end
81
+
82
+ unless ENV.key?('PB_NO_NETWORKING')
83
+ require 'protobuf/rpc/client'
84
+ require 'protobuf/rpc/service'
85
+
86
+ env_connector_type = ENV.fetch('PB_CLIENT_TYPE') do
87
+ ::Protobuf::DEFAULT_CONNECTOR
88
+ end.to_s.downcase.strip.to_sym
89
+
90
+ if ::Protobuf::CONNECTORS.include?(env_connector_type)
91
+ require "protobuf/#{env_connector_type}"
92
+ else
93
+ $stderr.puts <<-WARN
94
+ [WARNING] Require attempted on an invalid connector type '#{env_connector_type}'.
95
+ Falling back to default '#{::Protobuf::DEFAULT_CONNECTOR}' connector.
96
+ WARN
97
+
98
+ require "protobuf/#{::Protobuf::DEFAULT_CONNECTOR}"
99
+ end
100
+ end
@@ -0,0 +1,242 @@
1
+ require 'active_support/core_ext/hash/keys'
2
+
3
+ require 'thor'
4
+ require 'protobuf/version'
5
+ require 'protobuf/logging'
6
+ require 'protobuf/rpc/servers/socket_runner'
7
+ require 'protobuf/rpc/servers/zmq_runner'
8
+
9
+ module Protobuf
10
+ class CLI < ::Thor
11
+ include ::Thor::Actions
12
+ include ::Protobuf::Logging
13
+
14
+ attr_accessor :runner, :mode, :exit_requested
15
+
16
+ no_commands do
17
+ alias_method :exit_requested?, :exit_requested
18
+ end
19
+
20
+ default_task :start
21
+
22
+ desc 'start APP_FILE', 'Run the RPC server in the given mode, preloading the given APP_FILE. This is the default task.'
23
+
24
+ option :host, :type => :string, :default => '127.0.0.1', :aliases => %w(-o), :desc => 'Host to bind.'
25
+ option :port, :type => :numeric, :default => 9399, :aliases => %w(-p), :desc => 'Master Port to bind.'
26
+
27
+ option :backlog, :type => :numeric, :default => 100, :aliases => %w(-b), :desc => 'Backlog for listening socket when using Socket Server.'
28
+ option :threshold, :type => :numeric, :default => 100, :aliases => %w(-t), :desc => 'Multi-threaded Socket Server cleanup threshold.'
29
+ option :threads, :type => :numeric, :default => 5, :aliases => %w(-r), :desc => 'Number of worker threads to run. Only applicable in --zmq mode.'
30
+
31
+ option :log, :type => :string, :default => STDOUT, :aliases => %w(-l), :desc => 'Log file or device. Default is STDOUT.'
32
+ 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/)'
33
+
34
+ option :socket, :type => :boolean, :aliases => %w(-s), :desc => 'Socket Mode for server and client connections.'
35
+ option :zmq, :type => :boolean, :aliases => %w(-z), :desc => 'ZeroMQ Socket Mode for server and client connections.'
36
+
37
+ option :beacon_interval, :type => :numeric, :desc => 'Broadcast beacons every N seconds. (default: 5)'
38
+ option :beacon_port, :type => :numeric, :desc => 'Broadcast beacons to this port (default: value of ServiceDirectory.port)'
39
+ option :broadcast_beacons, :type => :boolean, :desc => 'Broadcast beacons for dynamic discovery (Currently only available with ZeroMQ).'
40
+ option :broadcast_busy, :type => :boolean, :default => false, :desc => 'Remove busy nodes from cluster when all workers are busy (Currently only available with ZeroMQ).'
41
+ option :debug, :type => :boolean, :default => false, :aliases => %w(-d), :desc => 'Debug Mode. Override log level to DEBUG.'
42
+ option :gc_pause_request, :type => :boolean, :default => false, :desc => 'Enable/Disable GC pause during request.'
43
+ option :print_deprecation_warnings, :type => :boolean, :default => nil, :desc => 'Cause use of deprecated fields to be printed or ignored.'
44
+ option :workers_only, :type => :boolean, :default => false, :desc => "Starts process with only workers (no broker/frontend is started) only relevant for Zmq Server"
45
+ option :worker_port, :type => :numeric, :default => nil, :desc => "Port for 'backend' where workers connect (defaults to port + 1)"
46
+ option :zmq_inproc, :type => :boolean, :default => true, :desc => 'Use inproc protocol for zmq Server/Broker/Worker'
47
+
48
+ def start(app_file)
49
+ debug_say('Configuring the rpc_server process')
50
+
51
+ configure_logger
52
+ configure_traps
53
+ configure_runner_mode
54
+ create_runner
55
+ configure_process_name(app_file)
56
+ configure_gc
57
+ configure_deprecation_warnings
58
+
59
+ require_application(app_file) unless exit_requested?
60
+ start_server unless exit_requested?
61
+ rescue => e
62
+ say_and_exit('ERROR: RPC Server failed to start.', e)
63
+ end
64
+
65
+ desc 'version', 'Print ruby and protoc versions and exit.'
66
+ def version
67
+ say("Ruby Protobuf v#{::Protobuf::VERSION}")
68
+ end
69
+
70
+ no_tasks do
71
+
72
+ # Tell protobuf how to handle the printing of deprecated field usage.
73
+ def configure_deprecation_warnings
74
+ if options.print_deprecation_warnings.nil?
75
+ ::Protobuf.print_deprecation_warnings = !ENV.key?("PB_IGNORE_DEPRECATIONS")
76
+ else
77
+ ::Protobuf.print_deprecation_warnings = options.print_deprecation_warnings?
78
+ end
79
+ end
80
+
81
+ # If we pause during request we don't need to pause in serialization
82
+ def configure_gc
83
+ debug_say('Configuring gc')
84
+
85
+ if defined?(JRUBY_VERSION)
86
+ # GC.enable/disable are noop's on Jruby
87
+ ::Protobuf.gc_pause_server_request = false
88
+ else
89
+ ::Protobuf.gc_pause_server_request = options.gc_pause_request?
90
+ end
91
+ end
92
+
93
+ # Setup the protobuf logger.
94
+ def configure_logger
95
+ debug_say('Configuring logger')
96
+
97
+ log_level = options.debug? ? ::Logger::DEBUG : options.level
98
+
99
+ ::Protobuf::Logging.initialize_logger(options.log, log_level)
100
+
101
+ # Debug output the server options to the log file.
102
+ logger.debug { 'Debugging options:' }
103
+ logger.debug { options.inspect }
104
+ end
105
+
106
+ # Re-write the $0 var to have a nice process name in ps.
107
+ def configure_process_name(app_file)
108
+ debug_say('Configuring process name')
109
+ $0 = "rpc_server --#{mode} #{options.host}:#{options.port} #{app_file}"
110
+ end
111
+
112
+ # Configure the mode of the server and the runner class.
113
+ def configure_runner_mode
114
+ debug_say('Configuring runner mode')
115
+
116
+ self.mode = if multi_mode?
117
+ say('WARNING: You have provided multiple mode options. Defaulting to socket mode.', :yellow)
118
+ :socket
119
+ elsif options.zmq?
120
+ :zmq
121
+ else # rubocop:disable Style/ElseAlignment
122
+ # above: https://github.com/bbatsov/rubocop/pull/1470/files
123
+ case server_type = ENV["PB_SERVER_TYPE"]
124
+ when nil, /socket/i
125
+ :socket
126
+ when /zmq/i
127
+ :zmq
128
+ else
129
+ say "WARNING: You have provided incorrect option 'PB_SERVER_TYPE=#{server_type}'. Defaulting to socket mode.", :yellow
130
+ :socket
131
+ end
132
+ end
133
+ end
134
+
135
+ # Configure signal traps.
136
+ # TODO: add signal handling for hot-reloading the application.
137
+ def configure_traps
138
+ debug_say('Configuring traps')
139
+
140
+ exit_signals = [:INT, :TERM]
141
+ exit_signals << :QUIT unless defined?(JRUBY_VERSION)
142
+
143
+ exit_signals.each do |signal|
144
+ debug_say("Registering trap for exit signal #{signal}", :blue)
145
+
146
+ trap(signal) do
147
+ self.exit_requested = true
148
+ shutdown_server
149
+ end
150
+ end
151
+ end
152
+
153
+ # Create the runner for the configured mode
154
+ def create_runner
155
+ debug_say("Creating #{mode} runner")
156
+ self.runner = case mode
157
+ when :zmq
158
+ create_zmq_runner
159
+ when :socket
160
+ create_socket_runner
161
+ else
162
+ say_and_exit("Unknown runner mode: #{mode}")
163
+ end
164
+ end
165
+
166
+ # Say something if we're in debug mode.
167
+ def debug_say(message, color = :yellow)
168
+ say(message, color) if options.debug?
169
+ end
170
+
171
+ # Internal helper to determine if the modes are multi-set which is not valid.
172
+ def multi_mode?
173
+ options.zmq? && options.socket?
174
+ end
175
+
176
+ # Require the application file given, exiting if the file doesn't exist.
177
+ def require_application(app_file)
178
+ debug_say('Requiring app file')
179
+ require app_file
180
+ rescue LoadError => e
181
+ say_and_exit("Failed to load application file #{app_file}", e)
182
+ end
183
+
184
+ def runner_options
185
+ opt = options.symbolize_keys
186
+
187
+ opt[:workers_only] = (!!ENV['PB_WORKERS_ONLY']) || options.workers_only
188
+
189
+ opt
190
+ end
191
+
192
+ def say_and_exit(message, exception = nil)
193
+ message = set_color(message, :red) if options.log == STDOUT
194
+
195
+ logger.error { message }
196
+
197
+ if exception
198
+ $stderr.puts "[#{exception.class.name}] #{exception.message}"
199
+ $stderr.puts exception.backtrace.join("\n")
200
+
201
+ logger.error { "[#{exception.class.name}] #{exception.message}" }
202
+ logger.debug { exception.backtrace.join("\n") }
203
+ end
204
+
205
+ exit(1)
206
+ end
207
+
208
+ def create_socket_runner
209
+ require 'protobuf/socket'
210
+
211
+ self.runner = ::Protobuf::Rpc::SocketRunner.new(runner_options)
212
+ end
213
+
214
+ def create_zmq_runner
215
+ require 'protobuf/zmq'
216
+
217
+ self.runner = ::Protobuf::Rpc::ZmqRunner.new(runner_options)
218
+ end
219
+
220
+ def shutdown_server
221
+ logger.info { 'RPC Server shutting down...' }
222
+ runner.stop
223
+ ::Protobuf::Rpc::ServiceDirectory.instance.stop
224
+ end
225
+
226
+ # Start the runner and log the relevant options.
227
+ def start_server
228
+ debug_say('Running server')
229
+
230
+ runner.run do
231
+ logger.info do
232
+ "pid #{::Process.pid} -- #{mode} RPC Server listening at #{options.host}:#{options.port}"
233
+ end
234
+
235
+ ::ActiveSupport::Notifications.instrument("after_server_bind")
236
+ end
237
+
238
+ logger.info { 'Shutdown complete' }
239
+ end
240
+ end
241
+ end
242
+ end