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,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)
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('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,123 @@
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_method :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.size > 0 && 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) do |s|
64
+ s.close
65
+ end
66
+ end
67
+ end
68
+
69
+ def run
70
+ logger.debug { sign_message("Run") }
71
+
72
+ server = ::TCPServer.new(host, port)
73
+ fail "The server was unable to start properly." if server.closed?
74
+
75
+ begin
76
+ server.listen(backlog)
77
+ listen_fds = [server]
78
+ self.running = true
79
+
80
+ while running?
81
+ logger.debug { sign_message("Waiting for connections") }
82
+ ready_cnxns = begin
83
+ IO.select(listen_fds, [], [], AUTO_COLLECT_TIMEOUT)
84
+ rescue IOError
85
+ nil
86
+ end
87
+
88
+ if ready_cnxns
89
+ ready_cnxns.first.each do |client|
90
+ case
91
+ when !running?
92
+ # no-op
93
+ when client == server
94
+ logger.debug { sign_message("Accepted new connection") }
95
+ client, _sockaddr = server.accept
96
+ listen_fds << client
97
+ else
98
+ unless working.include?(client)
99
+ working << listen_fds.delete(client)
100
+ logger.debug { sign_message("Working") }
101
+ threads << { :thread => new_worker(client), :socket => client }
102
+
103
+ cleanup_threads if cleanup?
104
+ end
105
+ end
106
+ end
107
+ else
108
+ # Run a cleanup if select times out while waiting
109
+ cleanup_threads if threads.size > 1
110
+ end
111
+ end
112
+ ensure
113
+ server.close
114
+ end
115
+ end
116
+
117
+ def stop
118
+ self.running = false
119
+ end
120
+ end
121
+ end
122
+ end
123
+ 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,40 @@
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.is_a?(Hash) then
16
+ options
17
+ when options.respond_to?(:to_hash) then
18
+ options.to_hash
19
+ else
20
+ fail "Cannot parser Socket Server - server options"
21
+ end
22
+
23
+ self.server = ::Protobuf::Rpc::Socket::Server.new(options)
24
+ end
25
+
26
+ def run
27
+ yield if block_given?
28
+ server.run
29
+ end
30
+
31
+ def running?
32
+ server.running?
33
+ end
34
+
35
+ def stop
36
+ server.stop
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,193 @@
1
+ require 'thread'
2
+
3
+ module Protobuf
4
+ module Rpc
5
+ module Zmq
6
+ class Broker
7
+ include ::Protobuf::Rpc::Zmq::Util
8
+
9
+ attr_reader :local_queue
10
+
11
+ def initialize(server)
12
+ @server = server
13
+
14
+ init_zmq_context
15
+ init_local_queue
16
+ init_backend_socket
17
+ init_frontend_socket
18
+ init_poller
19
+ rescue
20
+ teardown
21
+ raise
22
+ end
23
+
24
+ def run
25
+ @idle_workers = []
26
+ @running = true
27
+
28
+ loop do
29
+ process_local_queue
30
+ rc = @poller.poll(broker_polling_milliseconds)
31
+
32
+ # The server was shutdown and no requests are pending
33
+ break if rc == 0 && !running? && @server.workers.empty?
34
+ # Something went wrong
35
+ break if rc == -1
36
+
37
+ check_and_process_backend
38
+ process_local_queue # Fair ordering so queued requests get in before new requests
39
+ check_and_process_frontend
40
+ end
41
+ ensure
42
+ teardown
43
+ @running = false
44
+ end
45
+
46
+ def running?
47
+ @running && @server.running?
48
+ end
49
+
50
+ private
51
+
52
+ def backend_poll_weight
53
+ @backend_poll_weight ||= [ENV["PB_ZMQ_SERVER_BACKEND_POLL_WEIGHT"].to_i, 1].max
54
+ end
55
+
56
+ def broker_polling_milliseconds
57
+ @broker_polling_milliseconds ||= [ENV["PB_ZMQ_BROKER_POLLING_MILLISECONDS"].to_i, 500].max
58
+ end
59
+
60
+ def check_and_process_backend
61
+ readables_include_backend = @poller.readables.include?(@backend_socket)
62
+ message_count_read_from_backend = 0
63
+
64
+ while readables_include_backend && message_count_read_from_backend < backend_poll_weight
65
+ message_count_read_from_backend += 1
66
+ process_backend
67
+ @poller.poll_nonblock
68
+ readables_include_backend = @poller.readables.include?(@backend_socket)
69
+ end
70
+ end
71
+
72
+ def check_and_process_frontend
73
+ readables_include_frontend = @poller.readables.include?(@frontend_socket)
74
+ message_count_read_from_frontend = 0
75
+
76
+ while readables_include_frontend && message_count_read_from_frontend < frontend_poll_weight
77
+ message_count_read_from_frontend += 1
78
+ process_frontend
79
+ break unless local_queue_available? # no need to read frontend just to throw away messages, will prioritize backend when full
80
+ @poller.poll_nonblock
81
+ readables_include_frontend = @poller.readables.include?(@frontend_socket)
82
+ end
83
+ end
84
+
85
+ def frontend_poll_weight
86
+ @frontend_poll_weight ||= [ENV["PB_ZMQ_SERVER_FRONTEND_POLL_WEIGHT"].to_i, 1].max
87
+ end
88
+
89
+ def init_backend_socket
90
+ @backend_socket = @zmq_context.socket(ZMQ::ROUTER)
91
+ zmq_error_check(@backend_socket.bind(@server.backend_uri))
92
+ end
93
+
94
+ def init_frontend_socket
95
+ @frontend_socket = @zmq_context.socket(ZMQ::ROUTER)
96
+ zmq_error_check(@frontend_socket.bind(@server.frontend_uri))
97
+ end
98
+
99
+ def init_local_queue
100
+ @local_queue = []
101
+ end
102
+
103
+ def init_poller
104
+ @poller = ZMQ::Poller.new
105
+ @poller.register_readable(@frontend_socket)
106
+ @poller.register_readable(@backend_socket)
107
+ end
108
+
109
+ def init_zmq_context
110
+ if inproc?
111
+ @zmq_context = @server.zmq_context
112
+ else
113
+ @zmq_context = ZMQ::Context.new
114
+ end
115
+ end
116
+
117
+ def inproc?
118
+ !!@server.try(:inproc?)
119
+ end
120
+
121
+ def local_queue_available?
122
+ local_queue.size < local_queue_max_size && running?
123
+ end
124
+
125
+ def local_queue_max_size
126
+ @local_queue_max_size ||= [ENV["PB_ZMQ_SERVER_QUEUE_MAX_SIZE"].to_i, 5].max
127
+ end
128
+
129
+ def process_backend
130
+ worker, _ignore, *frames = read_from_backend
131
+
132
+ @idle_workers << worker
133
+
134
+ unless frames == [::Protobuf::Rpc::Zmq::WORKER_READY_MESSAGE]
135
+ write_to_frontend(frames)
136
+ end
137
+ end
138
+
139
+ def process_frontend
140
+ address, _, message, *frames = read_from_frontend
141
+
142
+ if message == ::Protobuf::Rpc::Zmq::CHECK_AVAILABLE_MESSAGE
143
+ if local_queue_available?
144
+ write_to_frontend([address, ::Protobuf::Rpc::Zmq::EMPTY_STRING, ::Protobuf::Rpc::Zmq::WORKERS_AVAILABLE])
145
+ else
146
+ write_to_frontend([address, ::Protobuf::Rpc::Zmq::EMPTY_STRING, ::Protobuf::Rpc::Zmq::NO_WORKERS_AVAILABLE])
147
+ end
148
+ else
149
+ if @idle_workers.empty?
150
+ local_queue << [address, ::Protobuf::Rpc::Zmq::EMPTY_STRING, message].concat(frames)
151
+ else
152
+ write_to_backend([@idle_workers.shift, ::Protobuf::Rpc::Zmq::EMPTY_STRING].concat([address, ::Protobuf::Rpc::Zmq::EMPTY_STRING, message]).concat(frames))
153
+ end
154
+ end
155
+ end
156
+
157
+ def process_local_queue
158
+ return if local_queue.empty?
159
+ return if @idle_workers.empty?
160
+
161
+ write_to_backend([@idle_workers.shift, ::Protobuf::Rpc::Zmq::EMPTY_STRING].concat(local_queue.shift))
162
+ process_local_queue
163
+ end
164
+
165
+ def read_from_backend
166
+ frames = []
167
+ zmq_error_check(@backend_socket.recv_strings(frames))
168
+ frames
169
+ end
170
+
171
+ def read_from_frontend
172
+ frames = []
173
+ zmq_error_check(@frontend_socket.recv_strings(frames))
174
+ frames
175
+ end
176
+
177
+ def teardown
178
+ @frontend_socket.try(:close)
179
+ @backend_socket.try(:close)
180
+ @zmq_context.try(:terminate) unless inproc?
181
+ end
182
+
183
+ def write_to_backend(frames)
184
+ zmq_error_check(@backend_socket.send_strings(frames))
185
+ end
186
+
187
+ def write_to_frontend(frames)
188
+ zmq_error_check(@frontend_socket.send_strings(frames))
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end