protobuffy 3.6.0 → 4.0.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 +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +67 -0
- data/.rubocop_todo.yml +145 -0
- data/.travis.yml +25 -5
- data/CHANGES.md +55 -0
- data/CONTRIBUTING.md +1 -1
- data/LICENSE.txt +17 -9
- data/README.md +13 -12
- data/Rakefile +15 -11
- data/bin/protoc-gen-ruby +8 -3
- data/bin/rpc_server +1 -0
- data/examples/lib/example/reverse-client.rb +2 -2
- data/install-protobuf.sh +28 -0
- data/lib/protobuf.rb +57 -53
- data/lib/protobuf/cli.rb +94 -74
- data/lib/protobuf/code_generator.rb +60 -9
- data/lib/protobuf/decoder.rb +19 -65
- data/lib/protobuf/deprecation.rb +117 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +11 -1
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +55 -3
- data/lib/protobuf/encoder.rb +13 -53
- data/lib/protobuf/enum.rb +58 -63
- data/lib/protobuf/field.rb +4 -4
- data/lib/protobuf/field/base_field.rb +101 -173
- data/lib/protobuf/field/bool_field.rb +17 -11
- data/lib/protobuf/field/bytes_field.rb +21 -35
- data/lib/protobuf/field/double_field.rb +0 -1
- data/lib/protobuf/field/enum_field.rb +23 -22
- data/lib/protobuf/field/field_array.rb +5 -4
- data/lib/protobuf/field/fixed32_field.rb +1 -1
- data/lib/protobuf/field/fixed64_field.rb +0 -1
- data/lib/protobuf/field/float_field.rb +4 -1
- data/lib/protobuf/field/int32_field.rb +0 -1
- data/lib/protobuf/field/int64_field.rb +0 -1
- data/lib/protobuf/field/integer_field.rb +0 -1
- data/lib/protobuf/field/message_field.rb +13 -28
- data/lib/protobuf/field/sfixed32_field.rb +0 -1
- data/lib/protobuf/field/sfixed64_field.rb +0 -1
- data/lib/protobuf/field/signed_integer_field.rb +0 -1
- data/lib/protobuf/field/sint32_field.rb +0 -1
- data/lib/protobuf/field/sint64_field.rb +0 -1
- data/lib/protobuf/field/string_field.rb +2 -4
- data/lib/protobuf/field/uint32_field.rb +0 -1
- data/lib/protobuf/field/uint64_field.rb +0 -1
- data/lib/protobuf/field/varint_field.rb +30 -13
- data/lib/protobuf/generators/base.rb +30 -16
- data/lib/protobuf/generators/enum_generator.rb +6 -9
- data/lib/protobuf/generators/extension_generator.rb +1 -2
- data/lib/protobuf/generators/field_generator.rb +25 -13
- data/lib/protobuf/generators/file_generator.rb +157 -35
- data/lib/protobuf/generators/group_generator.rb +22 -17
- data/lib/protobuf/generators/message_generator.rb +13 -14
- data/lib/protobuf/generators/option_generator.rb +17 -0
- data/lib/protobuf/generators/printable.rb +12 -13
- data/lib/protobuf/generators/service_generator.rb +2 -3
- data/lib/protobuf/http.rb +2 -2
- data/lib/protobuf/lifecycle.rb +20 -33
- data/lib/protobuf/logging.rb +39 -0
- data/lib/protobuf/message.rb +114 -47
- data/lib/protobuf/message/fields.rb +170 -88
- data/lib/protobuf/message/serialization.rb +19 -18
- data/lib/protobuf/optionable.rb +53 -6
- data/lib/protobuf/rpc/buffer.rb +18 -19
- data/lib/protobuf/rpc/client.rb +22 -50
- data/lib/protobuf/rpc/connectors/base.rb +177 -12
- data/lib/protobuf/rpc/connectors/http.rb +14 -9
- data/lib/protobuf/rpc/connectors/ping.rb +89 -0
- data/lib/protobuf/rpc/connectors/socket.rb +13 -8
- data/lib/protobuf/rpc/connectors/zmq.rb +178 -73
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +4 -1
- data/lib/protobuf/rpc/env.rb +12 -12
- data/lib/protobuf/rpc/error.rb +3 -3
- data/lib/protobuf/rpc/error/client_error.rb +4 -4
- data/lib/protobuf/rpc/error/server_error.rb +9 -9
- data/lib/protobuf/rpc/middleware/exception_handler.rb +6 -2
- data/lib/protobuf/rpc/middleware/logger.rb +8 -4
- data/lib/protobuf/rpc/middleware/request_decoder.rb +17 -21
- data/lib/protobuf/rpc/middleware/response_encoder.rb +22 -27
- data/lib/protobuf/rpc/middleware/statsd.rb +3 -3
- data/lib/protobuf/rpc/rpc.pb.rb +4 -1
- data/lib/protobuf/rpc/server.rb +1 -1
- data/lib/protobuf/rpc/servers/http/server.rb +19 -17
- data/lib/protobuf/rpc/servers/socket/server.rb +78 -70
- data/lib/protobuf/rpc/servers/socket/worker.rb +4 -4
- data/lib/protobuf/rpc/servers/socket_runner.rb +27 -15
- data/lib/protobuf/rpc/servers/zmq/broker.rb +70 -31
- data/lib/protobuf/rpc/servers/zmq/server.rb +55 -47
- data/lib/protobuf/rpc/servers/zmq/util.rb +14 -13
- data/lib/protobuf/rpc/servers/zmq/worker.rb +16 -16
- data/lib/protobuf/rpc/servers/zmq_runner.rb +26 -7
- data/lib/protobuf/rpc/service.rb +21 -27
- data/lib/protobuf/rpc/service_directory.rb +43 -27
- data/lib/protobuf/rpc/service_dispatcher.rb +9 -10
- data/lib/protobuf/rpc/service_filters.rb +32 -55
- data/lib/protobuf/rpc/stat.rb +4 -8
- data/lib/protobuf/socket.rb +1 -2
- data/lib/protobuf/tasks/compile.rake +3 -4
- data/lib/protobuf/varint.rb +9 -0
- data/lib/protobuf/varint_pure.rb +13 -0
- data/lib/protobuf/version.rb +1 -1
- data/lib/protobuf/zmq.rb +2 -2
- data/proto/google/protobuf/descriptor.proto +190 -31
- data/protobuffy.gemspec +30 -17
- data/spec/benchmark/tasks.rb +27 -19
- data/spec/bin/protoc-gen-ruby_spec.rb +11 -6
- data/spec/encoding/all_types_spec.rb +96 -84
- data/spec/encoding/extreme_values_spec.rb +0 -0
- data/spec/functional/class_inheritance_spec.rb +52 -0
- data/spec/functional/code_generator_spec.rb +38 -0
- data/spec/functional/socket_server_spec.rb +15 -15
- data/spec/functional/zmq_server_spec.rb +29 -27
- data/spec/lib/protobuf/cli_spec.rb +82 -67
- data/spec/lib/protobuf/code_generator_spec.rb +37 -10
- data/spec/lib/protobuf/enum_spec.rb +77 -46
- data/spec/lib/protobuf/field/bool_field_spec.rb +91 -0
- data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/enum_field_spec.rb +26 -0
- data/spec/lib/protobuf/field/field_array_spec.rb +69 -0
- data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/float_field_spec.rb +90 -0
- data/spec/lib/protobuf/field/int32_field_spec.rb +114 -1
- data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/message_field_spec.rb +132 -0
- data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/string_field_spec.rb +44 -11
- data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field_spec.rb +4 -6
- data/spec/lib/protobuf/generators/base_spec.rb +80 -13
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +35 -21
- data/spec/lib/protobuf/generators/extension_generator_spec.rb +12 -13
- data/spec/lib/protobuf/generators/field_generator_spec.rb +73 -21
- data/spec/lib/protobuf/generators/file_generator_spec.rb +89 -6
- data/spec/lib/protobuf/generators/service_generator_spec.rb +25 -13
- data/spec/lib/protobuf/lifecycle_spec.rb +25 -20
- data/spec/lib/protobuf/message_spec.rb +578 -79
- data/spec/lib/protobuf/optionable_spec.rb +202 -26
- data/spec/lib/protobuf/rpc/client_spec.rb +16 -16
- data/spec/lib/protobuf/rpc/connectors/base_spec.rb +167 -13
- data/spec/lib/protobuf/rpc/connectors/connector_spec.rb +4 -5
- data/spec/lib/protobuf/rpc/connectors/http_spec.rb +13 -11
- data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +69 -0
- data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +6 -7
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +35 -52
- data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +10 -10
- data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +11 -11
- data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +23 -23
- data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +11 -11
- data/spec/lib/protobuf/rpc/middleware/statsd_spec.rb +6 -6
- data/spec/lib/protobuf/rpc/servers/http/server_spec.rb +47 -44
- data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +6 -6
- data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +12 -10
- data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +11 -11
- data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +7 -7
- data/spec/lib/protobuf/rpc/service_directory_spec.rb +47 -49
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +8 -25
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +102 -69
- data/spec/lib/protobuf/rpc/service_spec.rb +37 -36
- data/spec/lib/protobuf/rpc/stat_spec.rb +7 -9
- data/spec/lib/protobuf/varint_spec.rb +29 -0
- data/spec/lib/protobuf_spec.rb +55 -28
- data/spec/spec_helper.rb +12 -27
- data/spec/support/all.rb +0 -1
- data/spec/support/packed_field.rb +4 -3
- data/spec/support/{test → protos}/all_types.data.bin +0 -0
- data/spec/support/{test → protos}/all_types.data.txt +0 -0
- data/spec/support/{test → protos}/enum.pb.rb +8 -4
- data/spec/support/{test → protos}/enum.proto +4 -1
- data/spec/support/{test → protos}/extreme_values.data.bin +0 -0
- data/spec/support/protos/google_unittest.bin +0 -0
- data/spec/support/protos/google_unittest.pb.rb +798 -0
- data/spec/support/{test → protos}/google_unittest.proto +237 -66
- data/spec/support/protos/google_unittest_custom_options.bin +0 -0
- data/spec/support/protos/google_unittest_custom_options.pb.rb +268 -0
- data/spec/support/protos/google_unittest_custom_options.proto +424 -0
- data/spec/support/protos/google_unittest_import.pb.rb +55 -0
- data/spec/support/{test → protos}/google_unittest_import.proto +19 -10
- data/spec/support/protos/google_unittest_import_public.pb.rb +31 -0
- data/spec/support/{test → protos}/google_unittest_import_public.proto +8 -5
- data/spec/support/{test → protos}/multi_field_extensions.pb.rb +5 -2
- data/spec/support/{test → protos}/multi_field_extensions.proto +2 -0
- data/spec/support/{test → protos}/resource.pb.rb +47 -11
- data/spec/support/{test → protos}/resource.proto +24 -1
- data/spec/support/resource_service.rb +23 -0
- data/spec/support/server.rb +32 -61
- metadata +119 -59
- data/lib/protobuf/deprecator.rb +0 -42
- data/lib/protobuf/logger.rb +0 -93
- data/lib/protobuf/rpc/connector.rb +0 -21
- data/lib/protobuf/rpc/connectors/common.rb +0 -172
- data/spec/data/data.bin +0 -3
- data/spec/data/types.bin +0 -0
- data/spec/lib/protobuf/logger_spec.rb +0 -145
- data/spec/lib/protobuf/rpc/connector_spec.rb +0 -26
- data/spec/lib/protobuf/rpc/connectors/common_spec.rb +0 -170
- data/spec/support/test/defaults.pb.rb +0 -25
- data/spec/support/test/defaults.proto +0 -9
- data/spec/support/test/extended.pb.rb +0 -22
- data/spec/support/test/extended.proto +0 -10
- data/spec/support/test/google_unittest.pb.rb +0 -543
- data/spec/support/test/google_unittest_import.pb.rb +0 -37
- data/spec/support/test/google_unittest_import_public.pb.rb +0 -8
- data/spec/support/test/resource_service.rb +0 -26
- data/spec/support/tolerance_matcher.rb +0 -40
@@ -4,8 +4,7 @@ module Protobuf
|
|
4
4
|
module Rpc
|
5
5
|
module Connectors
|
6
6
|
class Socket < Base
|
7
|
-
include Protobuf::
|
8
|
-
include Protobuf::Logger::LogMethods
|
7
|
+
include Protobuf::Logging
|
9
8
|
|
10
9
|
def send_request
|
11
10
|
timeout_wrap do
|
@@ -24,21 +23,27 @@ module Protobuf
|
|
24
23
|
|
25
24
|
def close_connection
|
26
25
|
@socket.close
|
27
|
-
|
26
|
+
logger.debug { sign_message('Connector closed') }
|
28
27
|
end
|
29
28
|
|
30
29
|
def connect_to_rpc_server
|
31
|
-
@socket
|
32
|
-
|
30
|
+
@socket ||= TCPSocket.new(options[:host], options[:port])
|
31
|
+
logger.debug { sign_message("Connection established #{options[:host]}:#{options[:port]}") }
|
33
32
|
end
|
34
33
|
|
35
34
|
# Method to determine error state, must be used with Connector api
|
36
35
|
def error?
|
37
36
|
return true if @error
|
38
|
-
|
37
|
+
logger.debug { sign_message("Error state : #{@socket.closed?}") }
|
39
38
|
@socket.closed?
|
40
39
|
end
|
41
40
|
|
41
|
+
def post_init
|
42
|
+
send_data unless error?
|
43
|
+
rescue => e
|
44
|
+
failure(:RPC_ERROR, "Connection error: #{e.message}")
|
45
|
+
end
|
46
|
+
|
42
47
|
def read_data
|
43
48
|
size_io = StringIO.new
|
44
49
|
|
@@ -51,7 +56,7 @@ module Protobuf
|
|
51
56
|
end
|
52
57
|
|
53
58
|
def read_response
|
54
|
-
|
59
|
+
logger.debug { sign_message("error? is #{error?}") }
|
55
60
|
return if error?
|
56
61
|
response_buffer = ::Protobuf::Rpc::Buffer.new(:read)
|
57
62
|
response_buffer << read_data
|
@@ -65,7 +70,7 @@ module Protobuf
|
|
65
70
|
request_buffer.set_data(@request_data)
|
66
71
|
@socket.write(request_buffer.write)
|
67
72
|
@socket.flush
|
68
|
-
|
73
|
+
logger.debug { sign_message("write closed") }
|
69
74
|
end
|
70
75
|
end
|
71
76
|
end
|
@@ -1,33 +1,37 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "thread_safe"
|
2
|
+
require "protobuf/rpc/connectors/base"
|
3
|
+
require "protobuf/rpc/connectors/ping"
|
4
|
+
require "protobuf/rpc/service_directory"
|
3
5
|
|
4
6
|
module Protobuf
|
5
7
|
module Rpc
|
6
8
|
module Connectors
|
7
9
|
class Zmq < Base
|
8
|
-
|
9
10
|
RequestTimeout = Class.new(RuntimeError)
|
11
|
+
ZmqRecoverableError = Class.new(RuntimeError)
|
12
|
+
ZmqEagainError = Class.new(RuntimeError)
|
10
13
|
|
11
14
|
##
|
12
15
|
# Included Modules
|
13
16
|
#
|
14
|
-
|
15
|
-
include Protobuf::Rpc::Connectors::Common
|
16
|
-
include Protobuf::Logger::LogMethods
|
17
|
+
include Protobuf::Logging
|
17
18
|
|
18
19
|
##
|
19
20
|
# Class Constants
|
20
21
|
#
|
21
|
-
|
22
22
|
CLIENT_RETRIES = (ENV['PB_CLIENT_RETRIES'] || 3)
|
23
23
|
|
24
24
|
##
|
25
25
|
# Class Methods
|
26
26
|
#
|
27
|
+
def self.ping_port_responses
|
28
|
+
@ping_port_responses ||= ::ThreadSafe::Cache.new
|
29
|
+
end
|
30
|
+
|
27
31
|
def self.zmq_context
|
28
|
-
@zmq_contexts ||= Hash.new
|
32
|
+
@zmq_contexts ||= Hash.new do |hash, key|
|
29
33
|
hash[key] = ZMQ::Context.new
|
30
|
-
|
34
|
+
end
|
31
35
|
|
32
36
|
@zmq_contexts[Process.pid]
|
33
37
|
end
|
@@ -35,6 +39,9 @@ module Protobuf
|
|
35
39
|
##
|
36
40
|
# Instance methods
|
37
41
|
#
|
42
|
+
def log_signature
|
43
|
+
@_log_signature ||= "[client-#{self.class}]"
|
44
|
+
end
|
38
45
|
|
39
46
|
# Start the request/response cycle. We implement the Lazy Pirate
|
40
47
|
# req/reply reliability pattern as laid out in the ZMQ Guide, Chapter 4.
|
@@ -46,15 +53,32 @@ module Protobuf
|
|
46
53
|
send_request_with_lazy_pirate unless error?
|
47
54
|
end
|
48
55
|
|
49
|
-
def log_signature
|
50
|
-
@_log_signature ||= "[client-#{self.class}]"
|
51
|
-
end
|
52
|
-
|
53
56
|
private
|
54
57
|
|
55
58
|
##
|
56
59
|
# Private Instance methods
|
57
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
|
58
82
|
|
59
83
|
def close_connection
|
60
84
|
# The socket is automatically closed after every request.
|
@@ -64,26 +88,14 @@ module Protobuf
|
|
64
88
|
# service. The LINGER is set to 0 so we can close immediately in
|
65
89
|
# the event of a timeout
|
66
90
|
def create_socket
|
67
|
-
socket = nil
|
68
|
-
|
69
91
|
begin
|
70
|
-
server_uri = lookup_server_uri
|
71
|
-
|
72
92
|
socket = zmq_context.socket(::ZMQ::REQ)
|
73
|
-
socket.setsockopt(::ZMQ::LINGER, 0)
|
74
|
-
|
75
|
-
log_debug { sign_message("Establishing connection: #{server_uri}") }
|
76
|
-
zmq_error_check(socket.connect(server_uri), :socket_connect)
|
77
|
-
log_debug { sign_message("Connection established to #{server_uri}") }
|
78
|
-
|
79
|
-
if first_alive_load_balance?
|
80
|
-
check_available_response = ""
|
81
|
-
zmq_error_check(socket.send_string(::Protobuf::Rpc::Zmq::CHECK_AVAILABLE_MESSAGE), :socket_send_string)
|
82
|
-
zmq_error_check(socket.recv_string(check_available_response), :socket_recv_string)
|
83
93
|
|
84
|
-
|
85
|
-
|
86
|
-
|
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?
|
87
99
|
end
|
88
100
|
end while socket.try(:socket).nil?
|
89
101
|
|
@@ -96,38 +108,73 @@ module Protobuf
|
|
96
108
|
!! @error
|
97
109
|
end
|
98
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
|
+
|
99
132
|
# Lookup a server uri for the requested service in the service
|
100
133
|
# directory. If the service directory is not running, default
|
101
134
|
# to the host and port in the options
|
102
135
|
#
|
103
136
|
def lookup_server_uri
|
104
|
-
|
105
|
-
service_directory.all_listings_for(service).
|
106
|
-
|
107
|
-
|
108
|
-
|
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}"
|
109
147
|
end
|
110
148
|
|
111
149
|
host = options[:host]
|
112
150
|
port = options[:port]
|
113
|
-
return "tcp://#{host}:#{port}" if host_alive?(host)
|
114
151
|
|
115
|
-
|
152
|
+
if host_alive?(host)
|
153
|
+
@stats.server = [port, host]
|
154
|
+
return "tcp://#{host}:#{port}"
|
155
|
+
end
|
156
|
+
|
157
|
+
sleep(1.0 / 100.0)
|
116
158
|
end
|
117
159
|
|
118
|
-
|
160
|
+
fail "Host not found for service #{service}"
|
119
161
|
end
|
120
162
|
|
121
|
-
def
|
122
|
-
|
123
|
-
|
124
|
-
socket = TCPSocket.new(host, ping_port.to_i)
|
163
|
+
def ping_port_open?(host)
|
164
|
+
Ping.new(host, ping_port.to_i).online?
|
165
|
+
end
|
125
166
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
167
|
+
def rcv_timeout
|
168
|
+
@rcv_timeout ||= begin
|
169
|
+
case
|
170
|
+
when options[:timeout] then
|
171
|
+
options[:timeout]
|
172
|
+
when ENV.key?("PB_ZMQ_CLIENT_RCV_TIMEOUT") then
|
173
|
+
ENV["PB_ZMQ_CLIENT_RCV_TIMEOUT"].to_i
|
174
|
+
else
|
175
|
+
300_000 # 300 seconds
|
176
|
+
end
|
177
|
+
end
|
131
178
|
end
|
132
179
|
|
133
180
|
# Trying a number of times, attempt to get a response from the server.
|
@@ -136,39 +183,38 @@ module Protobuf
|
|
136
183
|
#
|
137
184
|
def send_request_with_lazy_pirate
|
138
185
|
attempt = 0
|
139
|
-
timeout = options[:timeout].to_f
|
140
186
|
|
141
187
|
begin
|
142
188
|
attempt += 1
|
143
|
-
send_request_with_timeout(
|
189
|
+
send_request_with_timeout(attempt)
|
144
190
|
parse_response
|
145
191
|
rescue RequestTimeout
|
146
192
|
retry if attempt < CLIENT_RETRIES
|
147
|
-
|
193
|
+
failure(:RPC_FAILED, "The server repeatedly failed to respond within #{timeout} seconds")
|
148
194
|
end
|
149
195
|
end
|
150
196
|
|
151
|
-
def send_request_with_timeout(
|
197
|
+
def send_request_with_timeout(attempt = 0)
|
152
198
|
socket = create_socket
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
else
|
165
|
-
log_debug { sign_message("Timed out waiting for response (attempt #{attempt}, #{socket})") }
|
166
|
-
raise RequestTimeout
|
167
|
-
end
|
199
|
+
socket.setsockopt(::ZMQ::RCVTIMEO, rcv_timeout)
|
200
|
+
socket.setsockopt(::ZMQ::SNDTIMEO, snd_timeout)
|
201
|
+
|
202
|
+
logger.debug { sign_message("Sending Request (attempt #{attempt}, #{socket})") }
|
203
|
+
zmq_eagain_error_check(socket.send_string(@request_data), :socket_send_string)
|
204
|
+
logger.debug { sign_message("Waiting #{rcv_timeout}ms for response (attempt #{attempt}, #{socket})") }
|
205
|
+
zmq_eagain_error_check(socket.recv_string(@response_data = ""), :socket_recv_string)
|
206
|
+
logger.debug { sign_message("Response received (attempt #{attempt}, #{socket})") }
|
207
|
+
rescue ZmqEagainError
|
208
|
+
logger.debug { sign_message("Timed out waiting for response (attempt #{attempt}, #{socket})") }
|
209
|
+
raise RequestTimeout
|
168
210
|
ensure
|
169
|
-
|
211
|
+
logger.debug { sign_message("Closing Socket") }
|
170
212
|
zmq_error_check(socket.close, :socket_close) if socket
|
171
|
-
|
213
|
+
logger.debug { sign_message("Socket closed") }
|
214
|
+
end
|
215
|
+
|
216
|
+
def server_lookup_attempts
|
217
|
+
@server_lookup_attempts ||= [ENV["PB_ZMQ_CLIENT_SERVER_LOOKUP_ATTEMPTS"].to_i, 5].max
|
172
218
|
end
|
173
219
|
|
174
220
|
# The service we're attempting to connect to
|
@@ -179,7 +225,38 @@ module Protobuf
|
|
179
225
|
|
180
226
|
# Alias for ::Protobuf::Rpc::ServiceDirectory.instance
|
181
227
|
def service_directory
|
182
|
-
::Protobuf::Rpc
|
228
|
+
::Protobuf::Rpc.service_directory
|
229
|
+
end
|
230
|
+
|
231
|
+
def snd_timeout
|
232
|
+
@snd_timeout ||= begin
|
233
|
+
case
|
234
|
+
when options[:timeout] then
|
235
|
+
options[:timeout]
|
236
|
+
when ENV.key?("PB_ZMQ_CLIENT_SND_TIMEOUT") then
|
237
|
+
ENV["PB_ZMQ_CLIENT_SND_TIMEOUT"].to_i
|
238
|
+
else
|
239
|
+
300_000 # 300 seconds
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def socket_to_available_server(socket)
|
245
|
+
check_available_response = ""
|
246
|
+
socket.setsockopt(::ZMQ::RCVTIMEO, check_available_rcv_timeout)
|
247
|
+
socket.setsockopt(::ZMQ::SNDTIMEO, check_available_snd_timeout)
|
248
|
+
zmq_recoverable_error_check(socket.send_string(::Protobuf::Rpc::Zmq::CHECK_AVAILABLE_MESSAGE), :socket_send_string)
|
249
|
+
zmq_recoverable_error_check(socket.recv_string(check_available_response), :socket_recv_string)
|
250
|
+
|
251
|
+
if check_available_response == ::Protobuf::Rpc::Zmq::NO_WORKERS_AVAILABLE
|
252
|
+
zmq_recoverable_error_check(socket.close, :socket_close)
|
253
|
+
end
|
254
|
+
|
255
|
+
socket.setsockopt(::ZMQ::RCVTIMEO, -1)
|
256
|
+
socket.setsockopt(::ZMQ::SNDTIMEO, -1)
|
257
|
+
socket
|
258
|
+
rescue ZmqRecoverableError
|
259
|
+
return nil # couldn't make a connection and need to try again
|
183
260
|
end
|
184
261
|
|
185
262
|
# Return the ZMQ Context to use for this process.
|
@@ -190,15 +267,43 @@ module Protobuf
|
|
190
267
|
self.class.zmq_context
|
191
268
|
end
|
192
269
|
|
193
|
-
def
|
194
|
-
|
195
|
-
|
270
|
+
def zmq_eagain_error_check(return_code, source)
|
271
|
+
return if ::ZMQ::Util.resultcode_ok?(return_code || -1)
|
272
|
+
|
273
|
+
if ::ZMQ::Util.errno == ::ZMQ::EAGAIN # rubocop:disable Style/GuardClause
|
274
|
+
fail ZmqEagainError, <<-ERROR
|
275
|
+
Last ZMQ API call to #{source} failed with "#{::ZMQ::Util.error_string}".
|
276
|
+
|
277
|
+
#{caller(1).join($INPUT_RECORD_SEPARATOR)}
|
278
|
+
ERROR
|
279
|
+
else
|
280
|
+
fail <<-ERROR
|
196
281
|
Last ZMQ API call to #{source} failed with "#{::ZMQ::Util.error_string}".
|
197
282
|
|
198
|
-
#{caller(1).join(
|
283
|
+
#{caller(1).join($INPUT_RECORD_SEPARATOR)}
|
199
284
|
ERROR
|
200
285
|
end
|
201
286
|
end
|
287
|
+
|
288
|
+
def zmq_error_check(return_code, source)
|
289
|
+
return if ::ZMQ::Util.resultcode_ok?(return_code || -1)
|
290
|
+
|
291
|
+
fail <<-ERROR
|
292
|
+
Last ZMQ API call to #{source} failed with "#{::ZMQ::Util.error_string}".
|
293
|
+
|
294
|
+
#{caller(1).join($INPUT_RECORD_SEPARATOR)}
|
295
|
+
ERROR
|
296
|
+
end
|
297
|
+
|
298
|
+
def zmq_recoverable_error_check(return_code, source)
|
299
|
+
return if ::ZMQ::Util.resultcode_ok?(return_code || -1)
|
300
|
+
|
301
|
+
fail ZmqRecoverableError, <<-ERROR
|
302
|
+
Last ZMQ API call to #{source} failed with "#{::ZMQ::Util.error_string}".
|
303
|
+
|
304
|
+
#{caller(1).join($INPUT_RECORD_SEPARATOR)}
|
305
|
+
ERROR
|
306
|
+
end
|
202
307
|
end
|
203
308
|
end
|
204
309
|
end
|
@@ -1,11 +1,14 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
##
|
2
4
|
# This file is auto-generated. DO NOT EDIT!
|
3
5
|
#
|
4
|
-
require 'protobuf
|
6
|
+
require 'protobuf'
|
5
7
|
|
6
8
|
module Protobuf
|
7
9
|
module Rpc
|
8
10
|
module DynamicDiscovery
|
11
|
+
::Protobuf::Optionable.inject(self) { ::Google::Protobuf::FileOptions }
|
9
12
|
|
10
13
|
##
|
11
14
|
# Enum Classes
|
data/lib/protobuf/rpc/env.rb
CHANGED
@@ -16,19 +16,19 @@ module Protobuf
|
|
16
16
|
#
|
17
17
|
def self.hash_accessor(*names) #:nodoc:
|
18
18
|
names.each do |name|
|
19
|
-
|
20
|
-
def #{name}
|
21
|
-
self['#{name}']
|
22
|
-
end
|
19
|
+
name_str = name.to_s.freeze
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
define_method name do
|
22
|
+
self[name_str]
|
23
|
+
end
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -49,7 +49,7 @@ module Protobuf
|
|
49
49
|
:service_name,
|
50
50
|
:worker_id
|
51
51
|
|
52
|
-
def initialize(options={})
|
52
|
+
def initialize(options = {})
|
53
53
|
merge!(options)
|
54
54
|
|
55
55
|
self['worker_id'] = ::Thread.current.object_id.to_s(16)
|