protobuf-cucumber 3.10.4

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 (204) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rubocop.yml +70 -0
  4. data/.rubocop_todo.yml +145 -0
  5. data/.travis.yml +40 -0
  6. data/.yardopts +5 -0
  7. data/CHANGES.md +344 -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 +22 -0
  14. data/bin/rpc_server +5 -0
  15. data/install-protobuf.sh +28 -0
  16. data/lib/protobuf.rb +129 -0
  17. data/lib/protobuf/cli.rb +257 -0
  18. data/lib/protobuf/code_generator.rb +120 -0
  19. data/lib/protobuf/decoder.rb +28 -0
  20. data/lib/protobuf/deprecation.rb +117 -0
  21. data/lib/protobuf/descriptors.rb +3 -0
  22. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +62 -0
  23. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +301 -0
  24. data/lib/protobuf/encoder.rb +11 -0
  25. data/lib/protobuf/enum.rb +365 -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 +380 -0
  29. data/lib/protobuf/field/base_field_object_definitions.rb +504 -0
  30. data/lib/protobuf/field/bool_field.rb +64 -0
  31. data/lib/protobuf/field/bytes_field.rb +78 -0
  32. data/lib/protobuf/field/double_field.rb +25 -0
  33. data/lib/protobuf/field/enum_field.rb +61 -0
  34. data/lib/protobuf/field/field_array.rb +104 -0
  35. data/lib/protobuf/field/field_hash.rb +122 -0
  36. data/lib/protobuf/field/fixed32_field.rb +25 -0
  37. data/lib/protobuf/field/fixed64_field.rb +28 -0
  38. data/lib/protobuf/field/float_field.rb +43 -0
  39. data/lib/protobuf/field/int32_field.rb +21 -0
  40. data/lib/protobuf/field/int64_field.rb +34 -0
  41. data/lib/protobuf/field/integer_field.rb +23 -0
  42. data/lib/protobuf/field/message_field.rb +51 -0
  43. data/lib/protobuf/field/sfixed32_field.rb +27 -0
  44. data/lib/protobuf/field/sfixed64_field.rb +28 -0
  45. data/lib/protobuf/field/signed_integer_field.rb +29 -0
  46. data/lib/protobuf/field/sint32_field.rb +21 -0
  47. data/lib/protobuf/field/sint64_field.rb +21 -0
  48. data/lib/protobuf/field/string_field.rb +51 -0
  49. data/lib/protobuf/field/uint32_field.rb +21 -0
  50. data/lib/protobuf/field/uint64_field.rb +21 -0
  51. data/lib/protobuf/field/varint_field.rb +77 -0
  52. data/lib/protobuf/generators/base.rb +85 -0
  53. data/lib/protobuf/generators/enum_generator.rb +39 -0
  54. data/lib/protobuf/generators/extension_generator.rb +27 -0
  55. data/lib/protobuf/generators/field_generator.rb +193 -0
  56. data/lib/protobuf/generators/file_generator.rb +262 -0
  57. data/lib/protobuf/generators/group_generator.rb +122 -0
  58. data/lib/protobuf/generators/message_generator.rb +104 -0
  59. data/lib/protobuf/generators/option_generator.rb +17 -0
  60. data/lib/protobuf/generators/printable.rb +160 -0
  61. data/lib/protobuf/generators/service_generator.rb +50 -0
  62. data/lib/protobuf/lifecycle.rb +33 -0
  63. data/lib/protobuf/logging.rb +39 -0
  64. data/lib/protobuf/message.rb +260 -0
  65. data/lib/protobuf/message/fields.rb +233 -0
  66. data/lib/protobuf/message/serialization.rb +85 -0
  67. data/lib/protobuf/optionable.rb +70 -0
  68. data/lib/protobuf/rpc/buffer.rb +78 -0
  69. data/lib/protobuf/rpc/client.rb +140 -0
  70. data/lib/protobuf/rpc/connectors/base.rb +221 -0
  71. data/lib/protobuf/rpc/connectors/ping.rb +89 -0
  72. data/lib/protobuf/rpc/connectors/socket.rb +78 -0
  73. data/lib/protobuf/rpc/connectors/zmq.rb +319 -0
  74. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +50 -0
  75. data/lib/protobuf/rpc/env.rb +60 -0
  76. data/lib/protobuf/rpc/error.rb +28 -0
  77. data/lib/protobuf/rpc/error/client_error.rb +31 -0
  78. data/lib/protobuf/rpc/error/server_error.rb +43 -0
  79. data/lib/protobuf/rpc/middleware.rb +25 -0
  80. data/lib/protobuf/rpc/middleware/exception_handler.rb +40 -0
  81. data/lib/protobuf/rpc/middleware/logger.rb +95 -0
  82. data/lib/protobuf/rpc/middleware/request_decoder.rb +79 -0
  83. data/lib/protobuf/rpc/middleware/response_encoder.rb +83 -0
  84. data/lib/protobuf/rpc/middleware/runner.rb +18 -0
  85. data/lib/protobuf/rpc/rpc.pb.rb +64 -0
  86. data/lib/protobuf/rpc/rpc_method.rb +16 -0
  87. data/lib/protobuf/rpc/server.rb +39 -0
  88. data/lib/protobuf/rpc/servers/socket/server.rb +121 -0
  89. data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
  90. data/lib/protobuf/rpc/servers/socket_runner.rb +46 -0
  91. data/lib/protobuf/rpc/servers/zmq/broker.rb +194 -0
  92. data/lib/protobuf/rpc/servers/zmq/server.rb +321 -0
  93. data/lib/protobuf/rpc/servers/zmq/util.rb +48 -0
  94. data/lib/protobuf/rpc/servers/zmq/worker.rb +105 -0
  95. data/lib/protobuf/rpc/servers/zmq_runner.rb +70 -0
  96. data/lib/protobuf/rpc/service.rb +172 -0
  97. data/lib/protobuf/rpc/service_directory.rb +261 -0
  98. data/lib/protobuf/rpc/service_dispatcher.rb +45 -0
  99. data/lib/protobuf/rpc/service_filters.rb +250 -0
  100. data/lib/protobuf/rpc/stat.rb +119 -0
  101. data/lib/protobuf/socket.rb +21 -0
  102. data/lib/protobuf/tasks.rb +1 -0
  103. data/lib/protobuf/tasks/compile.rake +80 -0
  104. data/lib/protobuf/varint.rb +20 -0
  105. data/lib/protobuf/varint_pure.rb +31 -0
  106. data/lib/protobuf/version.rb +3 -0
  107. data/lib/protobuf/wire_type.rb +10 -0
  108. data/lib/protobuf/zmq.rb +21 -0
  109. data/profile.html +5103 -0
  110. data/proto/dynamic_discovery.proto +44 -0
  111. data/proto/google/protobuf/compiler/plugin.proto +147 -0
  112. data/proto/google/protobuf/descriptor.proto +779 -0
  113. data/proto/rpc.proto +69 -0
  114. data/protobuf-cucumber.gemspec +57 -0
  115. data/spec/benchmark/tasks.rb +143 -0
  116. data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
  117. data/spec/encoding/all_types_spec.rb +103 -0
  118. data/spec/encoding/extreme_values_spec.rb +0 -0
  119. data/spec/functional/class_inheritance_spec.rb +52 -0
  120. data/spec/functional/code_generator_spec.rb +58 -0
  121. data/spec/functional/socket_server_spec.rb +59 -0
  122. data/spec/functional/zmq_server_spec.rb +105 -0
  123. data/spec/lib/protobuf/cli_spec.rb +317 -0
  124. data/spec/lib/protobuf/code_generator_spec.rb +87 -0
  125. data/spec/lib/protobuf/enum_spec.rb +307 -0
  126. data/spec/lib/protobuf/field/bool_field_spec.rb +91 -0
  127. data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
  128. data/spec/lib/protobuf/field/enum_field_spec.rb +44 -0
  129. data/spec/lib/protobuf/field/field_array_spec.rb +105 -0
  130. data/spec/lib/protobuf/field/field_hash_spec.rb +168 -0
  131. data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
  132. data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
  133. data/spec/lib/protobuf/field/float_field_spec.rb +90 -0
  134. data/spec/lib/protobuf/field/int32_field_spec.rb +120 -0
  135. data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
  136. data/spec/lib/protobuf/field/message_field_spec.rb +132 -0
  137. data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
  138. data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
  139. data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
  140. data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
  141. data/spec/lib/protobuf/field/string_field_spec.rb +79 -0
  142. data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
  143. data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
  144. data/spec/lib/protobuf/field_spec.rb +192 -0
  145. data/spec/lib/protobuf/generators/base_spec.rb +154 -0
  146. data/spec/lib/protobuf/generators/enum_generator_spec.rb +82 -0
  147. data/spec/lib/protobuf/generators/extension_generator_spec.rb +42 -0
  148. data/spec/lib/protobuf/generators/field_generator_spec.rb +197 -0
  149. data/spec/lib/protobuf/generators/file_generator_spec.rb +119 -0
  150. data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
  151. data/spec/lib/protobuf/generators/service_generator_spec.rb +99 -0
  152. data/spec/lib/protobuf/lifecycle_spec.rb +94 -0
  153. data/spec/lib/protobuf/message_spec.rb +944 -0
  154. data/spec/lib/protobuf/optionable_spec.rb +265 -0
  155. data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
  156. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +226 -0
  157. data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +69 -0
  158. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +34 -0
  159. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +110 -0
  160. data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
  161. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
  162. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
  163. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +91 -0
  164. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
  165. data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +43 -0
  166. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
  167. data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
  168. data/spec/lib/protobuf/rpc/service_directory_spec.rb +293 -0
  169. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +35 -0
  170. data/spec/lib/protobuf/rpc/service_filters_spec.rb +517 -0
  171. data/spec/lib/protobuf/rpc/service_spec.rb +162 -0
  172. data/spec/lib/protobuf/rpc/stat_spec.rb +101 -0
  173. data/spec/lib/protobuf/varint_spec.rb +29 -0
  174. data/spec/lib/protobuf_spec.rb +105 -0
  175. data/spec/spec_helper.rb +42 -0
  176. data/spec/support/all.rb +6 -0
  177. data/spec/support/packed_field.rb +23 -0
  178. data/spec/support/protos/all_types.data.bin +0 -0
  179. data/spec/support/protos/all_types.data.txt +119 -0
  180. data/spec/support/protos/enum.pb.rb +63 -0
  181. data/spec/support/protos/enum.proto +37 -0
  182. data/spec/support/protos/extreme_values.data.bin +0 -0
  183. data/spec/support/protos/google_unittest.bin +0 -0
  184. data/spec/support/protos/google_unittest.pb.rb +798 -0
  185. data/spec/support/protos/google_unittest.proto +884 -0
  186. data/spec/support/protos/google_unittest_custom_options.bin +0 -0
  187. data/spec/support/protos/google_unittest_custom_options.pb.rb +361 -0
  188. data/spec/support/protos/google_unittest_custom_options.proto +424 -0
  189. data/spec/support/protos/google_unittest_import.pb.rb +55 -0
  190. data/spec/support/protos/google_unittest_import.proto +73 -0
  191. data/spec/support/protos/google_unittest_import_public.pb.rb +31 -0
  192. data/spec/support/protos/google_unittest_import_public.proto +41 -0
  193. data/spec/support/protos/map-test.bin +157 -0
  194. data/spec/support/protos/map-test.pb.rb +85 -0
  195. data/spec/support/protos/map-test.proto +68 -0
  196. data/spec/support/protos/multi_field_extensions.pb.rb +59 -0
  197. data/spec/support/protos/multi_field_extensions.proto +35 -0
  198. data/spec/support/protos/resource.pb.rb +172 -0
  199. data/spec/support/protos/resource.proto +137 -0
  200. data/spec/support/resource_service.rb +23 -0
  201. data/spec/support/server.rb +65 -0
  202. data/spec/support/test_app_file.rb +2 -0
  203. data/varint_prof.rb +82 -0
  204. metadata +579 -0
@@ -0,0 +1,83 @@
1
+ module Protobuf
2
+ module Rpc
3
+ module Middleware
4
+ class ResponseEncoder
5
+ include ::Protobuf::Logging
6
+
7
+ attr_reader :app, :env
8
+
9
+ def initialize(app)
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ dup._call(env)
15
+ end
16
+
17
+ def _call(env)
18
+ @env = app.call(env)
19
+
20
+ env.response = response
21
+ env.encoded_response = encoded_response
22
+ env
23
+ end
24
+
25
+ def log_signature
26
+ env.log_signature || super
27
+ end
28
+
29
+ private
30
+
31
+ # Encode the response wrapper to return to the client
32
+ #
33
+ def encoded_response
34
+ logger.debug { sign_message("Encoding response: #{response.inspect}") }
35
+
36
+ env.encoded_response = wrapped_response.encode
37
+ rescue => exception
38
+ log_exception(exception)
39
+
40
+ # Rescue encoding exceptions, re-wrap them as generic protobuf errors,
41
+ # and re-raise them
42
+ raise PbError, exception.message
43
+ end
44
+
45
+ # Prod the object to see if we can produce a proto object as a response
46
+ # candidate. Validate the candidate protos.
47
+ def response
48
+ return @response unless @response.nil?
49
+
50
+ candidate = env.response
51
+ return @response = validate!(candidate) if candidate.is_a?(Message)
52
+ return @response = validate!(candidate.to_proto) if candidate.respond_to?(:to_proto)
53
+ return @response = env.response_type.new(candidate.to_hash) if candidate.respond_to?(:to_hash)
54
+ return @response = candidate if candidate.is_a?(PbError)
55
+
56
+ @response = validate!(candidate)
57
+ end
58
+
59
+ # Ensure that the response candidate we've been given is of the type
60
+ # we expect so that deserialization on the client side works.
61
+ #
62
+ def validate!(candidate)
63
+ if candidate.class != env.response_type
64
+ fail BadResponseProto, "Expected response to be of type #{env.response_type.name} but was #{candidate.class.name}"
65
+ end
66
+
67
+ candidate
68
+ end
69
+
70
+ # The middleware stack returns either an error or response proto. Package
71
+ # it up so that it's in the correct spot in the response wrapper
72
+ #
73
+ def wrapped_response
74
+ if response.is_a?(::Protobuf::Rpc::PbError)
75
+ ::Protobuf::Socketrpc::Response.new(:error => response.message, :error_reason => response.error_type, :server => env.server)
76
+ else
77
+ ::Protobuf::Socketrpc::Response.new(:response_proto => response.encode, :server => env.server)
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,18 @@
1
+ require 'middleware/runner'
2
+
3
+ module Protobuf
4
+ module Rpc
5
+ module Middleware
6
+ class Runner < ::Middleware::Runner
7
+ # Override the default middleware runner so we can ensure that the
8
+ # service dispatcher is the last thing called in the stack.
9
+ #
10
+ def initialize(stack)
11
+ stack << Protobuf::Rpc::ServiceDispatcher
12
+
13
+ super(stack)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+
3
+ ##
4
+ # This file is auto-generated. DO NOT EDIT!
5
+ #
6
+ require 'protobuf'
7
+
8
+ module Protobuf
9
+ module Socketrpc
10
+ ::Protobuf::Optionable.inject(self) { ::Google::Protobuf::FileOptions }
11
+
12
+ ##
13
+ # Enum Classes
14
+ #
15
+ class ErrorReason < ::Protobuf::Enum
16
+ define :BAD_REQUEST_DATA, 0
17
+ define :BAD_REQUEST_PROTO, 1
18
+ define :SERVICE_NOT_FOUND, 2
19
+ define :METHOD_NOT_FOUND, 3
20
+ define :RPC_ERROR, 4
21
+ define :RPC_FAILED, 5
22
+ define :INVALID_REQUEST_PROTO, 6
23
+ define :BAD_RESPONSE_PROTO, 7
24
+ define :UNKNOWN_HOST, 8
25
+ define :IO_ERROR, 9
26
+ end
27
+
28
+
29
+ ##
30
+ # Message Classes
31
+ #
32
+ class Request < ::Protobuf::Message; end
33
+ class Response < ::Protobuf::Message; end
34
+ class Header < ::Protobuf::Message; end
35
+
36
+
37
+ ##
38
+ # Message Fields
39
+ #
40
+ class Request
41
+ required :string, :service_name, 1
42
+ required :string, :method_name, 2
43
+ optional :bytes, :request_proto, 3
44
+ optional :string, :caller, 4
45
+ repeated ::Protobuf::Socketrpc::Header, :headers, 5
46
+ end
47
+
48
+ class Response
49
+ optional :bytes, :response_proto, 1
50
+ optional :string, :error, 2
51
+ optional :bool, :callback, 3, :default => false
52
+ optional ::Protobuf::Socketrpc::ErrorReason, :error_reason, 4
53
+ optional :string, :server, 5
54
+ end
55
+
56
+ class Header
57
+ required :string, :key, 1
58
+ optional :string, :value, 2
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
@@ -0,0 +1,16 @@
1
+ module Protobuf
2
+ module Rpc
3
+ class RpcMethod
4
+ ::Protobuf::Optionable.inject(self, false) { ::Google::Protobuf::MethodOptions }
5
+
6
+ attr_reader :method, :request_type, :response_type
7
+
8
+ def initialize(method, request_type, response_type, &options_block)
9
+ @method = method
10
+ @request_type = request_type
11
+ @response_type = response_type
12
+ instance_eval(&options_block) if options_block
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,39 @@
1
+ require 'protobuf'
2
+ require 'protobuf/logging'
3
+ require 'protobuf/rpc/rpc.pb'
4
+ require 'protobuf/rpc/buffer'
5
+ require 'protobuf/rpc/env'
6
+ require 'protobuf/rpc/error'
7
+ require 'protobuf/rpc/middleware'
8
+ require 'protobuf/rpc/service_dispatcher'
9
+
10
+ module Protobuf
11
+ module Rpc
12
+ module Server
13
+ def gc_pause
14
+ ::GC.disable if ::Protobuf.gc_pause_server_request?
15
+
16
+ yield
17
+
18
+ ::GC.enable if ::Protobuf.gc_pause_server_request?
19
+ end
20
+
21
+ # Invoke the service method dictated by the proto wrapper request object
22
+ #
23
+ def handle_request(request_data, env_data = {})
24
+ # Create an env object that holds different parts of the environment and
25
+ # is available to all of the middlewares
26
+ env = Env.new(env_data.merge('encoded_request' => request_data, 'log_signature' => log_signature))
27
+
28
+ # Invoke the middleware stack, the last of which is the service dispatcher
29
+ env = Rpc.middleware.call(env)
30
+
31
+ env.encoded_response
32
+ end
33
+
34
+ def log_signature
35
+ @_log_signature ||= "[server-#{self.class.name}]"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,121 @@
1
+ require 'set'
2
+
3
+ require 'protobuf/rpc/servers/socket/worker'
4
+
5
+ module Protobuf
6
+ module Rpc
7
+ module Socket
8
+ class Server
9
+ include ::Protobuf::Logging
10
+
11
+ AUTO_COLLECT_TIMEOUT = 5 # seconds
12
+
13
+ private
14
+
15
+ attr_accessor :threshold, :host, :port, :backlog
16
+ attr_writer :running
17
+
18
+ public
19
+
20
+ attr_reader :running
21
+ alias :running? running
22
+
23
+ def initialize(options)
24
+ self.running = false
25
+ self.host = options.fetch(:host)
26
+ self.port = options.fetch(:port)
27
+ self.backlog = options.fetch(:backlog, 100)
28
+ self.threshold = options.fetch(:threshold, 100)
29
+ end
30
+
31
+ def threads
32
+ @threads ||= []
33
+ end
34
+
35
+ def working
36
+ @working ||= Set.new
37
+ end
38
+
39
+ def cleanup?
40
+ # every `threshold` connections run a cleanup routine after closing the response
41
+ !threads.empty? && threads.size % threshold == 0
42
+ end
43
+
44
+ def cleanup_threads
45
+ logger.debug { sign_message("Thread cleanup - #{threads.size} - start") }
46
+
47
+ threads.delete_if do |hash|
48
+ unless (thread = hash.fetch(:thread)).alive?
49
+ thread.join
50
+ working.delete(hash.fetch(:socket))
51
+ end
52
+ end
53
+
54
+ logger.debug { sign_message("Thread cleanup - #{threads.size} - complete") }
55
+ end
56
+
57
+ def log_signature
58
+ @_log_signature ||= "[server-#{self.class.name}]"
59
+ end
60
+
61
+ def new_worker(socket)
62
+ Thread.new(socket) do |sock|
63
+ ::Protobuf::Rpc::Socket::Worker.new(sock, &:close)
64
+ end
65
+ end
66
+
67
+ def run
68
+ logger.debug { sign_message("Run") }
69
+
70
+ server = ::TCPServer.new(host, port)
71
+ fail "The server was unable to start properly." if server.closed?
72
+
73
+ begin
74
+ server.listen(backlog)
75
+ listen_fds = [server]
76
+ self.running = true
77
+
78
+ while running?
79
+ logger.debug { sign_message("Waiting for connections") }
80
+ ready_cnxns = begin
81
+ IO.select(listen_fds, [], [], AUTO_COLLECT_TIMEOUT)
82
+ rescue IOError
83
+ nil
84
+ end
85
+
86
+ if ready_cnxns
87
+ ready_cnxns.first.each do |client|
88
+ case
89
+ when !running?
90
+ # no-op
91
+ when client == server
92
+ logger.debug { sign_message("Accepted new connection") }
93
+ client, _sockaddr = server.accept
94
+ listen_fds << client
95
+ else
96
+ unless working.include?(client)
97
+ working << listen_fds.delete(client)
98
+ logger.debug { sign_message("Working") }
99
+ threads << { :thread => new_worker(client), :socket => client }
100
+
101
+ cleanup_threads if cleanup?
102
+ end
103
+ end
104
+ end
105
+ elsif threads.size > 1
106
+ # Run a cleanup if select times out while waiting
107
+ cleanup_threads
108
+ end
109
+ end
110
+ ensure
111
+ server.close
112
+ end
113
+ end
114
+
115
+ def stop
116
+ self.running = false
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,56 @@
1
+ require 'protobuf/rpc/server'
2
+ require 'protobuf/logging'
3
+
4
+ module Protobuf
5
+ module Rpc
6
+ module Socket
7
+ class Worker
8
+ include ::Protobuf::Rpc::Server
9
+ include ::Protobuf::Logging
10
+
11
+ def initialize(sock, &complete_cb)
12
+ @socket = sock
13
+ @complete_cb = complete_cb
14
+
15
+ data = read_data
16
+ return unless data
17
+
18
+ gc_pause do
19
+ encoded_response = handle_request(data)
20
+ send_data(encoded_response)
21
+ end
22
+ end
23
+
24
+ def read_data
25
+ size_io = StringIO.new
26
+
27
+ until (size_reader = @socket.getc) == "-"
28
+ size_io << size_reader
29
+ end
30
+ str_size_io = size_io.string
31
+
32
+ @socket.read(str_size_io.to_i)
33
+ end
34
+
35
+ def send_data(data)
36
+ fail 'Socket closed unexpectedly' unless socket_writable?
37
+ response_buffer = Protobuf::Rpc::Buffer.new(:write)
38
+ response_buffer.set_data(data)
39
+
40
+ @socket.write(response_buffer.write)
41
+ @socket.flush
42
+
43
+ @complete_cb.call(@socket)
44
+ end
45
+
46
+ def log_signature
47
+ @_log_signature ||= "[server-#{self.class}-#{object_id}]"
48
+ end
49
+
50
+ def socket_writable?
51
+ ! @socket.nil? && ! @socket.closed?
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,46 @@
1
+ module Protobuf
2
+ module Rpc
3
+ class SocketRunner
4
+
5
+ private
6
+
7
+ attr_accessor :server
8
+
9
+ public
10
+
11
+ def initialize(options)
12
+ options = case
13
+ when options.is_a?(OpenStruct) then
14
+ options.marshal_dump
15
+ when options.respond_to?(:to_hash) then
16
+ options.to_hash.symbolize_keys
17
+ else
18
+ fail "Cannot parser Socket Server - server options"
19
+ end
20
+
21
+ self.server = ::Protobuf::Rpc::Socket::Server.new(options)
22
+ end
23
+
24
+ def run
25
+ yield if block_given?
26
+ server.run
27
+ end
28
+
29
+ def running?
30
+ server.running?
31
+ end
32
+
33
+ def stop
34
+ server.stop
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ module Protobuf
41
+ module Rpc
42
+ module Servers # bad file namespacing
43
+ SocketRunner = ::Protobuf::Rpc::SocketRunner
44
+ end
45
+ end
46
+ end