grpcx 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e6bcd16e9fceffd33f50eb1f4329ce55b9c983ff434f8688cbc2cf2432012d0
4
- data.tar.gz: 79fb5b99a06087b37e0a8af8c36c13eebaf07b81a797459144b144adcecc3e07
3
+ metadata.gz: a99773353852adc153af1cda72a8c17e980687c69127bb9a7830d983fd4a052d
4
+ data.tar.gz: 415a8d6f395db5283f57c9756ed47483560b8b1365ff224090a88f6a5dba02b1
5
5
  SHA512:
6
- metadata.gz: e19042030a742d1f985dde51ef366402bbd062c3fe4f2d17d987c6dbc40db0cf069ad61f746648291987d0011b38d28f757e3dd8b9b5bdcdff738ba34029b228
7
- data.tar.gz: a79ba2d070d331afa74b95f439f0cfa0fa243d2e5c6b11186d3175374f3a435b304082ad67ec2ba34230415dda06add606101b0762ed8823b36b4c4c19448443
6
+ metadata.gz: 8a92a53f2e0fe302482ca483f4434a35f274045d97ebc77c63e11a425f3c591d31bbcbdec2ed013a0c296fefbaf9ad514ecdc45ad8dbfc9143acde905d767933
7
+ data.tar.gz: 775e2e820a35bc874ab36090e3328c72954545653d5dec0a02ee3608aa4b836d88742b17b49a0845dc8e5897db6871464e9978b87f704a03819f23c4bd21971b
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  .rubocop-*
2
+ .rake_tasks~
2
3
  pkg/
@@ -1,96 +1,70 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grpcx (0.1.1)
4
+ grpcx (0.2.0)
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 (5.2.0)
12
- activesupport (= 5.2.0)
13
- activerecord (5.2.0)
14
- activemodel (= 5.2.0)
15
- activesupport (= 5.2.0)
11
+ activemodel (5.2.1)
12
+ activesupport (= 5.2.1)
13
+ activerecord (5.2.1)
14
+ activemodel (= 5.2.1)
15
+ activesupport (= 5.2.1)
16
16
  arel (>= 9.0)
17
- activesupport (5.2.0)
17
+ activesupport (5.2.1)
18
18
  concurrent-ruby (~> 1.0, >= 1.0.2)
19
19
  i18n (>= 0.7, < 2)
20
20
  minitest (~> 5.1)
21
21
  tzinfo (~> 1.1)
22
- addressable (2.5.2)
23
- public_suffix (>= 2.0.2, < 4.0)
24
22
  arel (9.0.0)
25
23
  ast (2.4.0)
26
24
  concurrent-ruby (1.0.5)
27
25
  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)
26
+ google-protobuf (3.6.1)
27
+ googleapis-common-protos-types (1.0.2)
32
28
  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)
29
+ grpc (1.14.2)
42
30
  google-protobuf (~> 3.1)
43
31
  googleapis-common-protos-types (~> 1.0.0)
44
- googleauth (>= 0.5.1, < 0.7)
45
- i18n (1.0.1)
32
+ i18n (1.1.0)
46
33
  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)
34
+ jaro_winkler (1.5.1)
53
35
  minitest (5.11.3)
54
- multi_json (1.13.1)
55
- multipart-post (2.0.0)
56
- os (0.9.6)
57
36
  parallel (1.12.1)
58
- parser (2.5.1.0)
37
+ parser (2.5.1.2)
59
38
  ast (~> 2.4.0)
60
- powerpack (0.1.1)
61
- public_suffix (3.0.2)
39
+ powerpack (0.1.2)
62
40
  rainbow (3.0.0)
63
41
  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)
42
+ rspec (3.8.0)
43
+ rspec-core (~> 3.8.0)
44
+ rspec-expectations (~> 3.8.0)
45
+ rspec-mocks (~> 3.8.0)
46
+ rspec-core (3.8.0)
47
+ rspec-support (~> 3.8.0)
48
+ rspec-expectations (3.8.1)
71
49
  diff-lcs (>= 1.2.0, < 2.0)
72
- rspec-support (~> 3.7.0)
73
- rspec-mocks (3.7.0)
50
+ rspec-support (~> 3.8.0)
51
+ rspec-mocks (3.8.0)
74
52
  diff-lcs (>= 1.2.0, < 2.0)
75
- rspec-support (~> 3.7.0)
76
- rspec-support (3.7.1)
77
- rubocop (0.55.0)
53
+ rspec-support (~> 3.8.0)
54
+ rspec-support (3.8.0)
55
+ rubocop (0.59.0)
56
+ jaro_winkler (~> 1.5.1)
78
57
  parallel (~> 1.10)
79
- parser (>= 2.5)
58
+ parser (>= 2.5, != 2.5.1.1)
80
59
  powerpack (~> 0.1)
81
60
  rainbow (>= 2.2.2, < 4.0)
82
61
  ruby-progressbar (~> 1.7)
83
62
  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)
63
+ ruby-progressbar (1.10.0)
90
64
  thread_safe (0.3.6)
91
65
  tzinfo (1.2.5)
92
66
  thread_safe (~> 0.1)
93
- unicode-display_width (1.3.2)
67
+ unicode-display_width (1.4.0)
94
68
 
95
69
  PLATFORMS
96
70
  ruby
@@ -104,4 +78,4 @@ DEPENDENCIES
104
78
  rubocop
105
79
 
106
80
  BUNDLED WITH
107
- 1.16.1
81
+ 1.16.4
data/README.md CHANGED
@@ -9,7 +9,7 @@ Mixin for `GRPC::RpcServer`:
9
9
 
10
10
  - handles [GRPC health checks](https://github.com/grpc/grpc/blob/master/doc/health-checking.md) requests
11
11
  - handles `ActiveRecord` connection (auto-connect + pooling)
12
- - instruments each request with `ActiveSupport::Notifications` (available as `process_action.grpc`, includes `action: METHOD_NAME` data)
12
+ - instruments each request with `ActiveSupport::Notifications` (available as `process_action.grpc`, includes `service: 'package.name.ServiceName', action: 'underscored_action_name'` data)
13
13
  - includes `ActiveSupport::Rescuable` and transforms most common `ActiveRecord::ActiveRecordError`-s into `GRPC::BadStatus` ones
14
14
 
15
15
 
@@ -51,12 +51,13 @@ end
51
51
  ## Using with [Datadog::Notifications](https://github.com/bsm/datadog-notifications)
52
52
 
53
53
  ```ruby
54
+ # TODO: update this in datadog-notifications gem itself (to handle new service/action payloads)
54
55
  module Datadog::Notifications::Plugins
55
- class GRPC < Base
56
+ class MyGRPC < Base
56
57
 
57
58
  def initialize(opts={})
58
59
  super
59
- Datadog::Notifications.subscribe 'process_action.grpc' do |reporter, event|
60
+ Datadog::Notifications.subscribe(Grpcx::Server::Interceptors::Instrumentation::METRIC_NAME) do |reporter, event|
60
61
  record(reporter, event)
61
62
  end
62
63
  end
@@ -64,9 +65,10 @@ module Datadog::Notifications::Plugins
64
65
  private
65
66
 
66
67
  def record(reporter, event)
67
- action = event.payload[:action]
68
- status = event.payload[:exception] ? 'error' : 'ok'
69
- tags = self.tags + ["rpc:#{action}", "status:#{status}"]
68
+ service = event.payload[:service]
69
+ action = event.payload[:action]
70
+ status = event.payload[:exception] ? 'error' : 'ok'
71
+ tags = self.tags + %W[service:#{service} action:#{action} status:#{status}]
70
72
 
71
73
  reporter.batch do
72
74
  reporter.increment 'grpc.request', tags: tags
@@ -78,7 +80,7 @@ module Datadog::Notifications::Plugins
78
80
  end
79
81
 
80
82
  Datadog::Notifications.configure do |c|
81
- c.use Datadog::Notifications::Plugins::GRPC
83
+ c.use Datadog::Notifications::Plugins::MyGRPC
82
84
  end if RUNNING_IN_PROD?
83
85
  ```
84
86
 
@@ -86,11 +88,14 @@ end if RUNNING_IN_PROD?
86
88
  ## Using with [Sentry](https://sentry.io/)/[Raven](https://github.com/getsentry/raven-ruby)
87
89
 
88
90
  ```ruby
89
- ActiveSupport::Notifications.subscribe('process_action.grpc') do |_name, _start, _finish, _id, payload|
91
+ ActiveSupport::Notifications.subscribe(Grpcx::Server::Interceptors::Instrumentation::METRIC_NAME) do |_name, _start, _finish, _id, payload|
90
92
  e = payload[:exception_object]
91
93
  next unless e
92
94
 
93
- Raven.capture_exception(e)
95
+ Raven.capture_exception(e, extra: {
96
+ 'service' => payload[:service],
97
+ 'action' => payload[:action],
98
+ })
94
99
  end
95
100
 
96
101
  Raven.configure do |config|
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'grpcx'
3
- s.version = '0.1.1'
3
+ s.version = '0.2.0'
4
4
  s.authors = ['Black Square Media Ltd']
5
5
  s.email = ['info@blacksquaremedia.com']
6
6
  s.summary = %(gRPC extensions/helpers)
@@ -1 +1,2 @@
1
1
  require 'grpcx/server'
2
+ require 'grpcx/entity'
@@ -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/CyclomaticComplexity, 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
@@ -7,25 +7,27 @@ module Grpcx
7
7
  METRIC_NAME = 'process_action.grpc'.freeze
8
8
 
9
9
  def request_response(opts={}, &block)
10
- instrument(action: opts[:method], &block)
10
+ instrument(opts[:method], &block)
11
11
  end
12
12
 
13
13
  def client_streamer(opts={}, &block)
14
- instrument(action: opts[:method], &block)
14
+ instrument(opts[:method], &block)
15
15
  end
16
16
 
17
17
  def server_streamer(opts={}, &block)
18
- instrument(action: opts[:method], &block)
18
+ instrument(opts[:method], &block)
19
19
  end
20
20
 
21
21
  def bidi_streamer(opts={}, &block)
22
- instrument(action: opts[:method], &block)
22
+ instrument(opts[:method], &block)
23
23
  end
24
24
 
25
25
  private
26
26
 
27
- def instrument(opts={}, &block)
28
- ActiveSupport::Notifications.instrument(METRIC_NAME, opts, &block)
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
32
 
31
33
  end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Grpcx::Entity do
4
+
5
+ it 'should build messages' do
6
+ msg = described_class.build Grpcx::Spec::Message,
7
+ name: 'Name',
8
+ version: 1,
9
+ types: {
10
+ num: 8,
11
+ truth: [1, 0, true, 'true'],
12
+ decimal: '1.2',
13
+ }
14
+
15
+ expect(msg.to_h).to eq(
16
+ name: "Name",
17
+ version: :V1,
18
+ types: {
19
+ num: 8,
20
+ truth: [true, false, true, true],
21
+ decimal: 1.2,
22
+ },
23
+ )
24
+ end
25
+
26
+ end
@@ -6,8 +6,15 @@ require 'google/protobuf'
6
6
  Google::Protobuf::DescriptorPool.generated_pool.build do
7
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
- add_enum "grpcx.spec.Enum" do
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
@@ -18,7 +25,8 @@ end
18
25
 
19
26
  module Grpcx::Spec
20
27
  Message = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpcx.spec.Message").msgclass
21
- Enum = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpcx.spec.Enum").enummodule
28
+ Version = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpcx.spec.Version").enummodule
29
+ Types = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpcx.spec.Types").msgclass
22
30
  GetMessageRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpcx.spec.GetMessageRequest").msgclass
23
31
 
24
32
  module Service
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.1.1
4
+ version: 0.2.0
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: 2018-05-10 00:00:00.000000000 Z
11
+ date: 2018-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -124,11 +124,13 @@ files:
124
124
  - Rakefile
125
125
  - grpcx.gemspec
126
126
  - lib/grpcx.rb
127
+ - lib/grpcx/entity.rb
127
128
  - lib/grpcx/server.rb
128
129
  - lib/grpcx/server/interceptors.rb
129
130
  - lib/grpcx/server/interceptors/active_record.rb
130
131
  - lib/grpcx/server/interceptors/instrumentation.rb
131
132
  - lib/grpcx/server/interceptors/rescue.rb
133
+ - spec/lib/entity_spec.rb
132
134
  - spec/lib/server_spec.rb
133
135
  - spec/spec_helper.rb
134
136
  homepage: https://github.com/bsm/grpcx
@@ -151,10 +153,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
153
  version: '0'
152
154
  requirements: []
153
155
  rubyforge_project:
154
- rubygems_version: 2.7.3
156
+ rubygems_version: 2.7.6
155
157
  signing_key:
156
158
  specification_version: 4
157
159
  summary: gRPC extensions/helpers
158
160
  test_files:
161
+ - spec/lib/entity_spec.rb
159
162
  - spec/lib/server_spec.rb
160
163
  - spec/spec_helper.rb