grpcx 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ce77106489146dc1a2c5dbaf39411f2061d86355b857de1100cc952a8d1b9522
4
+ data.tar.gz: 30cdaa7d8aaa269106010a61e91a4c2916c928218fa47624ee6c06a0f4bccd48
5
+ SHA512:
6
+ metadata.gz: 10727d31b94270648bab756d5da572ffcf244f17bf4540ee4830d110635bf26e7c0900de0d11002a5bd840a3796fbda18a417bd5f38353f44fdcdac7b39af03a
7
+ data.tar.gz: 1378bb8ecf7d4528e0400bb109fc80e1e98baa0567a131c510ed40b1f3dd37752337d21ad41f7982cf23fb3a7eb9d71fea3c18fd12de5ac5eb4e3d05c9b4a3f6
data/.editorconfig ADDED
@@ -0,0 +1,9 @@
1
+ root = true
2
+
3
+ [*]
4
+ indent_style = space
5
+ indent_size = 2
6
+ end_of_line = lf
7
+ charset = utf-8
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .rubocop-*
data/.rubocop.yml ADDED
@@ -0,0 +1,9 @@
1
+ inherit_from:
2
+ - https://storage.googleapis.com/bsm-misc/rubocop.yml
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 2.2
6
+
7
+ Metrics/AbcSize:
8
+ Enabled: false
9
+
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,107 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ grpcx (0.1.0)
5
+ activesupport (>= 5.0)
6
+ grpc (>= 1.8.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activemodel (5.2.0)
12
+ activesupport (= 5.2.0)
13
+ activerecord (5.2.0)
14
+ activemodel (= 5.2.0)
15
+ activesupport (= 5.2.0)
16
+ arel (>= 9.0)
17
+ activesupport (5.2.0)
18
+ concurrent-ruby (~> 1.0, >= 1.0.2)
19
+ i18n (>= 0.7, < 2)
20
+ minitest (~> 5.1)
21
+ tzinfo (~> 1.1)
22
+ addressable (2.5.2)
23
+ public_suffix (>= 2.0.2, < 4.0)
24
+ arel (9.0.0)
25
+ ast (2.4.0)
26
+ concurrent-ruby (1.0.5)
27
+ diff-lcs (1.3)
28
+ faraday (0.15.0)
29
+ multipart-post (>= 1.2, < 3)
30
+ google-protobuf (3.5.1.2-x86_64-linux)
31
+ googleapis-common-protos-types (1.0.1)
32
+ google-protobuf (~> 3.0)
33
+ googleauth (0.6.2)
34
+ faraday (~> 0.12)
35
+ jwt (>= 1.4, < 3.0)
36
+ logging (~> 2.0)
37
+ memoist (~> 0.12)
38
+ multi_json (~> 1.11)
39
+ os (~> 0.9)
40
+ signet (~> 0.7)
41
+ grpc (1.11.0-x86_64-linux)
42
+ google-protobuf (~> 3.1)
43
+ googleapis-common-protos-types (~> 1.0.0)
44
+ googleauth (>= 0.5.1, < 0.7)
45
+ i18n (1.0.1)
46
+ concurrent-ruby (~> 1.0)
47
+ jwt (2.1.0)
48
+ little-plugger (1.1.4)
49
+ logging (2.2.2)
50
+ little-plugger (~> 1.1)
51
+ multi_json (~> 1.10)
52
+ memoist (0.16.0)
53
+ minitest (5.11.3)
54
+ multi_json (1.13.1)
55
+ multipart-post (2.0.0)
56
+ os (0.9.6)
57
+ parallel (1.12.1)
58
+ parser (2.5.1.0)
59
+ ast (~> 2.4.0)
60
+ powerpack (0.1.1)
61
+ public_suffix (3.0.2)
62
+ rainbow (3.0.0)
63
+ rake (12.3.1)
64
+ rspec (3.7.0)
65
+ rspec-core (~> 3.7.0)
66
+ rspec-expectations (~> 3.7.0)
67
+ rspec-mocks (~> 3.7.0)
68
+ rspec-core (3.7.1)
69
+ rspec-support (~> 3.7.0)
70
+ rspec-expectations (3.7.0)
71
+ diff-lcs (>= 1.2.0, < 2.0)
72
+ rspec-support (~> 3.7.0)
73
+ rspec-mocks (3.7.0)
74
+ diff-lcs (>= 1.2.0, < 2.0)
75
+ rspec-support (~> 3.7.0)
76
+ rspec-support (3.7.1)
77
+ rubocop (0.55.0)
78
+ parallel (~> 1.10)
79
+ parser (>= 2.5)
80
+ powerpack (~> 0.1)
81
+ rainbow (>= 2.2.2, < 4.0)
82
+ ruby-progressbar (~> 1.7)
83
+ unicode-display_width (~> 1.0, >= 1.0.1)
84
+ ruby-progressbar (1.9.0)
85
+ signet (0.8.1)
86
+ addressable (~> 2.3)
87
+ faraday (~> 0.9)
88
+ jwt (>= 1.5, < 3.0)
89
+ multi_json (~> 1.10)
90
+ thread_safe (0.3.6)
91
+ tzinfo (1.2.5)
92
+ thread_safe (~> 0.1)
93
+ unicode-display_width (1.3.2)
94
+
95
+ PLATFORMS
96
+ ruby
97
+
98
+ DEPENDENCIES
99
+ activerecord
100
+ bundler
101
+ grpcx!
102
+ rake
103
+ rspec
104
+ rubocop
105
+
106
+ BUNDLED WITH
107
+ 1.16.1
data/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # grpcx
2
+
3
+ Ruby gRPC extensions/helpers
4
+
5
+
6
+ # Grpcx::Server
7
+
8
+ Mixin for `GRPC::RpcServer`:
9
+
10
+ - handles [GRPC health checks](https://github.com/grpc/grpc/blob/master/doc/health-checking.md) requests
11
+ - handles `ActiveRecord` connection (auto-connect + pooling)
12
+ - instruments each request with `ActiveSupport::Notifications` (available as `process_action.grpc`, includes `action: METHOD_NAME` data)
13
+ - includes `ActiveSupport::Rescuable` and transforms most common `ActiveRecord::ActiveRecordError`-s into `GRPC::BadStatus` ones
14
+
15
+
16
+ Example:
17
+
18
+ ```ruby
19
+ require 'grpcx/server' # or just 'grpcx'
20
+
21
+ class MyServer < GRPC::RpcServer
22
+ include Grpcx::Server
23
+
24
+ # optional custom error handling:
25
+ rescue_from 'MyError' do |e|
26
+ raise Grpc::BadStatus.new(e.to_s, my_extra: e.my_extra)
27
+ end
28
+ end
29
+
30
+ # proceed as with usual GRPC::RpcServer:
31
+ server = MyServer.new(...)
32
+ server.handle(MyService.new)
33
+ server.add_http2_port '127.0.0.1:8080', :this_port_is_insecure
34
+ server.run_till_terminated
35
+ ```
36
+
37
+ Recommended to be used with [Grpclb::Server](https://github.com/bsm/grpclb/tree/master/ruby):
38
+
39
+ ```ruby
40
+ require 'grpclb/server'
41
+ require 'grpcx/server'
42
+
43
+ class MyServer < Grpclb::Server
44
+ include Grpcx::Server
45
+ end
46
+
47
+ ...
48
+ ```
49
+
50
+
51
+ ## Using with [Datadog::Notifications](https://github.com/bsm/datadog-notifications)
52
+
53
+ ```ruby
54
+ module Datadog::Notifications::Plugins
55
+ class GRPC < Base
56
+
57
+ def initialize(opts={})
58
+ super
59
+ Datadog::Notifications.subscribe 'process_action.grpc' do |reporter, event|
60
+ record(reporter, event)
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def record(reporter, event)
67
+ action = event.payload[:action]
68
+ status = event.payload[:exception] ? 'error' : 'ok'
69
+ tags = self.tags + ["rpc:#{action}", "status:#{status}"]
70
+
71
+ reporter.batch do
72
+ reporter.increment 'grpc.request', tags: tags
73
+ reporter.timing 'grpc.request.time', event.duration, tags: tags
74
+ end
75
+ end
76
+
77
+ end
78
+ end
79
+
80
+ Datadog::Notifications.configure do |c|
81
+ c.use Datadog::Notifications::Plugins::GRPC
82
+ end if RUNNING_IN_PROD?
83
+ ```
84
+
85
+
86
+ ## Using with [Sentry](https://sentry.io/)/[Raven](https://github.com/getsentry/raven-ruby)
87
+
88
+ ```ruby
89
+ ActiveSupport::Notifications.subscribe('process_action.grpc') do |_name, _start, _finish, _id, payload|
90
+ e = payload[:exception_object]
91
+ next unless e
92
+
93
+ Raven.capture_exception(e)
94
+ end
95
+
96
+ Raven.configure do |config|
97
+ config.should_capture = proc {|e|
98
+ !e.is_a?(GRPC::BadStatus) # skip GRPC::BadStatus, but report everything else
99
+ }
100
+ end
101
+ ```
102
+
103
+ Similar approach can be used for logging.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
+
4
+ require 'rubocop/rake_task'
5
+ RuboCop::RakeTask.new(:rubocop)
6
+
7
+ require 'rspec/core/rake_task'
8
+ RSpec::Core::RakeTask.new(:spec)
9
+
10
+ task default: %i[rubocop spec]
data/grpcx.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'grpcx'
3
+ s.version = '0.1.0'
4
+ s.authors = ['Black Square Media Ltd']
5
+ s.email = ['info@blacksquaremedia.com']
6
+ s.summary = %(gRPC extensions/helpers)
7
+ s.description = %()
8
+ s.homepage = 'https://bitbucket.org/bsm/grpcx'
9
+ s.license = 'MIT'
10
+
11
+ s.files = `git ls-files -z`.split("\x0").reject {|f| f.match(%r{^spec/}) }
12
+ s.test_files = `git ls-files -z -- spec/*`.split("\x0")
13
+ s.require_paths = ['lib']
14
+ s.required_ruby_version = '>= 2.2'
15
+
16
+ s.add_dependency 'activesupport', '>= 5.0'
17
+ s.add_dependency 'grpc', '>= 1.8.0'
18
+
19
+ s.add_development_dependency 'activerecord'
20
+ s.add_development_dependency 'bundler'
21
+ s.add_development_dependency 'rake'
22
+ s.add_development_dependency 'rspec'
23
+ s.add_development_dependency 'rubocop'
24
+ end
@@ -0,0 +1,37 @@
1
+ module Grpcx
2
+ module Server
3
+ module Interceptors
4
+ # Manages ActiveRecord::Base connection,
5
+ # making sure that connection is established before each request
6
+ # and re-pooling connections when request is processed.
7
+ class ActiveRecord < GRPC::ServerInterceptor
8
+
9
+ def request_response(*, &block)
10
+ wrap(&block)
11
+ end
12
+
13
+ def client_streamer(*, &block)
14
+ wrap(&block)
15
+ end
16
+
17
+ def server_streamer(*, &block)
18
+ wrap(&block)
19
+ end
20
+
21
+ def bidi_streamer(*, &block)
22
+ wrap(&block)
23
+ end
24
+
25
+ private
26
+
27
+ def wrap
28
+ ::ActiveRecord::Base.establish_connection unless ::ActiveRecord::Base.connection.active?
29
+ yield
30
+ ensure
31
+ ::ActiveRecord::Base.clear_active_connections!
32
+ end
33
+
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,34 @@
1
+ require 'active_support/notifications'
2
+
3
+ module Grpcx
4
+ module Server
5
+ module Interceptors
6
+ class Instrumentation < GRPC::ServerInterceptor
7
+ METRIC_NAME = 'process_action.grpc'.freeze
8
+
9
+ def request_response(method: nil, &block)
10
+ instrument(action: method, &block)
11
+ end
12
+
13
+ def client_streamer(method: nil, &block)
14
+ instrument(action: method, &block)
15
+ end
16
+
17
+ def server_streamer(method: nil, &block)
18
+ instrument(action: method, &block)
19
+ end
20
+
21
+ def bidi_streamer(method: nil, &block)
22
+ instrument(action: method, &block)
23
+ end
24
+
25
+ private
26
+
27
+ def instrument(opts={}, &block)
28
+ ActiveSupport::Notifications.instrument(METRIC_NAME, opts, &block)
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,37 @@
1
+ module Grpcx
2
+ module Server
3
+ module Interceptors
4
+ class Rescue < GRPC::ServerInterceptor
5
+ def initialize(rescuable, opts={})
6
+ @rescuable = rescuable
7
+ super(opts)
8
+ end
9
+
10
+ def request_response(*)
11
+ yield
12
+ rescue StandardError => err
13
+ @rescuable.rescue_with_handler(err) || raise
14
+ end
15
+
16
+ def client_streamer(*)
17
+ yield
18
+ rescue StandardError => err
19
+ @rescuable.rescue_with_handler(err) || raise
20
+ end
21
+
22
+ def server_streamer(*)
23
+ yield
24
+ rescue StandardError => err
25
+ @rescuable.rescue_with_handler(err) || raise
26
+ end
27
+
28
+ def bidi_streamer(*)
29
+ yield
30
+ rescue StandardError => err
31
+ @rescuable.rescue_with_handler(err) || raise
32
+ end
33
+
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ require 'grpcx/server/interceptors/rescue'
2
+ require 'grpcx/server/interceptors/instrumentation'
3
+ require 'grpcx/server/interceptors/active_record'
@@ -0,0 +1,56 @@
1
+ require 'grpc'
2
+ require 'grpc/health/checker'
3
+ require 'active_support/concern'
4
+ require 'active_support/rescuable'
5
+ require 'grpcx/server/interceptors'
6
+
7
+ module Grpcx
8
+ module Server
9
+ extend ActiveSupport::Concern
10
+ include ActiveSupport::Rescuable
11
+
12
+ ServingStatus = ::Grpc::Health::Checker::HealthCheckResponse::ServingStatus
13
+
14
+ included do
15
+ attr_reader :interceptors
16
+
17
+ rescue_from 'ActiveRecord::RecordInvalid' do |e|
18
+ raise GRPC::InvalidArgument.new('record invalid', errors: e.record.errors.to_h)
19
+ end
20
+ rescue_from 'ActiveRecord::RecordNotFound' do |e|
21
+ raise GRPC::NotFound.new('record not found', id: e.id, model: e.model.to_s)
22
+ end
23
+ end
24
+
25
+ def initialize(opts={})
26
+ opts[:pool_size] ||= ENV['GRPC_SERVER_THREADS'].to_i if ENV['GRPC_SERVER_THREADS']
27
+ opts[:max_waiting_requests] ||= ENV['GRPC_SERVER_QUEUE'].to_i if ENV['GRPC_SERVER_QUEUE']
28
+
29
+ # interceptors are fired in FIFO order.
30
+ opts[:interceptors] ||= []
31
+ opts[:interceptors].prepend Grpcx::Server::Interceptors::Rescue.new(self)
32
+ opts[:interceptors].prepend Grpcx::Server::Interceptors::Instrumentation.new
33
+ opts[:interceptors].prepend Grpcx::Server::Interceptors::ActiveRecord.new if defined?(::ActiveRecord)
34
+
35
+ super(opts).tap do
36
+ handle(health)
37
+ end
38
+ end
39
+
40
+ def handle(service)
41
+ service_name = nil
42
+ if service.is_a?(Class) && service < GRPC::GenericService
43
+ service_name = service.service_name
44
+ elsif service.is_a?(GRPC::GenericService)
45
+ service_name = service.class.service_name
46
+ end
47
+
48
+ health.add_status(service_name, ServingStatus::SERVING) if service_name
49
+ super
50
+ end
51
+
52
+ def health
53
+ @health ||= ::Grpc::Health::Checker.new
54
+ end
55
+ end
56
+ end
data/lib/grpcx.rb ADDED
@@ -0,0 +1 @@
1
+ require 'grpcx/server'
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Grpcx::Server do
4
+
5
+ subject do
6
+ s = Grpcx::Spec::Server.new
7
+ s.handle Grpcx::Spec::Service::V1
8
+ s
9
+ end
10
+
11
+ it 'should have a health-check' do
12
+ expect(subject.health).to be_a(Grpc::Health::Checker)
13
+ expect(subject.health.instance_variable_get(:@statuses)).to eq(
14
+ 'grpcx.spec.service.V1' => 1,
15
+ 'grpc.health.v1.Health' => 1,
16
+ )
17
+ end
18
+
19
+ it 'should have interceptors' do
20
+ expect(subject.interceptors).to be_a(GRPC::InterceptorRegistry)
21
+
22
+ registered = subject.interceptors.instance_variable_get(:@interceptors)
23
+ expect(registered.size).to eq(3)
24
+ end
25
+
26
+ it 'should have rescue handlers' do
27
+ expect(subject.rescue_handlers.size).to eq(3)
28
+ expect(subject.rescue_handlers.map(&:first)).to match_array %w[
29
+ ActiveRecord::RecordInvalid
30
+ ActiveRecord::RecordNotFound
31
+ ArgumentError
32
+ ]
33
+ end
34
+
35
+ end
@@ -0,0 +1,45 @@
1
+ require 'rspec'
2
+ require 'grpcx'
3
+ require 'active_record'
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_message "grpcx.spec.Message" do
8
+ optional :name, :string, 1
9
+ end
10
+ add_enum "grpcx.spec.Enum" do
11
+ value :V0, 0
12
+ value :V1, 1
13
+ value :V2, 2
14
+ end
15
+ add_message "grpcx.spec.GetMessageRequest" do
16
+ end
17
+ end
18
+
19
+ module Grpcx::Spec
20
+ Message = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpcx.spec.Message").msgclass
21
+ Enum = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpcx.spec.Enum").enummodule
22
+ GetMessageRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpcx.spec.GetMessageRequest").msgclass
23
+
24
+ module Service
25
+ class V1
26
+ include GRPC::GenericService
27
+
28
+ self.marshal_class_method = :encode
29
+ self.unmarshal_class_method = :decode
30
+ self.service_name = 'grpcx.spec.service.V1'
31
+
32
+ rpc :GetMessage, GetMessageRequest, Message
33
+ end
34
+
35
+ Stub = V1.rpc_stub_class
36
+ end
37
+
38
+ class Server < GRPC::RpcServer
39
+ include Grpcx::Server
40
+
41
+ rescue_from 'ArgumentError' do |e|
42
+ raise GRPC::InvalidArgument.new(errors: e.to_s)
43
+ end
44
+ end
45
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: grpcx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Black Square Media Ltd
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-05-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: grpc
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.8.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: activerecord
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: ''
112
+ email:
113
+ - info@blacksquaremedia.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".editorconfig"
119
+ - ".gitignore"
120
+ - ".rubocop.yml"
121
+ - Gemfile
122
+ - Gemfile.lock
123
+ - README.md
124
+ - Rakefile
125
+ - grpcx.gemspec
126
+ - lib/grpcx.rb
127
+ - lib/grpcx/server.rb
128
+ - lib/grpcx/server/interceptors.rb
129
+ - lib/grpcx/server/interceptors/active_record.rb
130
+ - lib/grpcx/server/interceptors/instrumentation.rb
131
+ - lib/grpcx/server/interceptors/rescue.rb
132
+ - spec/lib/server_spec.rb
133
+ - spec/spec_helper.rb
134
+ homepage: https://bitbucket.org/bsm/grpcx
135
+ licenses:
136
+ - MIT
137
+ metadata: {}
138
+ post_install_message:
139
+ rdoc_options: []
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '2.2'
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ requirements: []
153
+ rubyforge_project:
154
+ rubygems_version: 2.7.3
155
+ signing_key:
156
+ specification_version: 4
157
+ summary: gRPC extensions/helpers
158
+ test_files:
159
+ - spec/lib/server_spec.rb
160
+ - spec/spec_helper.rb