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.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rubocop.yml +51 -0
- data/.rubocop_todo.yml +89 -0
- data/.travis.yml +25 -0
- data/.yardopts +5 -0
- data/CHANGES.md +256 -0
- data/CONTRIBUTING.md +16 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +64 -0
- data/bin/protoc-gen-ruby +16 -0
- data/bin/rpc_server +5 -0
- data/install-protobuf.sh +28 -0
- data/lib/protobuf.rb +100 -0
- data/lib/protobuf/cli.rb +242 -0
- data/lib/protobuf/code_generator.rb +44 -0
- data/lib/protobuf/decoder.rb +73 -0
- data/lib/protobuf/deprecation.rb +112 -0
- data/lib/protobuf/descriptors.rb +3 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +48 -0
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +251 -0
- data/lib/protobuf/encoder.rb +67 -0
- data/lib/protobuf/enum.rb +303 -0
- data/lib/protobuf/exceptions.rb +9 -0
- data/lib/protobuf/field.rb +74 -0
- data/lib/protobuf/field/base_field.rb +267 -0
- data/lib/protobuf/field/bool_field.rb +59 -0
- data/lib/protobuf/field/bytes_field.rb +82 -0
- data/lib/protobuf/field/double_field.rb +25 -0
- data/lib/protobuf/field/enum_field.rb +68 -0
- data/lib/protobuf/field/field_array.rb +87 -0
- data/lib/protobuf/field/fixed32_field.rb +25 -0
- data/lib/protobuf/field/fixed64_field.rb +28 -0
- data/lib/protobuf/field/float_field.rb +41 -0
- data/lib/protobuf/field/int32_field.rb +21 -0
- data/lib/protobuf/field/int64_field.rb +21 -0
- data/lib/protobuf/field/integer_field.rb +23 -0
- data/lib/protobuf/field/message_field.rb +65 -0
- data/lib/protobuf/field/sfixed32_field.rb +27 -0
- data/lib/protobuf/field/sfixed64_field.rb +28 -0
- data/lib/protobuf/field/signed_integer_field.rb +29 -0
- data/lib/protobuf/field/sint32_field.rb +21 -0
- data/lib/protobuf/field/sint64_field.rb +21 -0
- data/lib/protobuf/field/string_field.rb +34 -0
- data/lib/protobuf/field/uint32_field.rb +21 -0
- data/lib/protobuf/field/uint64_field.rb +21 -0
- data/lib/protobuf/field/varint_field.rb +73 -0
- data/lib/protobuf/generators/base.rb +70 -0
- data/lib/protobuf/generators/enum_generator.rb +41 -0
- data/lib/protobuf/generators/extension_generator.rb +27 -0
- data/lib/protobuf/generators/field_generator.rb +131 -0
- data/lib/protobuf/generators/file_generator.rb +135 -0
- data/lib/protobuf/generators/group_generator.rb +112 -0
- data/lib/protobuf/generators/message_generator.rb +98 -0
- data/lib/protobuf/generators/printable.rb +160 -0
- data/lib/protobuf/generators/service_generator.rb +26 -0
- data/lib/protobuf/lifecycle.rb +33 -0
- data/lib/protobuf/logging.rb +39 -0
- data/lib/protobuf/message.rb +193 -0
- data/lib/protobuf/message/fields.rb +133 -0
- data/lib/protobuf/message/serialization.rb +89 -0
- data/lib/protobuf/optionable.rb +23 -0
- data/lib/protobuf/rpc/buffer.rb +77 -0
- data/lib/protobuf/rpc/client.rb +168 -0
- data/lib/protobuf/rpc/connector.rb +19 -0
- data/lib/protobuf/rpc/connectors/base.rb +55 -0
- data/lib/protobuf/rpc/connectors/common.rb +176 -0
- data/lib/protobuf/rpc/connectors/socket.rb +73 -0
- data/lib/protobuf/rpc/connectors/zmq.rb +322 -0
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +49 -0
- data/lib/protobuf/rpc/env.rb +58 -0
- data/lib/protobuf/rpc/error.rb +28 -0
- data/lib/protobuf/rpc/error/client_error.rb +31 -0
- data/lib/protobuf/rpc/error/server_error.rb +43 -0
- data/lib/protobuf/rpc/middleware.rb +25 -0
- data/lib/protobuf/rpc/middleware/exception_handler.rb +36 -0
- data/lib/protobuf/rpc/middleware/logger.rb +91 -0
- data/lib/protobuf/rpc/middleware/request_decoder.rb +83 -0
- data/lib/protobuf/rpc/middleware/response_encoder.rb +88 -0
- data/lib/protobuf/rpc/middleware/runner.rb +18 -0
- data/lib/protobuf/rpc/rpc.pb.rb +55 -0
- data/lib/protobuf/rpc/server.rb +39 -0
- data/lib/protobuf/rpc/servers/socket/server.rb +123 -0
- data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
- data/lib/protobuf/rpc/servers/socket_runner.rb +40 -0
- data/lib/protobuf/rpc/servers/zmq/broker.rb +193 -0
- data/lib/protobuf/rpc/servers/zmq/server.rb +320 -0
- data/lib/protobuf/rpc/servers/zmq/util.rb +48 -0
- data/lib/protobuf/rpc/servers/zmq/worker.rb +104 -0
- data/lib/protobuf/rpc/servers/zmq_runner.rb +62 -0
- data/lib/protobuf/rpc/service.rb +179 -0
- data/lib/protobuf/rpc/service_directory.rb +253 -0
- data/lib/protobuf/rpc/service_dispatcher.rb +46 -0
- data/lib/protobuf/rpc/service_filters.rb +272 -0
- data/lib/protobuf/rpc/stat.rb +97 -0
- data/lib/protobuf/socket.rb +21 -0
- data/lib/protobuf/tasks.rb +1 -0
- data/lib/protobuf/tasks/compile.rake +61 -0
- data/lib/protobuf/version.rb +3 -0
- data/lib/protobuf/wire_type.rb +10 -0
- data/lib/protobuf/zmq.rb +21 -0
- data/proto/dynamic_discovery.proto +44 -0
- data/proto/google/protobuf/compiler/plugin.proto +147 -0
- data/proto/google/protobuf/descriptor.proto +620 -0
- data/proto/rpc.proto +62 -0
- data/protobuf.gemspec +51 -0
- data/spec/benchmark/tasks.rb +139 -0
- data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
- data/spec/data/data.bin +3 -0
- data/spec/data/types.bin +0 -0
- data/spec/encoding/all_types_spec.rb +105 -0
- data/spec/encoding/extreme_values_spec.rb +0 -0
- data/spec/functional/class_inheritance_spec.rb +52 -0
- data/spec/functional/socket_server_spec.rb +59 -0
- data/spec/functional/zmq_server_spec.rb +105 -0
- data/spec/lib/protobuf/cli_spec.rb +273 -0
- data/spec/lib/protobuf/code_generator_spec.rb +60 -0
- data/spec/lib/protobuf/enum_spec.rb +265 -0
- data/spec/lib/protobuf/field/bool_field_spec.rb +51 -0
- data/spec/lib/protobuf/field/field_array_spec.rb +69 -0
- data/spec/lib/protobuf/field/float_field_spec.rb +55 -0
- data/spec/lib/protobuf/field/int32_field_spec.rb +89 -0
- data/spec/lib/protobuf/field/string_field_spec.rb +45 -0
- data/spec/lib/protobuf/field_spec.rb +191 -0
- data/spec/lib/protobuf/generators/base_spec.rb +84 -0
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +73 -0
- data/spec/lib/protobuf/generators/extension_generator_spec.rb +42 -0
- data/spec/lib/protobuf/generators/field_generator_spec.rb +102 -0
- data/spec/lib/protobuf/generators/file_generator_spec.rb +32 -0
- data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
- data/spec/lib/protobuf/generators/service_generator_spec.rb +46 -0
- data/spec/lib/protobuf/lifecycle_spec.rb +94 -0
- data/spec/lib/protobuf/message_spec.rb +526 -0
- data/spec/lib/protobuf/optionable_spec.rb +46 -0
- data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
- data/spec/lib/protobuf/rpc/connector_spec.rb +26 -0
- data/spec/lib/protobuf/rpc/connectors/base_spec.rb +50 -0
- data/spec/lib/protobuf/rpc/connectors/common_spec.rb +170 -0
- data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +36 -0
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +117 -0
- data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
- data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
- data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
- data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +75 -0
- data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
- data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +43 -0
- data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
- data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
- data/spec/lib/protobuf/rpc/service_directory_spec.rb +293 -0
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +52 -0
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +517 -0
- data/spec/lib/protobuf/rpc/service_spec.rb +162 -0
- data/spec/lib/protobuf/rpc/stat_spec.rb +68 -0
- data/spec/lib/protobuf_spec.rb +98 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/support/all.rb +6 -0
- data/spec/support/packed_field.rb +22 -0
- data/spec/support/server.rb +64 -0
- data/spec/support/test/all_types.data.bin +0 -0
- data/spec/support/test/all_types.data.txt +119 -0
- data/spec/support/test/defaults.pb.rb +27 -0
- data/spec/support/test/defaults.proto +9 -0
- data/spec/support/test/enum.pb.rb +55 -0
- data/spec/support/test/enum.proto +34 -0
- data/spec/support/test/extended.pb.rb +18 -0
- data/spec/support/test/extended.proto +10 -0
- data/spec/support/test/extreme_values.data.bin +0 -0
- data/spec/support/test/google_unittest.pb.rb +537 -0
- data/spec/support/test/google_unittest.proto +713 -0
- data/spec/support/test/google_unittest_import.pb.rb +39 -0
- data/spec/support/test/google_unittest_import.proto +64 -0
- data/spec/support/test/google_unittest_import_public.pb.rb +10 -0
- data/spec/support/test/google_unittest_import_public.proto +38 -0
- data/spec/support/test/multi_field_extensions.pb.rb +58 -0
- data/spec/support/test/multi_field_extensions.proto +33 -0
- data/spec/support/test/resource.pb.rb +119 -0
- data/spec/support/test/resource.proto +94 -0
- data/spec/support/test/resource_service.rb +23 -0
- data/spec/support/test_app_file.rb +2 -0
- metadata +502 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
require 'thread_safe'
|
|
2
|
+
require 'protobuf/rpc/connectors/base'
|
|
3
|
+
require 'protobuf/rpc/service_directory'
|
|
4
|
+
|
|
5
|
+
module Protobuf
|
|
6
|
+
module Rpc
|
|
7
|
+
module Connectors
|
|
8
|
+
class Zmq < Base
|
|
9
|
+
RequestTimeout = Class.new(RuntimeError)
|
|
10
|
+
ZmqRecoverableError = Class.new(RuntimeError)
|
|
11
|
+
ZmqEagainError = Class.new(RuntimeError)
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# Included Modules
|
|
15
|
+
#
|
|
16
|
+
include Protobuf::Rpc::Connectors::Common
|
|
17
|
+
include Protobuf::Logging
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# Class Constants
|
|
21
|
+
#
|
|
22
|
+
CLIENT_RETRIES = (ENV['PB_CLIENT_RETRIES'] || 3)
|
|
23
|
+
|
|
24
|
+
##
|
|
25
|
+
# Class Methods
|
|
26
|
+
#
|
|
27
|
+
def self.ping_port_responses
|
|
28
|
+
@ping_port_responses ||= ::ThreadSafe::Cache.new
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.zmq_context
|
|
32
|
+
@zmq_contexts ||= Hash.new do |hash, key|
|
|
33
|
+
hash[key] = ZMQ::Context.new
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
@zmq_contexts[Process.pid]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# Instance methods
|
|
41
|
+
#
|
|
42
|
+
def log_signature
|
|
43
|
+
@_log_signature ||= "[client-#{self.class}]"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Start the request/response cycle. We implement the Lazy Pirate
|
|
47
|
+
# req/reply reliability pattern as laid out in the ZMQ Guide, Chapter 4.
|
|
48
|
+
#
|
|
49
|
+
# @see http://zguide.zeromq.org/php:chapter4#Client-side-Reliability-Lazy-Pirate-Pattern
|
|
50
|
+
#
|
|
51
|
+
def send_request
|
|
52
|
+
setup_connection
|
|
53
|
+
send_request_with_lazy_pirate unless error?
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
##
|
|
59
|
+
# Private Instance methods
|
|
60
|
+
#
|
|
61
|
+
def check_available_rcv_timeout
|
|
62
|
+
@check_available_rcv_timeout ||= begin
|
|
63
|
+
case
|
|
64
|
+
when ENV.key?("PB_ZMQ_CLIENT_CHECK_AVAILABLE_RCV_TIMEOUT") then
|
|
65
|
+
ENV["PB_ZMQ_CLIENT_CHECK_AVAILABLE_RCV_TIMEOUT"].to_i
|
|
66
|
+
else
|
|
67
|
+
200 # ms
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def check_available_snd_timeout
|
|
73
|
+
@check_available_snd_timeout ||= begin
|
|
74
|
+
case
|
|
75
|
+
when ENV.key?("PB_ZMQ_CLIENT_CHECK_AVAILABLE_SND_TIMEOUT") then
|
|
76
|
+
ENV["PB_ZMQ_CLIENT_CHECK_AVAILABLE_SND_TIMEOUT"].to_i
|
|
77
|
+
else
|
|
78
|
+
200 # ms
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def close_connection
|
|
84
|
+
# The socket is automatically closed after every request.
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Create a socket connected to a server that can handle the current
|
|
88
|
+
# service. The LINGER is set to 0 so we can close immediately in
|
|
89
|
+
# the event of a timeout
|
|
90
|
+
def create_socket
|
|
91
|
+
begin
|
|
92
|
+
socket = zmq_context.socket(::ZMQ::REQ)
|
|
93
|
+
|
|
94
|
+
if socket # Make sure the context builds the socket
|
|
95
|
+
server_uri = lookup_server_uri
|
|
96
|
+
socket.setsockopt(::ZMQ::LINGER, 0)
|
|
97
|
+
zmq_error_check(socket.connect(server_uri), :socket_connect)
|
|
98
|
+
socket = socket_to_available_server(socket) if first_alive_load_balance?
|
|
99
|
+
end
|
|
100
|
+
end while socket.try(:socket).nil?
|
|
101
|
+
|
|
102
|
+
socket
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Method to determine error state, must be used with Connector API.
|
|
106
|
+
#
|
|
107
|
+
def error?
|
|
108
|
+
!! @error
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def host_alive?(host)
|
|
112
|
+
return true unless ping_port_enabled?
|
|
113
|
+
|
|
114
|
+
if (last_response = self.class.ping_port_responses[host])
|
|
115
|
+
if (Time.now.to_i - last_response[:at]) <= host_alive_check_interval
|
|
116
|
+
return last_response[:ping_port_open]
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
ping_port_open = ping_port_open?(host)
|
|
121
|
+
self.class.ping_port_responses[host] = {
|
|
122
|
+
:at => Time.now.to_i,
|
|
123
|
+
:ping_port_open => ping_port_open,
|
|
124
|
+
}
|
|
125
|
+
ping_port_open
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def host_alive_check_interval
|
|
129
|
+
@host_alive_check_interval ||= [ENV["PB_ZMQ_CLIENT_HOST_ALIVE_CHECK_INTERVAL"].to_i, 1].max
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Lookup a server uri for the requested service in the service
|
|
133
|
+
# directory. If the service directory is not running, default
|
|
134
|
+
# to the host and port in the options
|
|
135
|
+
#
|
|
136
|
+
def lookup_server_uri
|
|
137
|
+
server_lookup_attempts.times do
|
|
138
|
+
first_alive_listing = service_directory.all_listings_for(service).find do |listing|
|
|
139
|
+
host_alive?(listing.try(:address))
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
if first_alive_listing
|
|
143
|
+
host = first_alive_listing.try(:address)
|
|
144
|
+
port = first_alive_listing.try(:port)
|
|
145
|
+
@stats.server = [port, host]
|
|
146
|
+
return "tcp://#{host}:#{port}"
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
host = options[:host]
|
|
150
|
+
port = options[:port]
|
|
151
|
+
|
|
152
|
+
if host_alive?(host)
|
|
153
|
+
@stats.server = [port, host]
|
|
154
|
+
return "tcp://#{host}:#{port}"
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
sleep(1.0 / 100.0)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
fail "Host not found for service #{service}"
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def ping_port_open?(host)
|
|
164
|
+
socket = TCPSocket.new(host, ping_port.to_i)
|
|
165
|
+
socket.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
|
|
166
|
+
socket.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_LINGER, [1, 0].pack('ii'))
|
|
167
|
+
|
|
168
|
+
true
|
|
169
|
+
rescue
|
|
170
|
+
false
|
|
171
|
+
ensure
|
|
172
|
+
begin
|
|
173
|
+
socket && socket.close
|
|
174
|
+
rescue IOError
|
|
175
|
+
nil
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def rcv_timeout
|
|
180
|
+
@rcv_timeout ||= begin
|
|
181
|
+
case
|
|
182
|
+
when options[:timeout] then
|
|
183
|
+
options[:timeout]
|
|
184
|
+
when ENV.key?("PB_ZMQ_CLIENT_RCV_TIMEOUT") then
|
|
185
|
+
ENV["PB_ZMQ_CLIENT_RCV_TIMEOUT"].to_i
|
|
186
|
+
else
|
|
187
|
+
300_000 # 300 seconds
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Trying a number of times, attempt to get a response from the server.
|
|
193
|
+
# If we haven't received a legitimate response in the CLIENT_RETRIES number
|
|
194
|
+
# of retries, fail the request.
|
|
195
|
+
#
|
|
196
|
+
def send_request_with_lazy_pirate
|
|
197
|
+
attempt = 0
|
|
198
|
+
|
|
199
|
+
begin
|
|
200
|
+
attempt += 1
|
|
201
|
+
send_request_with_timeout(attempt)
|
|
202
|
+
parse_response
|
|
203
|
+
rescue RequestTimeout
|
|
204
|
+
retry if attempt < CLIENT_RETRIES
|
|
205
|
+
failure(:RPC_FAILED, "The server repeatedly failed to respond within #{timeout} seconds")
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def send_request_with_timeout(attempt = 0)
|
|
210
|
+
socket = create_socket
|
|
211
|
+
socket.setsockopt(::ZMQ::RCVTIMEO, rcv_timeout)
|
|
212
|
+
socket.setsockopt(::ZMQ::SNDTIMEO, snd_timeout)
|
|
213
|
+
|
|
214
|
+
logger.debug { sign_message("Sending Request (attempt #{attempt}, #{socket})") }
|
|
215
|
+
zmq_eagain_error_check(socket.send_string(@request_data), :socket_send_string)
|
|
216
|
+
logger.debug { sign_message("Waiting #{rcv_timeout}ms for response (attempt #{attempt}, #{socket})") }
|
|
217
|
+
zmq_eagain_error_check(socket.recv_string(@response_data = ""), :socket_recv_string)
|
|
218
|
+
logger.debug { sign_message("Response received (attempt #{attempt}, #{socket})") }
|
|
219
|
+
rescue ZmqEagainError
|
|
220
|
+
logger.debug { sign_message("Timed out waiting for response (attempt #{attempt}, #{socket})") }
|
|
221
|
+
raise RequestTimeout
|
|
222
|
+
ensure
|
|
223
|
+
logger.debug { sign_message("Closing Socket") }
|
|
224
|
+
zmq_error_check(socket.close, :socket_close) if socket
|
|
225
|
+
logger.debug { sign_message("Socket closed") }
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def server_lookup_attempts
|
|
229
|
+
@server_lookup_attempts ||= [ENV["PB_ZMQ_CLIENT_SERVER_LOOKUP_ATTEMPTS"].to_i, 5].max
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# The service we're attempting to connect to
|
|
233
|
+
#
|
|
234
|
+
def service
|
|
235
|
+
options[:service]
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# Alias for ::Protobuf::Rpc::ServiceDirectory.instance
|
|
239
|
+
def service_directory
|
|
240
|
+
::Protobuf::Rpc::ServiceDirectory.instance
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def snd_timeout
|
|
244
|
+
@snd_timeout ||= begin
|
|
245
|
+
case
|
|
246
|
+
when options[:timeout] then
|
|
247
|
+
options[:timeout]
|
|
248
|
+
when ENV.key?("PB_ZMQ_CLIENT_SND_TIMEOUT") then
|
|
249
|
+
ENV["PB_ZMQ_CLIENT_SND_TIMEOUT"].to_i
|
|
250
|
+
else
|
|
251
|
+
300_000 # 300 seconds
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def socket_to_available_server(socket)
|
|
257
|
+
check_available_response = ""
|
|
258
|
+
socket.setsockopt(::ZMQ::RCVTIMEO, check_available_rcv_timeout)
|
|
259
|
+
socket.setsockopt(::ZMQ::SNDTIMEO, check_available_snd_timeout)
|
|
260
|
+
zmq_recoverable_error_check(socket.send_string(::Protobuf::Rpc::Zmq::CHECK_AVAILABLE_MESSAGE), :socket_send_string)
|
|
261
|
+
zmq_recoverable_error_check(socket.recv_string(check_available_response), :socket_recv_string)
|
|
262
|
+
|
|
263
|
+
if check_available_response == ::Protobuf::Rpc::Zmq::NO_WORKERS_AVAILABLE
|
|
264
|
+
zmq_recoverable_error_check(socket.close, :socket_close)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
socket.setsockopt(::ZMQ::RCVTIMEO, -1)
|
|
268
|
+
socket.setsockopt(::ZMQ::SNDTIMEO, -1)
|
|
269
|
+
socket
|
|
270
|
+
rescue ZmqRecoverableError
|
|
271
|
+
return nil # couldn't make a connection and need to try again
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Return the ZMQ Context to use for this process.
|
|
275
|
+
# If the context does not exist, create it, then register
|
|
276
|
+
# an exit block to ensure the context is terminated correctly.
|
|
277
|
+
#
|
|
278
|
+
def zmq_context
|
|
279
|
+
self.class.zmq_context
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def zmq_eagain_error_check(return_code, source)
|
|
283
|
+
return if ::ZMQ::Util.resultcode_ok?(return_code || -1)
|
|
284
|
+
|
|
285
|
+
if ::ZMQ::Util.errno == ::ZMQ::EAGAIN
|
|
286
|
+
fail ZmqEagainError, <<-ERROR
|
|
287
|
+
Last ZMQ API call to #{source} failed with "#{::ZMQ::Util.error_string}".
|
|
288
|
+
|
|
289
|
+
#{caller(1).join($INPUT_RECORD_SEPARATOR)}
|
|
290
|
+
ERROR
|
|
291
|
+
else
|
|
292
|
+
fail <<-ERROR
|
|
293
|
+
Last ZMQ API call to #{source} failed with "#{::ZMQ::Util.error_string}".
|
|
294
|
+
|
|
295
|
+
#{caller(1).join($INPUT_RECORD_SEPARATOR)}
|
|
296
|
+
ERROR
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def zmq_error_check(return_code, source)
|
|
301
|
+
return if ::ZMQ::Util.resultcode_ok?(return_code || -1)
|
|
302
|
+
|
|
303
|
+
fail <<-ERROR
|
|
304
|
+
Last ZMQ API call to #{source} failed with "#{::ZMQ::Util.error_string}".
|
|
305
|
+
|
|
306
|
+
#{caller(1).join($INPUT_RECORD_SEPARATOR)}
|
|
307
|
+
ERROR
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def zmq_recoverable_error_check(return_code, source)
|
|
311
|
+
return if ::ZMQ::Util.resultcode_ok?(return_code || -1)
|
|
312
|
+
|
|
313
|
+
fail ZmqRecoverableError, <<-ERROR
|
|
314
|
+
Last ZMQ API call to #{source} failed with "#{::ZMQ::Util.error_string}".
|
|
315
|
+
|
|
316
|
+
#{caller(1).join($INPUT_RECORD_SEPARATOR)}
|
|
317
|
+
ERROR
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# This file is auto-generated. DO NOT EDIT!
|
|
5
|
+
#
|
|
6
|
+
require 'protobuf/message'
|
|
7
|
+
|
|
8
|
+
module Protobuf
|
|
9
|
+
module Rpc
|
|
10
|
+
module DynamicDiscovery
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# Enum Classes
|
|
14
|
+
#
|
|
15
|
+
class BeaconType < ::Protobuf::Enum
|
|
16
|
+
define :HEARTBEAT, 0
|
|
17
|
+
define :FLATLINE, 1
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# Message Classes
|
|
23
|
+
#
|
|
24
|
+
class Server < ::Protobuf::Message; end
|
|
25
|
+
class Beacon < ::Protobuf::Message; end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# Message Fields
|
|
30
|
+
#
|
|
31
|
+
class Server
|
|
32
|
+
optional :string, :uuid, 1
|
|
33
|
+
optional :string, :address, 2
|
|
34
|
+
optional :string, :port, 3
|
|
35
|
+
optional :int32, :ttl, 4
|
|
36
|
+
repeated :string, :services, 5
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class Beacon
|
|
40
|
+
optional ::Protobuf::Rpc::DynamicDiscovery::BeaconType, :beacon_type, 1
|
|
41
|
+
optional ::Protobuf::Rpc::DynamicDiscovery::Server, :server, 2
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module Protobuf
|
|
2
|
+
module Rpc
|
|
3
|
+
class Env < Hash
|
|
4
|
+
# Creates an accessor that simply sets and reads a key in the hash:
|
|
5
|
+
#
|
|
6
|
+
# class Config < Hash
|
|
7
|
+
# hash_accessor :app
|
|
8
|
+
# end
|
|
9
|
+
#
|
|
10
|
+
# config = Config.new
|
|
11
|
+
# config.app = Foo
|
|
12
|
+
# config[:app] #=> Foo
|
|
13
|
+
#
|
|
14
|
+
# config[:app] = Bar
|
|
15
|
+
# config.app #=> Bar
|
|
16
|
+
#
|
|
17
|
+
def self.hash_accessor(*names) #:nodoc:
|
|
18
|
+
names.each do |name|
|
|
19
|
+
name_str = name.to_s.freeze
|
|
20
|
+
|
|
21
|
+
define_method name do
|
|
22
|
+
self[name_str]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
define_method "#{name}=" do |value|
|
|
26
|
+
self[name_str] = value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
define_method "#{name}?" do
|
|
30
|
+
!self[name_str].nil?
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# TODO: Add extra info about the environment (i.e. variables) and other
|
|
36
|
+
# information that might be useful
|
|
37
|
+
hash_accessor :client_host,
|
|
38
|
+
:encoded_request,
|
|
39
|
+
:encoded_response,
|
|
40
|
+
:log_signature,
|
|
41
|
+
:method_name,
|
|
42
|
+
:request,
|
|
43
|
+
:request_type,
|
|
44
|
+
:response,
|
|
45
|
+
:response_type,
|
|
46
|
+
:rpc_method,
|
|
47
|
+
:rpc_service,
|
|
48
|
+
:service_name,
|
|
49
|
+
:worker_id
|
|
50
|
+
|
|
51
|
+
def initialize(options = {})
|
|
52
|
+
merge!(options)
|
|
53
|
+
|
|
54
|
+
self['worker_id'] = ::Thread.current.object_id.to_s(16)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'protobuf/rpc/rpc.pb'
|
|
2
|
+
|
|
3
|
+
module Protobuf
|
|
4
|
+
module Rpc
|
|
5
|
+
ClientError = Struct.new("ClientError", :code, :message)
|
|
6
|
+
|
|
7
|
+
# Base PbError class for client and server errors
|
|
8
|
+
class PbError < StandardError
|
|
9
|
+
attr_reader :error_type
|
|
10
|
+
|
|
11
|
+
def initialize(message = 'An unknown RpcError occurred', error_type = 'RPC_ERROR')
|
|
12
|
+
@error_type = error_type.is_a?(String) ? Socketrpc::ErrorReason.const_get(error_type) : error_type
|
|
13
|
+
super message
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def encode
|
|
17
|
+
to_response.encode
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def to_response
|
|
21
|
+
Socketrpc::Response.new(:error => message, :error_reason => error_type)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
require 'protobuf/rpc/error/server_error'
|
|
28
|
+
require 'protobuf/rpc/error/client_error'
|