protobuffy 3.1.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/.travis.yml +12 -0
- data/.yardopts +5 -0
- data/CHANGES.md +261 -0
- data/CONTRIBUTING.md +16 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +14 -0
- data/README.md +58 -0
- data/Rakefile +61 -0
- data/bin/protoc-gen-ruby +17 -0
- data/bin/rpc_server +4 -0
- data/examples/bin/reverse-client-http +4 -0
- data/examples/bin/reverse-client-socket +4 -0
- data/examples/bin/reverse-client-zmq +4 -0
- data/examples/config.ru +6 -0
- data/examples/definitions/example/reverse.proto +12 -0
- data/examples/lib/example/reverse-client.rb +23 -0
- data/examples/lib/example/reverse-service.rb +9 -0
- data/examples/lib/example/reverse.pb.rb +36 -0
- data/lib/protobuf.rb +106 -0
- data/lib/protobuf/cli.rb +249 -0
- data/lib/protobuf/code_generator.rb +41 -0
- data/lib/protobuf/decoder.rb +74 -0
- data/lib/protobuf/deprecator.rb +42 -0
- data/lib/protobuf/descriptors.rb +3 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +52 -0
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +249 -0
- data/lib/protobuf/encoder.rb +62 -0
- data/lib/protobuf/enum.rb +319 -0
- data/lib/protobuf/exceptions.rb +9 -0
- data/lib/protobuf/field.rb +74 -0
- data/lib/protobuf/field/base_field.rb +280 -0
- data/lib/protobuf/field/bool_field.rb +53 -0
- data/lib/protobuf/field/bytes_field.rb +81 -0
- data/lib/protobuf/field/double_field.rb +26 -0
- data/lib/protobuf/field/enum_field.rb +57 -0
- data/lib/protobuf/field/field_array.rb +86 -0
- data/lib/protobuf/field/fixed32_field.rb +25 -0
- data/lib/protobuf/field/fixed64_field.rb +29 -0
- data/lib/protobuf/field/float_field.rb +38 -0
- data/lib/protobuf/field/int32_field.rb +22 -0
- data/lib/protobuf/field/int64_field.rb +22 -0
- data/lib/protobuf/field/integer_field.rb +24 -0
- data/lib/protobuf/field/message_field.rb +66 -0
- data/lib/protobuf/field/sfixed32_field.rb +28 -0
- data/lib/protobuf/field/sfixed64_field.rb +29 -0
- data/lib/protobuf/field/signed_integer_field.rb +30 -0
- data/lib/protobuf/field/sint32_field.rb +22 -0
- data/lib/protobuf/field/sint64_field.rb +22 -0
- data/lib/protobuf/field/string_field.rb +35 -0
- data/lib/protobuf/field/uint32_field.rb +22 -0
- data/lib/protobuf/field/uint64_field.rb +22 -0
- data/lib/protobuf/field/varint_field.rb +68 -0
- data/lib/protobuf/generators/base.rb +71 -0
- data/lib/protobuf/generators/enum_generator.rb +42 -0
- data/lib/protobuf/generators/extension_generator.rb +28 -0
- data/lib/protobuf/generators/field_generator.rb +132 -0
- data/lib/protobuf/generators/file_generator.rb +140 -0
- data/lib/protobuf/generators/group_generator.rb +113 -0
- data/lib/protobuf/generators/message_generator.rb +99 -0
- data/lib/protobuf/generators/printable.rb +161 -0
- data/lib/protobuf/generators/service_generator.rb +27 -0
- data/lib/protobuf/http.rb +20 -0
- data/lib/protobuf/lifecycle.rb +46 -0
- data/lib/protobuf/logger.rb +86 -0
- data/lib/protobuf/message.rb +182 -0
- data/lib/protobuf/message/fields.rb +122 -0
- data/lib/protobuf/message/serialization.rb +84 -0
- data/lib/protobuf/optionable.rb +23 -0
- data/lib/protobuf/rpc/buffer.rb +79 -0
- data/lib/protobuf/rpc/client.rb +168 -0
- data/lib/protobuf/rpc/connector.rb +21 -0
- data/lib/protobuf/rpc/connectors/base.rb +54 -0
- data/lib/protobuf/rpc/connectors/common.rb +172 -0
- data/lib/protobuf/rpc/connectors/http.rb +90 -0
- data/lib/protobuf/rpc/connectors/socket.rb +73 -0
- data/lib/protobuf/rpc/connectors/zmq.rb +205 -0
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +47 -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 +53 -0
- data/lib/protobuf/rpc/server.rb +39 -0
- data/lib/protobuf/rpc/servers/http/server.rb +101 -0
- data/lib/protobuf/rpc/servers/http_runner.rb +34 -0
- data/lib/protobuf/rpc/servers/socket/server.rb +113 -0
- data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
- data/lib/protobuf/rpc/servers/socket_runner.rb +34 -0
- data/lib/protobuf/rpc/servers/zmq/broker.rb +155 -0
- data/lib/protobuf/rpc/servers/zmq/server.rb +313 -0
- data/lib/protobuf/rpc/servers/zmq/util.rb +47 -0
- data/lib/protobuf/rpc/servers/zmq/worker.rb +105 -0
- data/lib/protobuf/rpc/servers/zmq_runner.rb +51 -0
- data/lib/protobuf/rpc/service.rb +179 -0
- data/lib/protobuf/rpc/service_directory.rb +245 -0
- data/lib/protobuf/rpc/service_dispatcher.rb +46 -0
- data/lib/protobuf/rpc/service_filters.rb +273 -0
- data/lib/protobuf/rpc/stat.rb +148 -0
- data/lib/protobuf/socket.rb +22 -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/protobuffy.gemspec +37 -0
- data/spec/benchmark/tasks.rb +113 -0
- data/spec/bin/protoc-gen-ruby_spec.rb +18 -0
- data/spec/data/data.bin +3 -0
- data/spec/data/types.bin +0 -0
- data/spec/encoding/all_types_spec.rb +91 -0
- data/spec/encoding/extreme_values_spec.rb +0 -0
- data/spec/functional/socket_server_spec.rb +59 -0
- data/spec/functional/zmq_server_spec.rb +103 -0
- data/spec/lib/protobuf/cli_spec.rb +267 -0
- data/spec/lib/protobuf/code_generator_spec.rb +60 -0
- data/spec/lib/protobuf/enum_spec.rb +239 -0
- data/spec/lib/protobuf/field/int32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/string_field_spec.rb +46 -0
- data/spec/lib/protobuf/field_spec.rb +194 -0
- data/spec/lib/protobuf/generators/base_spec.rb +87 -0
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +68 -0
- data/spec/lib/protobuf/generators/extension_generator_spec.rb +43 -0
- data/spec/lib/protobuf/generators/field_generator_spec.rb +99 -0
- data/spec/lib/protobuf/generators/file_generator_spec.rb +29 -0
- data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
- data/spec/lib/protobuf/generators/service_generator_spec.rb +43 -0
- data/spec/lib/protobuf/lifecycle_spec.rb +89 -0
- data/spec/lib/protobuf/logger_spec.rb +136 -0
- data/spec/lib/protobuf/message_spec.rb +368 -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/connector_spec.rb +13 -0
- data/spec/lib/protobuf/rpc/connectors/http_spec.rb +61 -0
- data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +24 -0
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +129 -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/http/server_spec.rb +104 -0
- data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
- data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +41 -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 +295 -0
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +52 -0
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +484 -0
- data/spec/lib/protobuf/rpc/service_spec.rb +161 -0
- data/spec/lib/protobuf/rpc/stat_spec.rb +151 -0
- data/spec/lib/protobuf_spec.rb +78 -0
- data/spec/spec_helper.rb +57 -0
- data/spec/support/all.rb +7 -0
- data/spec/support/packed_field.rb +22 -0
- data/spec/support/server.rb +94 -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 +25 -0
- data/spec/support/test/defaults.proto +9 -0
- data/spec/support/test/enum.pb.rb +59 -0
- data/spec/support/test/enum.proto +34 -0
- data/spec/support/test/extended.pb.rb +22 -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 +543 -0
- data/spec/support/test/google_unittest.proto +713 -0
- data/spec/support/test/google_unittest_import.pb.rb +37 -0
- data/spec/support/test/google_unittest_import.proto +64 -0
- data/spec/support/test/google_unittest_import_public.pb.rb +8 -0
- data/spec/support/test/google_unittest_import_public.proto +38 -0
- data/spec/support/test/multi_field_extensions.pb.rb +56 -0
- data/spec/support/test/multi_field_extensions.proto +33 -0
- data/spec/support/test/resource.pb.rb +117 -0
- data/spec/support/test/resource.proto +94 -0
- data/spec/support/test/resource_service.rb +26 -0
- data/spec/support/test_app_file.rb +2 -0
- data/spec/support/tolerance_matcher.rb +40 -0
- metadata +367 -0
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'protobuf/rpc/connectors/base'
|
2
|
+
require 'cgi'
|
3
|
+
require 'faraday'
|
4
|
+
|
5
|
+
module Protobuf
|
6
|
+
module Rpc
|
7
|
+
module Connectors
|
8
|
+
class Http < Base
|
9
|
+
include Protobuf::Rpc::Connectors::Common
|
10
|
+
include Protobuf::Logger::LogMethods
|
11
|
+
|
12
|
+
def send_request
|
13
|
+
timeout_wrap do
|
14
|
+
setup_connection
|
15
|
+
post_init
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def log_signature
|
20
|
+
@_log_signature ||= "[http-client-#{self.class.name}]"
|
21
|
+
end
|
22
|
+
|
23
|
+
# private
|
24
|
+
|
25
|
+
def close_connection
|
26
|
+
log_debug { sign_message('Connector closed') }
|
27
|
+
end
|
28
|
+
|
29
|
+
# Method to determine error state, must be used with Connector api
|
30
|
+
def error?
|
31
|
+
log_debug { sign_message("Error state : #{@error}") }
|
32
|
+
if @error
|
33
|
+
true
|
34
|
+
else
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def host
|
40
|
+
'http://' + options[:host] + ':' + options[:port].to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
def base
|
44
|
+
options[:base] or ''
|
45
|
+
end
|
46
|
+
|
47
|
+
def client
|
48
|
+
@_client ||= Faraday.new(:url => host)
|
49
|
+
end
|
50
|
+
|
51
|
+
def send_data
|
52
|
+
rpc_request = ::Protobuf::Socketrpc::Request.decode(@request_data)
|
53
|
+
|
54
|
+
http_response = client.post do |http_request|
|
55
|
+
path_components = [''] + rpc_request[:service_name].split('::') + [rpc_request[:method_name]]
|
56
|
+
http_request.url base + path_components.map{ |x| CGI::escape(x) }.join('/')
|
57
|
+
http_request.headers['Content-Type'] = 'application/x-protobuf'
|
58
|
+
http_request.headers['X-Protobuf-Caller'] = rpc_request[:caller] || ''
|
59
|
+
http_request.body = rpc_request[:request_proto]
|
60
|
+
end
|
61
|
+
|
62
|
+
# Server returns protobuf response with no error
|
63
|
+
if http_response.status == 200 and http_response.headers['x-protobuf-error'].nil?
|
64
|
+
rpc_response = Protobuf::Socketrpc::Response.new(
|
65
|
+
:response_proto => http_response.body
|
66
|
+
)
|
67
|
+
# Server returns protobuf error
|
68
|
+
elsif http_response.status != 200 and not http_response.headers['x-protobuf-error'].nil?
|
69
|
+
rpc_response = Protobuf::Socketrpc::Response.new(
|
70
|
+
:response_proto => http_response.body,
|
71
|
+
:error => http_response.headers['x-protobuf-error'],
|
72
|
+
:error_reason => http_response.headers['x-protobuf-error-reason'].to_i
|
73
|
+
)
|
74
|
+
# Server didn't return a response or error
|
75
|
+
else
|
76
|
+
rpc_response = Protobuf::Socketrpc::Response.new(
|
77
|
+
:response_proto => http_response.body,
|
78
|
+
:error => "Bad response from the server.",
|
79
|
+
:error_reason => Protobuf::Socketrpc::ErrorReason::BAD_RESPONSE_PROTO
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
@response_data = rpc_response.encode()
|
84
|
+
|
85
|
+
parse_response
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'protobuf/rpc/connectors/base'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Rpc
|
5
|
+
module Connectors
|
6
|
+
class Socket < Base
|
7
|
+
include Protobuf::Rpc::Connectors::Common
|
8
|
+
include Protobuf::Logger::LogMethods
|
9
|
+
|
10
|
+
def send_request
|
11
|
+
timeout_wrap do
|
12
|
+
setup_connection
|
13
|
+
connect_to_rpc_server
|
14
|
+
post_init
|
15
|
+
read_response
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def log_signature
|
20
|
+
@_log_signature ||= "[client-#{self.class}]"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def close_connection
|
26
|
+
@socket.close
|
27
|
+
log_debug { sign_message('Connector closed') }
|
28
|
+
end
|
29
|
+
|
30
|
+
def connect_to_rpc_server
|
31
|
+
@socket = TCPSocket.new(options[:host], options[:port])
|
32
|
+
log_debug { sign_message("Connection established #{options[:host]}:#{options[:port]}") }
|
33
|
+
end
|
34
|
+
|
35
|
+
# Method to determine error state, must be used with Connector api
|
36
|
+
def error?
|
37
|
+
return true if @error
|
38
|
+
log_debug { sign_message("Error state : #{@socket.closed?}") }
|
39
|
+
@socket.closed?
|
40
|
+
end
|
41
|
+
|
42
|
+
def read_data
|
43
|
+
size_io = StringIO.new
|
44
|
+
|
45
|
+
until (size_reader = @socket.getc) == "-"
|
46
|
+
size_io << size_reader
|
47
|
+
end
|
48
|
+
str_size_io = size_io.string
|
49
|
+
|
50
|
+
"#{str_size_io}-#{@socket.read(str_size_io.to_i)}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def read_response
|
54
|
+
log_debug { sign_message("error? is #{error?}") }
|
55
|
+
return if error?
|
56
|
+
response_buffer = ::Protobuf::Rpc::Buffer.new(:read)
|
57
|
+
response_buffer << read_data
|
58
|
+
@response_data = response_buffer.data
|
59
|
+
parse_response if response_buffer.flushed?
|
60
|
+
end
|
61
|
+
|
62
|
+
def send_data
|
63
|
+
return if error?
|
64
|
+
request_buffer = ::Protobuf::Rpc::Buffer.new(:write)
|
65
|
+
request_buffer.set_data(@request_data)
|
66
|
+
@socket.write(request_buffer.write)
|
67
|
+
@socket.flush
|
68
|
+
log_debug { sign_message("write closed") }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'protobuf/rpc/connectors/base'
|
2
|
+
require 'protobuf/rpc/service_directory'
|
3
|
+
|
4
|
+
module Protobuf
|
5
|
+
module Rpc
|
6
|
+
module Connectors
|
7
|
+
class Zmq < Base
|
8
|
+
|
9
|
+
RequestTimeout = Class.new(RuntimeError)
|
10
|
+
|
11
|
+
##
|
12
|
+
# Included Modules
|
13
|
+
#
|
14
|
+
|
15
|
+
include Protobuf::Rpc::Connectors::Common
|
16
|
+
include Protobuf::Logger::LogMethods
|
17
|
+
|
18
|
+
##
|
19
|
+
# Class Constants
|
20
|
+
#
|
21
|
+
|
22
|
+
CLIENT_RETRIES = (ENV['PB_CLIENT_RETRIES'] || 3)
|
23
|
+
|
24
|
+
##
|
25
|
+
# Class Methods
|
26
|
+
#
|
27
|
+
def self.zmq_context
|
28
|
+
@zmq_contexts ||= Hash.new { |hash, key|
|
29
|
+
hash[key] = ZMQ::Context.new
|
30
|
+
}
|
31
|
+
|
32
|
+
@zmq_contexts[Process.pid]
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Instance methods
|
37
|
+
#
|
38
|
+
|
39
|
+
# Start the request/response cycle. We implement the Lazy Pirate
|
40
|
+
# req/reply reliability pattern as laid out in the ZMQ Guide, Chapter 4.
|
41
|
+
#
|
42
|
+
# @see http://zguide.zeromq.org/php:chapter4#Client-side-Reliability-Lazy-Pirate-Pattern
|
43
|
+
#
|
44
|
+
def send_request
|
45
|
+
setup_connection
|
46
|
+
send_request_with_lazy_pirate unless error?
|
47
|
+
end
|
48
|
+
|
49
|
+
def log_signature
|
50
|
+
@_log_signature ||= "[client-#{self.class}]"
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
##
|
56
|
+
# Private Instance methods
|
57
|
+
#
|
58
|
+
|
59
|
+
def close_connection
|
60
|
+
# The socket is automatically closed after every request.
|
61
|
+
end
|
62
|
+
|
63
|
+
# Create a socket connected to a server that can handle the current
|
64
|
+
# service. The LINGER is set to 0 so we can close immediately in
|
65
|
+
# the event of a timeout
|
66
|
+
def create_socket
|
67
|
+
socket = nil
|
68
|
+
|
69
|
+
begin
|
70
|
+
server_uri = lookup_server_uri
|
71
|
+
|
72
|
+
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
|
+
|
84
|
+
if check_available_response == ::Protobuf::Rpc::Zmq::NO_WORKERS_AVAILABLE
|
85
|
+
zmq_error_check(socket.close, :socket_close)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end while socket.try(:socket).nil?
|
89
|
+
|
90
|
+
socket
|
91
|
+
end
|
92
|
+
|
93
|
+
# Method to determine error state, must be used with Connector API.
|
94
|
+
#
|
95
|
+
def error?
|
96
|
+
!! @error
|
97
|
+
end
|
98
|
+
|
99
|
+
# Lookup a server uri for the requested service in the service
|
100
|
+
# directory. If the service directory is not running, default
|
101
|
+
# to the host and port in the options
|
102
|
+
#
|
103
|
+
def lookup_server_uri
|
104
|
+
50.times do
|
105
|
+
service_directory.all_listings_for(service).each do |listing|
|
106
|
+
host = listing.try(:address)
|
107
|
+
port = listing.try(:port)
|
108
|
+
return "tcp://#{host}:#{port}" if host_alive?(host)
|
109
|
+
end
|
110
|
+
|
111
|
+
host = options[:host]
|
112
|
+
port = options[:port]
|
113
|
+
return "tcp://#{host}:#{port}" if host_alive?(host)
|
114
|
+
|
115
|
+
sleep(1.0/10.0) # not sure why sleeping at all, but should be way less than 1 second
|
116
|
+
end
|
117
|
+
|
118
|
+
raise "Host not found for service #{service}"
|
119
|
+
end
|
120
|
+
|
121
|
+
def host_alive?(host)
|
122
|
+
return true unless ping_port_enabled?
|
123
|
+
|
124
|
+
socket = TCPSocket.new(host, ping_port.to_i)
|
125
|
+
|
126
|
+
true
|
127
|
+
rescue
|
128
|
+
false
|
129
|
+
ensure
|
130
|
+
socket.close rescue nil
|
131
|
+
end
|
132
|
+
|
133
|
+
# Trying a number of times, attempt to get a response from the server.
|
134
|
+
# If we haven't received a legitimate response in the CLIENT_RETRIES number
|
135
|
+
# of retries, fail the request.
|
136
|
+
#
|
137
|
+
def send_request_with_lazy_pirate
|
138
|
+
attempt = 0
|
139
|
+
timeout = options[:timeout].to_f
|
140
|
+
|
141
|
+
begin
|
142
|
+
attempt += 1
|
143
|
+
send_request_with_timeout(timeout, attempt)
|
144
|
+
parse_response
|
145
|
+
rescue RequestTimeout
|
146
|
+
retry if attempt < CLIENT_RETRIES
|
147
|
+
fail(:RPC_FAILED, "The server repeatedly failed to respond within #{timeout} seconds")
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def send_request_with_timeout(timeout, attempt = 0)
|
152
|
+
socket = create_socket
|
153
|
+
|
154
|
+
poller = ::ZMQ::Poller.new
|
155
|
+
poller.register_readable(socket)
|
156
|
+
|
157
|
+
log_debug { sign_message("Sending Request (attempt #{attempt}, #{socket})") }
|
158
|
+
zmq_error_check(socket.send_string(@request_data), :socket_send_string)
|
159
|
+
log_debug { sign_message("Waiting #{timeout} seconds for response (attempt #{attempt}, #{socket})") }
|
160
|
+
|
161
|
+
if poller.poll(timeout * 1000) == 1
|
162
|
+
zmq_error_check(socket.recv_string(@response_data = ""), :socket_recv_string)
|
163
|
+
log_debug { sign_message("Response received (attempt #{attempt}, #{socket})") }
|
164
|
+
else
|
165
|
+
log_debug { sign_message("Timed out waiting for response (attempt #{attempt}, #{socket})") }
|
166
|
+
raise RequestTimeout
|
167
|
+
end
|
168
|
+
ensure
|
169
|
+
log_debug { sign_message("Closing Socket") }
|
170
|
+
zmq_error_check(socket.close, :socket_close) if socket
|
171
|
+
log_debug { sign_message("Socket closed") }
|
172
|
+
end
|
173
|
+
|
174
|
+
# The service we're attempting to connect to
|
175
|
+
#
|
176
|
+
def service
|
177
|
+
options[:service]
|
178
|
+
end
|
179
|
+
|
180
|
+
# Alias for ::Protobuf::Rpc::ServiceDirectory.instance
|
181
|
+
def service_directory
|
182
|
+
::Protobuf::Rpc::ServiceDirectory.instance
|
183
|
+
end
|
184
|
+
|
185
|
+
# Return the ZMQ Context to use for this process.
|
186
|
+
# If the context does not exist, create it, then register
|
187
|
+
# an exit block to ensure the context is terminated correctly.
|
188
|
+
#
|
189
|
+
def zmq_context
|
190
|
+
self.class.zmq_context
|
191
|
+
end
|
192
|
+
|
193
|
+
def zmq_error_check(return_code, source)
|
194
|
+
unless ::ZMQ::Util.resultcode_ok?(return_code || -1)
|
195
|
+
raise <<-ERROR
|
196
|
+
Last ZMQ API call to #{source} failed with "#{::ZMQ::Util.error_string}".
|
197
|
+
|
198
|
+
#{caller(1).join($/)}
|
199
|
+
ERROR
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
##
|
2
|
+
# This file is auto-generated. DO NOT EDIT!
|
3
|
+
#
|
4
|
+
require 'protobuf/message'
|
5
|
+
|
6
|
+
module Protobuf
|
7
|
+
module Rpc
|
8
|
+
module DynamicDiscovery
|
9
|
+
|
10
|
+
##
|
11
|
+
# Enum Classes
|
12
|
+
#
|
13
|
+
class BeaconType < ::Protobuf::Enum
|
14
|
+
define :HEARTBEAT, 0
|
15
|
+
define :FLATLINE, 1
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
##
|
20
|
+
# Message Classes
|
21
|
+
#
|
22
|
+
class Server < ::Protobuf::Message; end
|
23
|
+
class Beacon < ::Protobuf::Message; end
|
24
|
+
|
25
|
+
|
26
|
+
##
|
27
|
+
# Message Fields
|
28
|
+
#
|
29
|
+
class Server
|
30
|
+
optional :string, :uuid, 1
|
31
|
+
optional :string, :address, 2
|
32
|
+
optional :string, :port, 3
|
33
|
+
optional :int32, :ttl, 4
|
34
|
+
repeated :string, :services, 5
|
35
|
+
end
|
36
|
+
|
37
|
+
class Beacon
|
38
|
+
optional ::Protobuf::Rpc::DynamicDiscovery::BeaconType, :beacon_type, 1
|
39
|
+
optional ::Protobuf::Rpc::DynamicDiscovery::Server, :server, 2
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
@@ -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
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
20
|
+
def #{name}
|
21
|
+
self['#{name}']
|
22
|
+
end
|
23
|
+
|
24
|
+
def #{name}=(value)
|
25
|
+
self['#{name}'] = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def #{name}?
|
29
|
+
! self['#{name}'].nil?
|
30
|
+
end
|
31
|
+
METHOD
|
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
|