protobuf-cucumber 3.10.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rubocop.yml +70 -0
- data/.rubocop_todo.yml +145 -0
- data/.travis.yml +40 -0
- data/.yardopts +5 -0
- data/CHANGES.md +344 -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 +22 -0
- data/bin/rpc_server +5 -0
- data/install-protobuf.sh +28 -0
- data/lib/protobuf.rb +129 -0
- data/lib/protobuf/cli.rb +257 -0
- data/lib/protobuf/code_generator.rb +120 -0
- data/lib/protobuf/decoder.rb +28 -0
- data/lib/protobuf/deprecation.rb +117 -0
- data/lib/protobuf/descriptors.rb +3 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +62 -0
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +301 -0
- data/lib/protobuf/encoder.rb +11 -0
- data/lib/protobuf/enum.rb +365 -0
- data/lib/protobuf/exceptions.rb +9 -0
- data/lib/protobuf/field.rb +74 -0
- data/lib/protobuf/field/base_field.rb +380 -0
- data/lib/protobuf/field/base_field_object_definitions.rb +504 -0
- data/lib/protobuf/field/bool_field.rb +64 -0
- data/lib/protobuf/field/bytes_field.rb +78 -0
- data/lib/protobuf/field/double_field.rb +25 -0
- data/lib/protobuf/field/enum_field.rb +61 -0
- data/lib/protobuf/field/field_array.rb +104 -0
- data/lib/protobuf/field/field_hash.rb +122 -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 +43 -0
- data/lib/protobuf/field/int32_field.rb +21 -0
- data/lib/protobuf/field/int64_field.rb +34 -0
- data/lib/protobuf/field/integer_field.rb +23 -0
- data/lib/protobuf/field/message_field.rb +51 -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 +51 -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 +77 -0
- data/lib/protobuf/generators/base.rb +85 -0
- data/lib/protobuf/generators/enum_generator.rb +39 -0
- data/lib/protobuf/generators/extension_generator.rb +27 -0
- data/lib/protobuf/generators/field_generator.rb +193 -0
- data/lib/protobuf/generators/file_generator.rb +262 -0
- data/lib/protobuf/generators/group_generator.rb +122 -0
- data/lib/protobuf/generators/message_generator.rb +104 -0
- data/lib/protobuf/generators/option_generator.rb +17 -0
- data/lib/protobuf/generators/printable.rb +160 -0
- data/lib/protobuf/generators/service_generator.rb +50 -0
- data/lib/protobuf/lifecycle.rb +33 -0
- data/lib/protobuf/logging.rb +39 -0
- data/lib/protobuf/message.rb +260 -0
- data/lib/protobuf/message/fields.rb +233 -0
- data/lib/protobuf/message/serialization.rb +85 -0
- data/lib/protobuf/optionable.rb +70 -0
- data/lib/protobuf/rpc/buffer.rb +78 -0
- data/lib/protobuf/rpc/client.rb +140 -0
- data/lib/protobuf/rpc/connectors/base.rb +221 -0
- data/lib/protobuf/rpc/connectors/ping.rb +89 -0
- data/lib/protobuf/rpc/connectors/socket.rb +78 -0
- data/lib/protobuf/rpc/connectors/zmq.rb +319 -0
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +50 -0
- data/lib/protobuf/rpc/env.rb +60 -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 +40 -0
- data/lib/protobuf/rpc/middleware/logger.rb +95 -0
- data/lib/protobuf/rpc/middleware/request_decoder.rb +79 -0
- data/lib/protobuf/rpc/middleware/response_encoder.rb +83 -0
- data/lib/protobuf/rpc/middleware/runner.rb +18 -0
- data/lib/protobuf/rpc/rpc.pb.rb +64 -0
- data/lib/protobuf/rpc/rpc_method.rb +16 -0
- data/lib/protobuf/rpc/server.rb +39 -0
- data/lib/protobuf/rpc/servers/socket/server.rb +121 -0
- data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
- data/lib/protobuf/rpc/servers/socket_runner.rb +46 -0
- data/lib/protobuf/rpc/servers/zmq/broker.rb +194 -0
- data/lib/protobuf/rpc/servers/zmq/server.rb +321 -0
- data/lib/protobuf/rpc/servers/zmq/util.rb +48 -0
- data/lib/protobuf/rpc/servers/zmq/worker.rb +105 -0
- data/lib/protobuf/rpc/servers/zmq_runner.rb +70 -0
- data/lib/protobuf/rpc/service.rb +172 -0
- data/lib/protobuf/rpc/service_directory.rb +261 -0
- data/lib/protobuf/rpc/service_dispatcher.rb +45 -0
- data/lib/protobuf/rpc/service_filters.rb +250 -0
- data/lib/protobuf/rpc/stat.rb +119 -0
- data/lib/protobuf/socket.rb +21 -0
- data/lib/protobuf/tasks.rb +1 -0
- data/lib/protobuf/tasks/compile.rake +80 -0
- data/lib/protobuf/varint.rb +20 -0
- data/lib/protobuf/varint_pure.rb +31 -0
- data/lib/protobuf/version.rb +3 -0
- data/lib/protobuf/wire_type.rb +10 -0
- data/lib/protobuf/zmq.rb +21 -0
- data/profile.html +5103 -0
- data/proto/dynamic_discovery.proto +44 -0
- data/proto/google/protobuf/compiler/plugin.proto +147 -0
- data/proto/google/protobuf/descriptor.proto +779 -0
- data/proto/rpc.proto +69 -0
- data/protobuf-cucumber.gemspec +57 -0
- data/spec/benchmark/tasks.rb +143 -0
- data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
- data/spec/encoding/all_types_spec.rb +103 -0
- 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 +58 -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 +317 -0
- data/spec/lib/protobuf/code_generator_spec.rb +87 -0
- data/spec/lib/protobuf/enum_spec.rb +307 -0
- 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 +44 -0
- data/spec/lib/protobuf/field/field_array_spec.rb +105 -0
- data/spec/lib/protobuf/field/field_hash_spec.rb +168 -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 +120 -0
- 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 +79 -0
- 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 +192 -0
- data/spec/lib/protobuf/generators/base_spec.rb +154 -0
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +82 -0
- data/spec/lib/protobuf/generators/extension_generator_spec.rb +42 -0
- data/spec/lib/protobuf/generators/field_generator_spec.rb +197 -0
- data/spec/lib/protobuf/generators/file_generator_spec.rb +119 -0
- data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
- data/spec/lib/protobuf/generators/service_generator_spec.rb +99 -0
- data/spec/lib/protobuf/lifecycle_spec.rb +94 -0
- data/spec/lib/protobuf/message_spec.rb +944 -0
- data/spec/lib/protobuf/optionable_spec.rb +265 -0
- data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
- data/spec/lib/protobuf/rpc/connectors/base_spec.rb +226 -0
- data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +69 -0
- data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +34 -0
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +110 -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 +91 -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 +35 -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 +101 -0
- data/spec/lib/protobuf/varint_spec.rb +29 -0
- data/spec/lib/protobuf_spec.rb +105 -0
- data/spec/spec_helper.rb +42 -0
- data/spec/support/all.rb +6 -0
- data/spec/support/packed_field.rb +23 -0
- data/spec/support/protos/all_types.data.bin +0 -0
- data/spec/support/protos/all_types.data.txt +119 -0
- data/spec/support/protos/enum.pb.rb +63 -0
- data/spec/support/protos/enum.proto +37 -0
- data/spec/support/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/protos/google_unittest.proto +884 -0
- data/spec/support/protos/google_unittest_custom_options.bin +0 -0
- data/spec/support/protos/google_unittest_custom_options.pb.rb +361 -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/protos/google_unittest_import.proto +73 -0
- data/spec/support/protos/google_unittest_import_public.pb.rb +31 -0
- data/spec/support/protos/google_unittest_import_public.proto +41 -0
- data/spec/support/protos/map-test.bin +157 -0
- data/spec/support/protos/map-test.pb.rb +85 -0
- data/spec/support/protos/map-test.proto +68 -0
- data/spec/support/protos/multi_field_extensions.pb.rb +59 -0
- data/spec/support/protos/multi_field_extensions.proto +35 -0
- data/spec/support/protos/resource.pb.rb +172 -0
- data/spec/support/protos/resource.proto +137 -0
- data/spec/support/resource_service.rb +23 -0
- data/spec/support/server.rb +65 -0
- data/spec/support/test_app_file.rb +2 -0
- data/varint_prof.rb +82 -0
- metadata +579 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'protobuf/logging'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Rpc
|
5
|
+
class ServiceDispatcher
|
6
|
+
include ::Protobuf::Logging
|
7
|
+
|
8
|
+
attr_reader :env
|
9
|
+
|
10
|
+
def initialize(_app)
|
11
|
+
# End of the line...
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
dup._call(env)
|
16
|
+
end
|
17
|
+
|
18
|
+
def _call(env)
|
19
|
+
@env = env
|
20
|
+
|
21
|
+
env.response = dispatch_rpc_request
|
22
|
+
env
|
23
|
+
end
|
24
|
+
|
25
|
+
def rpc_service
|
26
|
+
@rpc_service ||= env.rpc_service.new(env)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def dispatch_rpc_request
|
32
|
+
rpc_service.call(method_name)
|
33
|
+
rpc_service.response
|
34
|
+
end
|
35
|
+
|
36
|
+
def method_name
|
37
|
+
env.method_name
|
38
|
+
end
|
39
|
+
|
40
|
+
def service_name
|
41
|
+
env.service_name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,250 @@
|
|
1
|
+
module Protobuf
|
2
|
+
module Rpc
|
3
|
+
module ServiceFilters
|
4
|
+
|
5
|
+
def self.included(other)
|
6
|
+
other.class_eval do
|
7
|
+
extend Protobuf::Rpc::ServiceFilters::ClassMethods
|
8
|
+
include Protobuf::Rpc::ServiceFilters::InstanceMethods
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
|
14
|
+
[:after, :around, :before].each do |type|
|
15
|
+
# Setter DSL method for given filter types.
|
16
|
+
#
|
17
|
+
define_method "#{type}_filter" do |*args|
|
18
|
+
set_filters(type, *args)
|
19
|
+
end
|
20
|
+
alias_method "#{type}_action", "#{type}_filter"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Filters hash keyed based on filter type (e.g. :before, :after, :around),
|
24
|
+
# whose values are Sets.
|
25
|
+
#
|
26
|
+
def filters
|
27
|
+
@filters ||= Hash.new { |h, k| h[k] = [] }
|
28
|
+
end
|
29
|
+
|
30
|
+
# Filters hash keyed based on filter type (e.g. :before, :after, :around),
|
31
|
+
# whose values are Sets.
|
32
|
+
#
|
33
|
+
def rescue_filters
|
34
|
+
@rescue_filters ||= {}
|
35
|
+
end
|
36
|
+
|
37
|
+
def rescue_from(*ex_klasses, &block)
|
38
|
+
options = ex_klasses.last.is_a?(Hash) ? ex_klasses.pop : {}
|
39
|
+
callable = options.delete(:with) { block }
|
40
|
+
fail ArgumentError, 'Option :with missing from rescue_from options' if callable.nil?
|
41
|
+
ex_klasses.each { |ex_klass| rescue_filters[ex_klass] = callable }
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def define_filter(type, filter, options = {})
|
47
|
+
return if filter_defined?(type, filter)
|
48
|
+
filters[type] << options.merge(:callable => filter)
|
49
|
+
remember_filter(type, filter)
|
50
|
+
end
|
51
|
+
|
52
|
+
def defined_filters
|
53
|
+
@defined_filters ||= Hash.new { |h, k| h[k] = Set.new }
|
54
|
+
end
|
55
|
+
|
56
|
+
# Check to see if the filter has been defined.
|
57
|
+
#
|
58
|
+
def filter_defined?(type, filter)
|
59
|
+
defined_filters[type].include?(filter)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Remember that we stored the filter.
|
63
|
+
#
|
64
|
+
def remember_filter(type, filter)
|
65
|
+
defined_filters[type] << filter
|
66
|
+
end
|
67
|
+
|
68
|
+
# Takes a list of actually (or potentially) callable objects.
|
69
|
+
# TODO: add support for if/unless
|
70
|
+
# TODO: add support for only/except sub-filters
|
71
|
+
#
|
72
|
+
def set_filters(type, *args)
|
73
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
74
|
+
args.each do |filter|
|
75
|
+
define_filter(type, filter, options)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
module InstanceMethods
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# Get back to class filters.
|
86
|
+
#
|
87
|
+
def filters
|
88
|
+
self.class.filters
|
89
|
+
end
|
90
|
+
|
91
|
+
# Predicate which uses the filter options to determine if the filter
|
92
|
+
# should be called. Specifically checks the :if, :unless, :only, and :except
|
93
|
+
# options for every filter. Each option check is expected to return false
|
94
|
+
# if the filter should not be invoked, true if invocation should occur.
|
95
|
+
#
|
96
|
+
def invoke_filter?(rpc_method, filter)
|
97
|
+
invoke_via_only?(rpc_method, filter) &&
|
98
|
+
invoke_via_except?(rpc_method, filter) &&
|
99
|
+
invoke_via_if?(rpc_method, filter) &&
|
100
|
+
invoke_via_unless?(rpc_method, filter)
|
101
|
+
end
|
102
|
+
|
103
|
+
# If the target rpc endpoint method is listed under an :except option,
|
104
|
+
# return false to indicate that the filter should not be invoked. Any
|
105
|
+
# other target rpc endpoint methods not listed should be invoked.
|
106
|
+
# This option is the opposite of :only.
|
107
|
+
#
|
108
|
+
# Value should be a symbol/string or an array of symbols/strings.
|
109
|
+
#
|
110
|
+
def invoke_via_except?(rpc_method, filter)
|
111
|
+
except = [filter.fetch(:except) { [] }].flatten
|
112
|
+
except.empty? || !except.include?(rpc_method)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Invoke the given :if callable (if any) and return its return value.
|
116
|
+
# Used by `invoke_filter?` which expects a true/false
|
117
|
+
# return value to determine if we should invoke the target filter.
|
118
|
+
#
|
119
|
+
# Value can either be a symbol/string indicating an instance method to call
|
120
|
+
# or an object that responds to `call`.
|
121
|
+
#
|
122
|
+
def invoke_via_if?(_rpc_method, filter)
|
123
|
+
if_check = filter.fetch(:if, nil)
|
124
|
+
return true if if_check.nil?
|
125
|
+
call_or_send(if_check)
|
126
|
+
end
|
127
|
+
|
128
|
+
# If the target rpc endpoint method is listed in the :only option,
|
129
|
+
# it should be invoked. Any target rpc endpoint methods not listed in this
|
130
|
+
# option should not be invoked. This option is the opposite of :except.
|
131
|
+
#
|
132
|
+
# Value should be a symbol/string or an array of symbols/strings.
|
133
|
+
#
|
134
|
+
def invoke_via_only?(rpc_method, filter)
|
135
|
+
only = [filter.fetch(:only) { [] }].flatten
|
136
|
+
only.empty? || only.include?(rpc_method)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Invoke the given :unless callable (if any) and return the opposite
|
140
|
+
# of it's return value. Used by `invoke_filter?` which expects a true/false
|
141
|
+
# return value to determine if we should invoke the target filter.
|
142
|
+
#
|
143
|
+
# Value can either be a symbol/string indicating an instance method to call
|
144
|
+
# or an object that responds to `call`.
|
145
|
+
#
|
146
|
+
def invoke_via_unless?(_rpc_method, filter)
|
147
|
+
unless_check = filter.fetch(:unless, nil)
|
148
|
+
return true if unless_check.nil?
|
149
|
+
!call_or_send(unless_check)
|
150
|
+
end
|
151
|
+
|
152
|
+
def rescue_filters
|
153
|
+
self.class.rescue_filters
|
154
|
+
end
|
155
|
+
|
156
|
+
# Loop over the unwrapped filters and invoke them. An unwrapped filter
|
157
|
+
# is either a before or after filter, not an around filter.
|
158
|
+
#
|
159
|
+
def run_unwrapped_filters(unwrapped_filters, rpc_method, stop_on_false_return = false)
|
160
|
+
unwrapped_filters.each do |filter|
|
161
|
+
if invoke_filter?(rpc_method, filter)
|
162
|
+
return_value = call_or_send(filter[:callable])
|
163
|
+
return false if stop_on_false_return && return_value == false
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
true
|
168
|
+
end
|
169
|
+
|
170
|
+
# Reverse build a chain of around filters. To implement an around chain,
|
171
|
+
# simply build a method that yields control when it expects the underlying
|
172
|
+
# method to be invoked. If the endpoint should not be run (due to some
|
173
|
+
# condition), simply do not yield.
|
174
|
+
#
|
175
|
+
# Around filters are invoked in the order they are defined, outer to inner,
|
176
|
+
# with the inner-most method called being the actual rpc endpoint.
|
177
|
+
#
|
178
|
+
# Let's say you have a class defined with the following filters:
|
179
|
+
#
|
180
|
+
# class MyService
|
181
|
+
# around_filter :filter1, :filter2, :filter3
|
182
|
+
#
|
183
|
+
# def my_endpoint
|
184
|
+
# # do stuff
|
185
|
+
# end
|
186
|
+
# end
|
187
|
+
#
|
188
|
+
# When the my_endpoint method is invoked using Service#callable_rpc_method,
|
189
|
+
# It is similar to this call chain:
|
190
|
+
#
|
191
|
+
# filter1 do
|
192
|
+
# filter2 do
|
193
|
+
# filter3 do
|
194
|
+
# my_endpoint
|
195
|
+
# end
|
196
|
+
# end
|
197
|
+
# end
|
198
|
+
#
|
199
|
+
def run_around_filters(rpc_method)
|
200
|
+
final = -> { __send__(rpc_method) }
|
201
|
+
filters[:around].reverse.reduce(final) do |previous, filter|
|
202
|
+
if invoke_filter?(rpc_method, filter)
|
203
|
+
-> { call_or_send(filter[:callable], &previous) }
|
204
|
+
else
|
205
|
+
previous
|
206
|
+
end
|
207
|
+
end.call
|
208
|
+
end
|
209
|
+
|
210
|
+
# Entry method to call each filter type in the appropriate order. This should
|
211
|
+
# be used instead of the other run methods directly.
|
212
|
+
#
|
213
|
+
def run_filters(rpc_method)
|
214
|
+
run_rescue_filters do
|
215
|
+
continue = run_unwrapped_filters(filters[:before], rpc_method, true)
|
216
|
+
if continue
|
217
|
+
run_around_filters(rpc_method)
|
218
|
+
run_unwrapped_filters(filters[:after], rpc_method)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def run_rescue_filters
|
224
|
+
if rescue_filters.keys.empty?
|
225
|
+
yield
|
226
|
+
else
|
227
|
+
begin
|
228
|
+
yield
|
229
|
+
rescue *rescue_filters.keys => ex
|
230
|
+
callable = rescue_filters.fetch(ex.class) do
|
231
|
+
mapped_klass = rescue_filters.keys.find { |child_klass| ex.class < child_klass }
|
232
|
+
rescue_filters[mapped_klass]
|
233
|
+
end
|
234
|
+
|
235
|
+
call_or_send(callable, ex)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
# Call the object if it is callable, otherwise invoke the method using
|
241
|
+
# __send__ assuming that we respond_to it. Return the call's return value.
|
242
|
+
#
|
243
|
+
def call_or_send(callable, *args, &block)
|
244
|
+
return callable.call(self, *args, &block) if callable.respond_to?(:call)
|
245
|
+
__send__(callable, *args, &block)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'time'
|
3
|
+
require 'protobuf/logging'
|
4
|
+
require 'protobuf/rpc/rpc.pb'
|
5
|
+
|
6
|
+
module Protobuf
|
7
|
+
module Rpc
|
8
|
+
class Stat
|
9
|
+
attr_accessor :mode, :start_time, :end_time, :request_size, :dispatcher
|
10
|
+
attr_accessor :response_size, :client, :service, :method_name, :status
|
11
|
+
attr_reader :server
|
12
|
+
|
13
|
+
MODES = [:SERVER, :CLIENT].freeze
|
14
|
+
|
15
|
+
ERROR_TRANSLATIONS = {
|
16
|
+
::Protobuf::Socketrpc::ErrorReason::BAD_REQUEST_DATA => "BAD_REQUEST_DATA",
|
17
|
+
::Protobuf::Socketrpc::ErrorReason::BAD_REQUEST_PROTO => "BAD_REQUEST_PROTO",
|
18
|
+
::Protobuf::Socketrpc::ErrorReason::SERVICE_NOT_FOUND => "SERVICE_NOT_FOUND",
|
19
|
+
::Protobuf::Socketrpc::ErrorReason::METHOD_NOT_FOUND => "METHOD_NOT_FOUND",
|
20
|
+
::Protobuf::Socketrpc::ErrorReason::RPC_ERROR => "RPC_ERROR",
|
21
|
+
::Protobuf::Socketrpc::ErrorReason::RPC_FAILED => "RPC_FAILED",
|
22
|
+
::Protobuf::Socketrpc::ErrorReason::INVALID_REQUEST_PROTO => "INVALID_REQUEST_PROTO",
|
23
|
+
::Protobuf::Socketrpc::ErrorReason::BAD_RESPONSE_PROTO => "BAD_RESPONSE_PROTO",
|
24
|
+
::Protobuf::Socketrpc::ErrorReason::UNKNOWN_HOST => "UNKNOWN_HOST",
|
25
|
+
::Protobuf::Socketrpc::ErrorReason::IO_ERROR => "IO_ERROR",
|
26
|
+
}.freeze
|
27
|
+
|
28
|
+
def initialize(mode = :SERVER)
|
29
|
+
@mode = mode
|
30
|
+
@request_size = 0
|
31
|
+
@response_size = 0
|
32
|
+
start
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_writer :client
|
36
|
+
|
37
|
+
def client
|
38
|
+
@client || nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def elapsed_time
|
42
|
+
(start_time && end_time ? "#{(end_time - start_time).round(4)}s" : nil)
|
43
|
+
end
|
44
|
+
|
45
|
+
def method_name
|
46
|
+
@method_name ||= @dispatcher.try(:service).try(:method_name)
|
47
|
+
end
|
48
|
+
|
49
|
+
def server=(peer)
|
50
|
+
case peer
|
51
|
+
when Array
|
52
|
+
@server = "#{peer[1]}:#{peer[0]}"
|
53
|
+
when String
|
54
|
+
@server = peer
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def service
|
59
|
+
@service ||= @dispatcher.try(:service).class.name
|
60
|
+
end
|
61
|
+
|
62
|
+
def sizes
|
63
|
+
if stopped?
|
64
|
+
"#{@request_size}B/#{@response_size}B"
|
65
|
+
else
|
66
|
+
"#{@request_size}B/-"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def start
|
71
|
+
@start_time ||= ::Time.now
|
72
|
+
end
|
73
|
+
|
74
|
+
def stop
|
75
|
+
start unless @start_time
|
76
|
+
@end_time ||= ::Time.now
|
77
|
+
end
|
78
|
+
|
79
|
+
def stopped?
|
80
|
+
!end_time.nil?
|
81
|
+
end
|
82
|
+
|
83
|
+
def rpc
|
84
|
+
service && method_name ? "#{service}##{method_name}" : nil
|
85
|
+
end
|
86
|
+
|
87
|
+
def server?
|
88
|
+
@mode == :SERVER
|
89
|
+
end
|
90
|
+
|
91
|
+
def client?
|
92
|
+
@mode == :CLIENT
|
93
|
+
end
|
94
|
+
|
95
|
+
def status_string
|
96
|
+
return "OK" if status.nil?
|
97
|
+
|
98
|
+
ERROR_TRANSLATIONS.fetch(status, "UNKNOWN_ERROR")
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
[
|
103
|
+
server? ? "[SRV]" : "[CLT]",
|
104
|
+
server? ? client : server,
|
105
|
+
trace_id,
|
106
|
+
rpc,
|
107
|
+
sizes,
|
108
|
+
elapsed_time,
|
109
|
+
status_string,
|
110
|
+
@end_time.try(:iso8601),
|
111
|
+
].compact.join(' - ')
|
112
|
+
end
|
113
|
+
|
114
|
+
def trace_id
|
115
|
+
::Thread.current.object_id.to_s(16)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
##
|
2
|
+
## Socket Mode
|
3
|
+
##
|
4
|
+
#
|
5
|
+
# Require this file if you wish to run your server and/or client RPC
|
6
|
+
# with the raw socket handlers. This is the default run mode for bin/rpc_server.
|
7
|
+
#
|
8
|
+
# To run with rpc_server either omit any mode switches, or explicitly pass `socket`:
|
9
|
+
#
|
10
|
+
# rpc_server myapp.rb
|
11
|
+
# rpc_server --socket myapp.rb
|
12
|
+
#
|
13
|
+
# To run for client-side only override the require in your Gemfile:
|
14
|
+
#
|
15
|
+
# gem 'protobuf', :require => 'protobuf/socket'
|
16
|
+
#
|
17
|
+
require 'protobuf'
|
18
|
+
require 'protobuf/rpc/servers/socket/server'
|
19
|
+
require 'protobuf/rpc/connectors/socket'
|
20
|
+
|
21
|
+
::Protobuf.connector_type_class = ::Protobuf::Rpc::Connectors::Socket
|
@@ -0,0 +1 @@
|
|
1
|
+
load 'protobuf/tasks/compile.rake'
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
|
3
|
+
namespace :protobuf do
|
4
|
+
|
5
|
+
desc "Clean & Compile the protobuf source to ruby classes. Pass PB_NO_CLEAN=1 if you do not want to force-clean first."
|
6
|
+
task :compile, [:package, :source, :destination, :plugin, :file_extension] do |_tasks, args|
|
7
|
+
binpath = ::File.expand_path("../../../../bin", __FILE__)
|
8
|
+
|
9
|
+
args.with_defaults(:destination => "lib")
|
10
|
+
args.with_defaults(:source => "definitions")
|
11
|
+
args.with_defaults(:plugin => "protoc-gen-ruby-protobuf=#{binpath}/protoc-gen-ruby")
|
12
|
+
args.with_defaults(:file_extension => ".pb.rb")
|
13
|
+
|
14
|
+
# The local Ruby generator collides with the builtin Ruby generator
|
15
|
+
#
|
16
|
+
# From the protoc docs:
|
17
|
+
#
|
18
|
+
# --plugin=EXECUTABLE
|
19
|
+
#
|
20
|
+
# ...EXECUTABLE may be of the form NAME=PATH, in which case the given plugin name
|
21
|
+
# is mapped to the given executable even if the executable"s own name differs.
|
22
|
+
#
|
23
|
+
# Use the NAME=PATH form to specify an alternative plugin name that avoids the name collision
|
24
|
+
#
|
25
|
+
plugin_name, _plugin_path = args[:plugin].split("=")
|
26
|
+
|
27
|
+
# The plugin name MUST have the protoc-gen- prefix in order to work, but that prefix is dropped
|
28
|
+
# when using the plugin to generate definitions
|
29
|
+
plugin_name.gsub!("protoc-gen-", "")
|
30
|
+
|
31
|
+
unless do_not_clean?
|
32
|
+
force_clean!
|
33
|
+
::Rake::Task[:clean].invoke(args[:package], args[:destination], args[:file_extension])
|
34
|
+
end
|
35
|
+
|
36
|
+
command = []
|
37
|
+
command << "protoc"
|
38
|
+
command << "--plugin=#{args[:plugin]}"
|
39
|
+
command << "--#{plugin_name}_out=#{args[:destination]}"
|
40
|
+
command << "-I #{args[:source]}"
|
41
|
+
command << Dir["#{args[:source]}/#{args[:package]}/**/*.proto"].join(" ")
|
42
|
+
full_command = command.join(" ")
|
43
|
+
|
44
|
+
puts full_command
|
45
|
+
system(full_command)
|
46
|
+
end
|
47
|
+
|
48
|
+
desc "Clean the generated *.pb.rb files from the destination package. Pass PB_FORCE_CLEAN=1 to skip confirmation step."
|
49
|
+
task :clean, [:package, :destination, :file_extension] do |_task, args|
|
50
|
+
args.with_defaults(:destination => "lib")
|
51
|
+
args.with_defaults(:file_extension => ".pb.rb")
|
52
|
+
|
53
|
+
file_extension = args[:file_extension].sub(/\*?\.+/, "")
|
54
|
+
files_to_clean = ::File.join(args[:destination], args[:package], "**", "*.#{file_extension}")
|
55
|
+
|
56
|
+
if force_clean? || permission_to_clean?(files_to_clean)
|
57
|
+
::Dir.glob(files_to_clean).each do |file|
|
58
|
+
::FileUtils.rm(file)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def do_not_clean?
|
64
|
+
! ::ENV.key?("PB_NO_CLEAN")
|
65
|
+
end
|
66
|
+
|
67
|
+
def force_clean?
|
68
|
+
::ENV.key?("PB_FORCE_CLEAN")
|
69
|
+
end
|
70
|
+
|
71
|
+
def force_clean!
|
72
|
+
::ENV["PB_FORCE_CLEAN"] = "1"
|
73
|
+
end
|
74
|
+
|
75
|
+
def permission_to_clean?(files_to_clean)
|
76
|
+
puts "Do you really want to remove files matching pattern #{files_to_clean}? (y/n)"
|
77
|
+
::STDIN.gets.chomp =~ /y(es)?/i
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|