grpcx 0.1.1 → 0.3.2
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/.github/workflows/test.yml +21 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +10 -5
- data/Gemfile.lock +64 -78
- data/README.md +10 -33
- data/grpcx.gemspec +4 -3
- data/lib/grpcx/entity.rb +58 -0
- data/lib/grpcx/server/interceptors/active_record.rb +0 -2
- data/lib/grpcx/server/interceptors/instrumentation.rb +12 -11
- data/lib/grpcx/server/interceptors/rescue.rb +9 -10
- data/lib/grpcx/server.rb +2 -2
- data/lib/grpcx.rb +1 -0
- data/spec/lib/entity_spec.rb +24 -0
- data/spec/lib/server_spec.rb +3 -5
- data/spec/spec_helper.rb +14 -6
- metadata +11 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ae9c03741c37bfd3ee885a9a95623e8daba6abaed7ead588f75c79f46d45e44d
|
|
4
|
+
data.tar.gz: 7d2c52dfac712a2b1cf961ec3316fc0bc0dada3f81ebff4862e11fed43d05994
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 061002012c4005ee48ca374505bd4fbb1f29a09c98d444d99517871eaace0317c8a455c444a6f9a88c32287e751bf65cc3f5778b1ad487024f28997329584deb
|
|
7
|
+
data.tar.gz: ccdf1e5cc44b92b46214bc02c8ed29d03faea2f45964663f3bb59ca1873da7457a1e630c58c46b4f74bd0dd2447fc2d908877621f7387b9d20121882619053a3
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches:
|
|
5
|
+
- main
|
|
6
|
+
pull_request:
|
|
7
|
+
branches:
|
|
8
|
+
- main
|
|
9
|
+
jobs:
|
|
10
|
+
ruby:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
ruby-version: ["2.7", "3.0", "3.1"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v2
|
|
17
|
+
- uses: ruby/setup-ruby@v1
|
|
18
|
+
with:
|
|
19
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
20
|
+
bundler-cache: true
|
|
21
|
+
- run: bundle exec rake
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
-
|
|
1
|
+
inherit_gem:
|
|
2
|
+
rubocop-bsm:
|
|
3
|
+
- default.yml
|
|
4
|
+
inherit_mode:
|
|
5
|
+
merge:
|
|
6
|
+
- Exclude
|
|
3
7
|
|
|
4
8
|
AllCops:
|
|
5
|
-
TargetRubyVersion: 2.
|
|
9
|
+
TargetRubyVersion: "2.7"
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
RSpec/FilePath:
|
|
12
|
+
Enabled: false
|
|
13
|
+
Lint/EmptyBlock:
|
|
8
14
|
Enabled: false
|
|
9
|
-
|
data/Gemfile.lock
CHANGED
|
@@ -1,96 +1,82 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
grpcx (0.
|
|
4
|
+
grpcx (0.3.2)
|
|
5
5
|
activesupport (>= 5.0)
|
|
6
6
|
grpc (>= 1.8.0)
|
|
7
7
|
|
|
8
8
|
GEM
|
|
9
9
|
remote: https://rubygems.org/
|
|
10
10
|
specs:
|
|
11
|
-
activemodel (
|
|
12
|
-
activesupport (=
|
|
13
|
-
activerecord (
|
|
14
|
-
activemodel (=
|
|
15
|
-
activesupport (=
|
|
16
|
-
|
|
17
|
-
activesupport (5.2.0)
|
|
11
|
+
activemodel (7.0.1)
|
|
12
|
+
activesupport (= 7.0.1)
|
|
13
|
+
activerecord (7.0.1)
|
|
14
|
+
activemodel (= 7.0.1)
|
|
15
|
+
activesupport (= 7.0.1)
|
|
16
|
+
activesupport (7.0.1)
|
|
18
17
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
19
|
-
i18n (>=
|
|
20
|
-
minitest (
|
|
21
|
-
tzinfo (~>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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)
|
|
18
|
+
i18n (>= 1.6, < 2)
|
|
19
|
+
minitest (>= 5.1)
|
|
20
|
+
tzinfo (~> 2.0)
|
|
21
|
+
ast (2.4.2)
|
|
22
|
+
concurrent-ruby (1.1.9)
|
|
23
|
+
diff-lcs (1.5.0)
|
|
24
|
+
google-protobuf (3.19.2)
|
|
25
|
+
googleapis-common-protos-types (1.3.0)
|
|
26
|
+
google-protobuf (~> 3.14)
|
|
27
|
+
grpc (1.42.0)
|
|
28
|
+
google-protobuf (~> 3.18)
|
|
29
|
+
googleapis-common-protos-types (~> 1.0)
|
|
30
|
+
i18n (1.8.11)
|
|
46
31
|
concurrent-ruby (~> 1.0)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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)
|
|
32
|
+
minitest (5.15.0)
|
|
33
|
+
parallel (1.21.0)
|
|
34
|
+
parser (3.1.0.0)
|
|
35
|
+
ast (~> 2.4.1)
|
|
62
36
|
rainbow (3.0.0)
|
|
63
|
-
rake (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
rspec-
|
|
68
|
-
|
|
69
|
-
rspec-
|
|
70
|
-
rspec-
|
|
37
|
+
rake (13.0.6)
|
|
38
|
+
regexp_parser (2.2.0)
|
|
39
|
+
rexml (3.2.5)
|
|
40
|
+
rspec (3.10.0)
|
|
41
|
+
rspec-core (~> 3.10.0)
|
|
42
|
+
rspec-expectations (~> 3.10.0)
|
|
43
|
+
rspec-mocks (~> 3.10.0)
|
|
44
|
+
rspec-core (3.10.1)
|
|
45
|
+
rspec-support (~> 3.10.0)
|
|
46
|
+
rspec-expectations (3.10.1)
|
|
71
47
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
72
|
-
rspec-support (~> 3.
|
|
73
|
-
rspec-mocks (3.
|
|
48
|
+
rspec-support (~> 3.10.0)
|
|
49
|
+
rspec-mocks (3.10.2)
|
|
74
50
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
75
|
-
rspec-support (~> 3.
|
|
76
|
-
rspec-support (3.
|
|
77
|
-
rubocop (
|
|
51
|
+
rspec-support (~> 3.10.0)
|
|
52
|
+
rspec-support (3.10.3)
|
|
53
|
+
rubocop (1.24.1)
|
|
78
54
|
parallel (~> 1.10)
|
|
79
|
-
parser (>=
|
|
80
|
-
powerpack (~> 0.1)
|
|
55
|
+
parser (>= 3.0.0.0)
|
|
81
56
|
rainbow (>= 2.2.2, < 4.0)
|
|
57
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
58
|
+
rexml
|
|
59
|
+
rubocop-ast (>= 1.15.1, < 2.0)
|
|
82
60
|
ruby-progressbar (~> 1.7)
|
|
83
|
-
unicode-display_width (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
61
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
|
62
|
+
rubocop-ast (1.15.1)
|
|
63
|
+
parser (>= 3.0.1.1)
|
|
64
|
+
rubocop-bsm (0.6.0)
|
|
65
|
+
rubocop (~> 1.0)
|
|
66
|
+
rubocop-performance
|
|
67
|
+
rubocop-rake
|
|
68
|
+
rubocop-rspec
|
|
69
|
+
rubocop-performance (1.13.1)
|
|
70
|
+
rubocop (>= 1.7.0, < 2.0)
|
|
71
|
+
rubocop-ast (>= 0.4.0)
|
|
72
|
+
rubocop-rake (0.6.0)
|
|
73
|
+
rubocop (~> 1.0)
|
|
74
|
+
rubocop-rspec (2.7.0)
|
|
75
|
+
rubocop (~> 1.19)
|
|
76
|
+
ruby-progressbar (1.11.0)
|
|
77
|
+
tzinfo (2.0.4)
|
|
78
|
+
concurrent-ruby (~> 1.0)
|
|
79
|
+
unicode-display_width (2.1.0)
|
|
94
80
|
|
|
95
81
|
PLATFORMS
|
|
96
82
|
ruby
|
|
@@ -101,7 +87,7 @@ DEPENDENCIES
|
|
|
101
87
|
grpcx!
|
|
102
88
|
rake
|
|
103
89
|
rspec
|
|
104
|
-
rubocop
|
|
90
|
+
rubocop-bsm
|
|
105
91
|
|
|
106
92
|
BUNDLED WITH
|
|
107
|
-
|
|
93
|
+
2.2.27
|
data/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# grpcx
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/bsm/grpcx/actions/workflows/test.yml)
|
|
4
4
|
|
|
5
|
+
Ruby gRPC extensions/helpers
|
|
5
6
|
|
|
6
7
|
# Grpcx::Server
|
|
7
8
|
|
|
@@ -9,10 +10,9 @@ Mixin for `GRPC::RpcServer`:
|
|
|
9
10
|
|
|
10
11
|
- handles [GRPC health checks](https://github.com/grpc/grpc/blob/master/doc/health-checking.md) requests
|
|
11
12
|
- handles `ActiveRecord` connection (auto-connect + pooling)
|
|
12
|
-
- instruments each request with `ActiveSupport::Notifications` (available as `process_action.grpc`, includes `action:
|
|
13
|
+
- instruments each request with `ActiveSupport::Notifications` (available as `process_action.grpc`, includes `service: 'package.name.ServiceName', action: 'underscored_action_name'` data)
|
|
13
14
|
- includes `ActiveSupport::Rescuable` and transforms most common `ActiveRecord::ActiveRecordError`-s into `GRPC::BadStatus` ones
|
|
14
15
|
|
|
15
|
-
|
|
16
16
|
Example:
|
|
17
17
|
|
|
18
18
|
```ruby
|
|
@@ -47,50 +47,27 @@ end
|
|
|
47
47
|
...
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
|
|
51
50
|
## Using with [Datadog::Notifications](https://github.com/bsm/datadog-notifications)
|
|
52
51
|
|
|
53
|
-
|
|
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
|
|
52
|
+
Since version >= [0.5.4](https://github.com/bsm/datadog-notifications/releases/tag/v0.5.4)
|
|
79
53
|
|
|
54
|
+
```ruby
|
|
80
55
|
Datadog::Notifications.configure do |c|
|
|
81
56
|
c.use Datadog::Notifications::Plugins::GRPC
|
|
82
57
|
end if RUNNING_IN_PROD?
|
|
83
58
|
```
|
|
84
59
|
|
|
85
|
-
|
|
86
60
|
## Using with [Sentry](https://sentry.io/)/[Raven](https://github.com/getsentry/raven-ruby)
|
|
87
61
|
|
|
88
62
|
```ruby
|
|
89
|
-
ActiveSupport::Notifications.subscribe(
|
|
63
|
+
ActiveSupport::Notifications.subscribe(Grpcx::Server::Interceptors::Instrumentation::METRIC_NAME) do |_name, _start, _finish, _id, payload|
|
|
90
64
|
e = payload[:exception_object]
|
|
91
65
|
next unless e
|
|
92
66
|
|
|
93
|
-
Raven.capture_exception(e
|
|
67
|
+
Raven.capture_exception(e, extra: {
|
|
68
|
+
'service' => payload[:service],
|
|
69
|
+
'action' => payload[:action],
|
|
70
|
+
})
|
|
94
71
|
end
|
|
95
72
|
|
|
96
73
|
Raven.configure do |config|
|
data/grpcx.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = 'grpcx'
|
|
3
|
-
s.version = '0.
|
|
3
|
+
s.version = '0.3.2'
|
|
4
4
|
s.authors = ['Black Square Media Ltd']
|
|
5
5
|
s.email = ['info@blacksquaremedia.com']
|
|
6
6
|
s.summary = %(gRPC extensions/helpers)
|
|
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
|
11
11
|
s.files = `git ls-files -z`.split("\x0").reject {|f| f.match(%r{^spec/}) }
|
|
12
12
|
s.test_files = `git ls-files -z -- spec/*`.split("\x0")
|
|
13
13
|
s.require_paths = ['lib']
|
|
14
|
-
s.required_ruby_version = '>= 2.
|
|
14
|
+
s.required_ruby_version = '>= 2.7'
|
|
15
15
|
|
|
16
16
|
s.add_dependency 'activesupport', '>= 5.0'
|
|
17
17
|
s.add_dependency 'grpc', '>= 1.8.0'
|
|
@@ -20,5 +20,6 @@ Gem::Specification.new do |s|
|
|
|
20
20
|
s.add_development_dependency 'bundler'
|
|
21
21
|
s.add_development_dependency 'rake'
|
|
22
22
|
s.add_development_dependency 'rspec'
|
|
23
|
-
s.add_development_dependency 'rubocop'
|
|
23
|
+
s.add_development_dependency 'rubocop-bsm'
|
|
24
|
+
s.metadata['rubygems_mfa_required'] = 'true'
|
|
24
25
|
end
|
data/lib/grpcx/entity.rb
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
|
2
|
+
require 'set'
|
|
3
|
+
|
|
4
|
+
module Grpcx
|
|
5
|
+
# Entity releated helpers
|
|
6
|
+
module Entity
|
|
7
|
+
def self._convert(field, value, &block)
|
|
8
|
+
field.label == :repeated ? value.map(&block) : yield(value) if value # rubocop:disable Style/IfUnlessModifierOfIfUnless
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON'].to_set.freeze
|
|
14
|
+
|
|
15
|
+
# @param [Class] msgclass messagepack message class
|
|
16
|
+
# @param [Hash] attrs attributes to assign
|
|
17
|
+
def build(msgclass, attrs = {}) # rubocop:disable Metrics/MethodLength
|
|
18
|
+
attrs = ActiveSupport::HashWithIndifferentAccess.new(attrs)
|
|
19
|
+
fields = {}
|
|
20
|
+
msgclass.descriptor.each do |field| # rubocop:disable Metrics/BlockLength
|
|
21
|
+
next unless attrs.key?(field.name)
|
|
22
|
+
|
|
23
|
+
source = attrs[field.name]
|
|
24
|
+
target = nil
|
|
25
|
+
|
|
26
|
+
case field.type
|
|
27
|
+
when :int64, :int32
|
|
28
|
+
target = Entity._convert(field, source, &:to_i)
|
|
29
|
+
when :float, :double
|
|
30
|
+
target = Entity._convert(field, source, &:to_f)
|
|
31
|
+
when :string
|
|
32
|
+
target = Entity._convert(field, source, &:to_s)
|
|
33
|
+
when :bool
|
|
34
|
+
target = Entity._convert(field, source) do |vv|
|
|
35
|
+
TRUE_VALUES.include?(vv)
|
|
36
|
+
end
|
|
37
|
+
when :enum
|
|
38
|
+
target = Entity._convert(field, source) do |vv|
|
|
39
|
+
case vv
|
|
40
|
+
when Integer
|
|
41
|
+
vv
|
|
42
|
+
when String, Symbol
|
|
43
|
+
field.subtype.lookup_name(vv.to_s.upcase.to_sym)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
when :message
|
|
47
|
+
target = Entity._convert(field, source) do |vv|
|
|
48
|
+
build(field.subtype.msgclass, vv)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
fields[field.name] = target if target
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
msgclass.new(fields)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -5,7 +5,6 @@ module Grpcx
|
|
|
5
5
|
# making sure that connection is established before each request
|
|
6
6
|
# and re-pooling connections when request is processed.
|
|
7
7
|
class ActiveRecord < GRPC::ServerInterceptor
|
|
8
|
-
|
|
9
8
|
def request_response(*, &block)
|
|
10
9
|
wrap(&block)
|
|
11
10
|
end
|
|
@@ -30,7 +29,6 @@ module Grpcx
|
|
|
30
29
|
ensure
|
|
31
30
|
::ActiveRecord::Base.clear_active_connections!
|
|
32
31
|
end
|
|
33
|
-
|
|
34
32
|
end
|
|
35
33
|
end
|
|
36
34
|
end
|
|
@@ -6,28 +6,29 @@ module Grpcx
|
|
|
6
6
|
class Instrumentation < GRPC::ServerInterceptor
|
|
7
7
|
METRIC_NAME = 'process_action.grpc'.freeze
|
|
8
8
|
|
|
9
|
-
def request_response(opts={}, &block)
|
|
10
|
-
instrument(
|
|
9
|
+
def request_response(opts = {}, &block)
|
|
10
|
+
instrument(opts[:method], &block)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def client_streamer(opts={}, &block)
|
|
14
|
-
instrument(
|
|
13
|
+
def client_streamer(opts = {}, &block)
|
|
14
|
+
instrument(opts[:method], &block)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def server_streamer(opts={}, &block)
|
|
18
|
-
instrument(
|
|
17
|
+
def server_streamer(opts = {}, &block)
|
|
18
|
+
instrument(opts[:method], &block)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def bidi_streamer(opts={}, &block)
|
|
22
|
-
instrument(
|
|
21
|
+
def bidi_streamer(opts = {}, &block)
|
|
22
|
+
instrument(opts[:method], &block)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
private
|
|
26
26
|
|
|
27
|
-
def instrument(
|
|
28
|
-
|
|
27
|
+
def instrument(method, &block)
|
|
28
|
+
service = method.owner.service_name # method is just a standard ruby Method class, so `owner` is a service impl
|
|
29
|
+
action = method.name # does not match real proto service name; it's a GRPC::GenericService.underscore-d version
|
|
30
|
+
ActiveSupport::Notifications.instrument(METRIC_NAME, service: service, action: action, &block)
|
|
29
31
|
end
|
|
30
|
-
|
|
31
32
|
end
|
|
32
33
|
end
|
|
33
34
|
end
|
|
@@ -2,35 +2,34 @@ module Grpcx
|
|
|
2
2
|
module Server
|
|
3
3
|
module Interceptors
|
|
4
4
|
class Rescue < GRPC::ServerInterceptor
|
|
5
|
-
def initialize(rescuable, opts={})
|
|
5
|
+
def initialize(rescuable, opts = {})
|
|
6
6
|
@rescuable = rescuable
|
|
7
7
|
super(opts)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def request_response(*)
|
|
11
11
|
yield
|
|
12
|
-
rescue StandardError =>
|
|
13
|
-
@rescuable.rescue_with_handler(
|
|
12
|
+
rescue StandardError => e
|
|
13
|
+
@rescuable.rescue_with_handler(e) || raise
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def client_streamer(*)
|
|
17
17
|
yield
|
|
18
|
-
rescue StandardError =>
|
|
19
|
-
@rescuable.rescue_with_handler(
|
|
18
|
+
rescue StandardError => e
|
|
19
|
+
@rescuable.rescue_with_handler(e) || raise
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def server_streamer(*)
|
|
23
23
|
yield
|
|
24
|
-
rescue StandardError =>
|
|
25
|
-
@rescuable.rescue_with_handler(
|
|
24
|
+
rescue StandardError => e
|
|
25
|
+
@rescuable.rescue_with_handler(e) || raise
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def bidi_streamer(*)
|
|
29
29
|
yield
|
|
30
|
-
rescue StandardError =>
|
|
31
|
-
@rescuable.rescue_with_handler(
|
|
30
|
+
rescue StandardError => e
|
|
31
|
+
@rescuable.rescue_with_handler(e) || raise
|
|
32
32
|
end
|
|
33
|
-
|
|
34
33
|
end
|
|
35
34
|
end
|
|
36
35
|
end
|
data/lib/grpcx/server.rb
CHANGED
|
@@ -22,7 +22,7 @@ module Grpcx
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
def initialize(opts
|
|
25
|
+
def initialize(**opts)
|
|
26
26
|
opts[:pool_size] ||= ENV['GRPC_SERVER_THREADS'].to_i if ENV['GRPC_SERVER_THREADS']
|
|
27
27
|
opts[:max_waiting_requests] ||= ENV['GRPC_SERVER_QUEUE'].to_i if ENV['GRPC_SERVER_QUEUE']
|
|
28
28
|
|
|
@@ -32,7 +32,7 @@ module Grpcx
|
|
|
32
32
|
opts[:interceptors].prepend Grpcx::Server::Interceptors::Instrumentation.new
|
|
33
33
|
opts[:interceptors].prepend Grpcx::Server::Interceptors::ActiveRecord.new if defined?(::ActiveRecord)
|
|
34
34
|
|
|
35
|
-
super
|
|
35
|
+
super.tap do
|
|
36
36
|
handle(health)
|
|
37
37
|
end
|
|
38
38
|
end
|
data/lib/grpcx.rb
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Grpcx::Entity do
|
|
4
|
+
it 'builds messages' do
|
|
5
|
+
msg = described_class.build Grpcx::Spec::Message,
|
|
6
|
+
name: 'Name',
|
|
7
|
+
version: 1,
|
|
8
|
+
types: {
|
|
9
|
+
num: 8,
|
|
10
|
+
truth: [1, 0, true, 'true'],
|
|
11
|
+
decimal: '1.2',
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
expect(msg.to_h).to eq(
|
|
15
|
+
name: 'Name',
|
|
16
|
+
version: :V1,
|
|
17
|
+
types: {
|
|
18
|
+
num: 8,
|
|
19
|
+
truth: [true, false, true, true],
|
|
20
|
+
decimal: 1.2,
|
|
21
|
+
},
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
end
|
data/spec/lib/server_spec.rb
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
RSpec.describe Grpcx::Server do
|
|
4
|
-
|
|
5
4
|
subject do
|
|
6
5
|
s = Grpcx::Spec::Server.new
|
|
7
6
|
s.handle Grpcx::Spec::Service::V1
|
|
8
7
|
s
|
|
9
8
|
end
|
|
10
9
|
|
|
11
|
-
it '
|
|
10
|
+
it 'has a health-check' do
|
|
12
11
|
expect(subject.health).to be_a(Grpc::Health::Checker)
|
|
13
12
|
expect(subject.health.instance_variable_get(:@statuses)).to eq(
|
|
14
13
|
'grpcx.spec.service.V1' => 1,
|
|
@@ -16,14 +15,14 @@ RSpec.describe Grpcx::Server do
|
|
|
16
15
|
)
|
|
17
16
|
end
|
|
18
17
|
|
|
19
|
-
it '
|
|
18
|
+
it 'has interceptors' do
|
|
20
19
|
expect(subject.interceptors).to be_a(GRPC::InterceptorRegistry)
|
|
21
20
|
|
|
22
21
|
registered = subject.interceptors.instance_variable_get(:@interceptors)
|
|
23
22
|
expect(registered.size).to eq(3)
|
|
24
23
|
end
|
|
25
24
|
|
|
26
|
-
it '
|
|
25
|
+
it 'has rescue handlers' do
|
|
27
26
|
expect(subject.rescue_handlers.size).to eq(3)
|
|
28
27
|
expect(subject.rescue_handlers.map(&:first)).to match_array %w[
|
|
29
28
|
ActiveRecord::RecordInvalid
|
|
@@ -31,5 +30,4 @@ RSpec.describe Grpcx::Server do
|
|
|
31
30
|
ArgumentError
|
|
32
31
|
]
|
|
33
32
|
end
|
|
34
|
-
|
|
35
33
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -4,22 +4,30 @@ require 'active_record'
|
|
|
4
4
|
require 'google/protobuf'
|
|
5
5
|
|
|
6
6
|
Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
7
|
-
add_message
|
|
7
|
+
add_message 'grpcx.spec.Message' do
|
|
8
8
|
optional :name, :string, 1
|
|
9
|
+
optional :version, :enum, 2, 'grpcx.spec.Version'
|
|
10
|
+
optional :types, :message, 3, 'grpcx.spec.Types'
|
|
9
11
|
end
|
|
10
|
-
|
|
12
|
+
add_message 'grpcx.spec.Types' do
|
|
13
|
+
optional :num, :int64, 1
|
|
14
|
+
repeated :truth, :bool, 2
|
|
15
|
+
optional :decimal, :double, 3
|
|
16
|
+
end
|
|
17
|
+
add_enum 'grpcx.spec.Version' do
|
|
11
18
|
value :V0, 0
|
|
12
19
|
value :V1, 1
|
|
13
20
|
value :V2, 2
|
|
14
21
|
end
|
|
15
|
-
add_message
|
|
22
|
+
add_message 'grpcx.spec.GetMessageRequest' do
|
|
16
23
|
end
|
|
17
24
|
end
|
|
18
25
|
|
|
19
26
|
module Grpcx::Spec
|
|
20
|
-
Message = Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
Message = Google::Protobuf::DescriptorPool.generated_pool.lookup('grpcx.spec.Message').msgclass
|
|
28
|
+
Version = Google::Protobuf::DescriptorPool.generated_pool.lookup('grpcx.spec.Version').enummodule
|
|
29
|
+
Types = Google::Protobuf::DescriptorPool.generated_pool.lookup('grpcx.spec.Types').msgclass
|
|
30
|
+
GetMessageRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup('grpcx.spec.GetMessageRequest').msgclass
|
|
23
31
|
|
|
24
32
|
module Service
|
|
25
33
|
class V1
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: grpcx
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Black Square Media Ltd
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-01-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -95,7 +95,7 @@ dependencies:
|
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: '0'
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name: rubocop
|
|
98
|
+
name: rubocop-bsm
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
100
100
|
requirements:
|
|
101
101
|
- - ">="
|
|
@@ -116,6 +116,7 @@ extensions: []
|
|
|
116
116
|
extra_rdoc_files: []
|
|
117
117
|
files:
|
|
118
118
|
- ".editorconfig"
|
|
119
|
+
- ".github/workflows/test.yml"
|
|
119
120
|
- ".gitignore"
|
|
120
121
|
- ".rubocop.yml"
|
|
121
122
|
- Gemfile
|
|
@@ -124,17 +125,20 @@ files:
|
|
|
124
125
|
- Rakefile
|
|
125
126
|
- grpcx.gemspec
|
|
126
127
|
- lib/grpcx.rb
|
|
128
|
+
- lib/grpcx/entity.rb
|
|
127
129
|
- lib/grpcx/server.rb
|
|
128
130
|
- lib/grpcx/server/interceptors.rb
|
|
129
131
|
- lib/grpcx/server/interceptors/active_record.rb
|
|
130
132
|
- lib/grpcx/server/interceptors/instrumentation.rb
|
|
131
133
|
- lib/grpcx/server/interceptors/rescue.rb
|
|
134
|
+
- spec/lib/entity_spec.rb
|
|
132
135
|
- spec/lib/server_spec.rb
|
|
133
136
|
- spec/spec_helper.rb
|
|
134
137
|
homepage: https://github.com/bsm/grpcx
|
|
135
138
|
licenses:
|
|
136
139
|
- MIT
|
|
137
|
-
metadata:
|
|
140
|
+
metadata:
|
|
141
|
+
rubygems_mfa_required: 'true'
|
|
138
142
|
post_install_message:
|
|
139
143
|
rdoc_options: []
|
|
140
144
|
require_paths:
|
|
@@ -143,18 +147,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
143
147
|
requirements:
|
|
144
148
|
- - ">="
|
|
145
149
|
- !ruby/object:Gem::Version
|
|
146
|
-
version: '2.
|
|
150
|
+
version: '2.7'
|
|
147
151
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
152
|
requirements:
|
|
149
153
|
- - ">="
|
|
150
154
|
- !ruby/object:Gem::Version
|
|
151
155
|
version: '0'
|
|
152
156
|
requirements: []
|
|
153
|
-
|
|
154
|
-
rubygems_version: 2.7.3
|
|
157
|
+
rubygems_version: 3.2.15
|
|
155
158
|
signing_key:
|
|
156
159
|
specification_version: 4
|
|
157
160
|
summary: gRPC extensions/helpers
|
|
158
161
|
test_files:
|
|
162
|
+
- spec/lib/entity_spec.rb
|
|
159
163
|
- spec/lib/server_spec.rb
|
|
160
164
|
- spec/spec_helper.rb
|