rails_twirp 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8df8457b09993d7d5c986130e724948df049c201b6797f33a7b66458bde98918
4
- data.tar.gz: 0a2100cbefd37754f9dbd6cf666def1c29d0936322f72837d7e60653b5510b79
3
+ metadata.gz: 34fc8b4e84ba8c456ac2fa01c3c35dd0fd11224360d6e21b832b5d17ed1f57a5
4
+ data.tar.gz: 9626b771c35bfdd034fa1dccad6ef5ed921aad0abdf3086bfe27a6b3b26f50b9
5
5
  SHA512:
6
- metadata.gz: 1b50c23cd6fa8852686ca96066c0a65a532f06ec0225b5ed04ac860218760d187e868d0b3d499855527ed23d355dacf8bf33eb1aaf2fd1b590b29aa12c8e836a
7
- data.tar.gz: 461fe47bbafdd0bcf304f48b4938f307fd380d7bbce7049a703c60f7bc781b0f58b1cf06b7410c4a168e39441b1a9bd49b5091a0dbfc3472870c002bef6f51e1
6
+ metadata.gz: e4621381feff50a031faf89079aa49054d246bd52f0e9d0fe4fe588f3014c2dd9a779f249aa16ac15340d9e259b61e273b393dd6a69ecaa15b5bf76c29578434
7
+ data.tar.gz: e91d714d2ef9c5e6a45e34911a29de4c1927d2e8442c5bf3538c5c43f137c10010b0282d9a5f2d4c5901d9c1733191cd0e7ff4e2764d8ae546233798ef81d64b
data/lib/rails_twirp.rb CHANGED
@@ -4,6 +4,7 @@ require "rails_twirp/application"
4
4
  require "rails_twirp/base"
5
5
  require "rails_twirp/route_set"
6
6
  require "rails_twirp/testing/integration_test"
7
+ require "rails_twirp/log_subscriber"
7
8
 
8
9
  module RailsTwirp
9
10
  mattr_accessor :test_app
@@ -10,6 +10,8 @@ require "abstract_controller/callbacks"
10
10
  require "action_controller/metal/helpers"
11
11
  require "rails_twirp/rescue"
12
12
  require "rails_twirp/url_for"
13
+ require "rails_twirp/implicit_render"
14
+ require "rails_twirp/instrumentation"
13
15
 
14
16
  module RailsTwirp
15
17
  class Base < AbstractController::Base
@@ -24,15 +26,16 @@ module RailsTwirp
24
26
  include UrlFor
25
27
  include AbstractController::AssetPaths
26
28
  include AbstractController::Caching
27
- include AbstractController::Logger
28
29
 
29
30
  include ActionView::Rendering
30
31
  include RenderPb
31
32
  include Errors
33
+ include ImplicitRender
32
34
 
33
35
  # These need to be last so errors can be handled as early as possible.
34
36
  include AbstractController::Callbacks
35
37
  include Rescue
38
+ include Instrumentation
36
39
 
37
40
  attr_internal :request, :env, :response_class
38
41
  def initialize
@@ -55,8 +58,6 @@ module RailsTwirp
55
58
 
56
59
  process(action)
57
60
 
58
- # Implicit render
59
- self.response_body = render unless response_body
60
61
  response_body
61
62
  end
62
63
 
@@ -0,0 +1,11 @@
1
+ require "action_controller/metal/basic_implicit_render"
2
+
3
+ module RailsTwirp
4
+ module ImplicitRender
5
+ include ActionController::BasicImplicitRender
6
+
7
+ def default_render
8
+ render
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ module RailsTwirp
2
+ module Instrumentation
3
+ extend ActiveSupport::Concern
4
+
5
+ include AbstractController::Logger
6
+
7
+ def process_action(*)
8
+ raw_payload = {
9
+ controller: self.class.name,
10
+ action: action_name,
11
+ request: request,
12
+ http_request: http_request,
13
+ headers: http_request.headers,
14
+ path: http_request.fullpath
15
+ }
16
+
17
+ ActiveSupport::Notifications.instrument("start_processing.rails_twirp", raw_payload)
18
+
19
+ ActiveSupport::Notifications.instrument("process_action.rails_twirp", raw_payload) do |payload|
20
+ result = super
21
+ if response_body.is_a?(Twirp::Error)
22
+ payload[:code] = response_body.code
23
+ payload[:msg] = response_body.msg
24
+ else
25
+ payload[:code] = :success
26
+ end
27
+ payload[:response] = response_body
28
+ result
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,64 @@
1
+ require "active_support/log_subscriber"
2
+
3
+ module RailsTwirp
4
+ class LogSubscriber < ActiveSupport::LogSubscriber
5
+ def start_processing(event)
6
+ return unless logger.info?
7
+
8
+ payload = event.payload
9
+
10
+ info "Processing by #{payload[:controller]}##{payload[:action]}"
11
+ end
12
+
13
+ def process_action(event)
14
+ payload = event.payload
15
+ exception_raised(payload[:http_request], payload[:exception_object]) if payload[:exception_object]
16
+
17
+ info do
18
+ code = payload.fetch(:code, :internal)
19
+
20
+ message = +"Completed #{code} in #{event.duration.round}ms (Allocations: #{event.allocations})"
21
+ message << "\n\n" if defined?(Rails.env) && Rails.env.development?
22
+
23
+ message
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def exception_raised(request, exception)
30
+ backtrace_cleaner = request.get_header("action_dispatch.backtrace_cleaner")
31
+ wrapper = ActionDispatch::ExceptionWrapper.new(backtrace_cleaner, exception)
32
+
33
+ log_error(wrapper)
34
+ end
35
+
36
+ def log_error(wrapper)
37
+ exception = wrapper.exception
38
+ trace = wrapper.exception_trace
39
+
40
+ message = []
41
+ message << " "
42
+ message << "#{exception.class} (#{exception.message}):"
43
+ message.concat(exception.annotated_source_code) if exception.respond_to?(:annotated_source_code)
44
+ message << " "
45
+ message.concat(trace)
46
+
47
+ log_array(message)
48
+ end
49
+
50
+ def log_array(array)
51
+ lines = Array(array)
52
+
53
+ return if lines.empty?
54
+
55
+ if logger.formatter&.respond_to?(:tags_text)
56
+ fatal { lines.join("\n#{logger.formatter.tags_text}") }
57
+ else
58
+ fatal { lines.join("\n") }
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ RailsTwirp::LogSubscriber.attach_to :rails_twirp
@@ -1,11 +1,17 @@
1
+ require "twirp/encoding"
2
+
1
3
  module RailsTwirp
2
4
  class IntegrationTest < ActiveSupport::TestCase
5
+ Response = Struct.new(:status, :body, :headers)
6
+
3
7
  attr_reader :response, :request, :controller
8
+ attr_writer :mount_path
4
9
 
5
10
  def initialize(name)
6
11
  super
7
12
  reset!
8
13
  @before_rpc = []
14
+ @mount_path = "/twirp"
9
15
  end
10
16
 
11
17
  def reset!
@@ -19,32 +25,59 @@ module RailsTwirp
19
25
 
20
26
  def rpc(service, rpc, request, headers: nil)
21
27
  @request = request
22
- service = app.twirp.routes.services[service].to_service
23
-
24
- rack_env = {
25
- "HTTP_HOST" => "localhost"
26
- }
27
- http_request = ActionDispatch::Request.new(rack_env)
28
- http_request.headers.merge! headers if headers.present?
29
- env = {rack_env: rack_env}
30
28
 
29
+ env = build_rack_env(service, rpc, request, headers)
31
30
  @before_rpc.each do |hook|
32
31
  hook.call(env)
33
32
  end
34
33
 
35
- response = begin
36
- service.call_rpc rpc, request, env
37
- rescue => e
38
- Twirp::Error.internal_with(e)
39
- end
34
+ status, headers, body = app.call(env)
35
+ @response = decode_rack_response(service, rpc, status, headers, body)
36
+ set_controller_from_rack_env(env)
40
37
 
41
- @response = response
42
- @controller = http_request.controller_instance
43
- response
38
+ @response
44
39
  end
45
40
 
46
41
  def app
47
42
  RailsTwirp.test_app
48
43
  end
44
+
45
+ private
46
+
47
+ def build_rack_env(service, rpc, request, headers)
48
+ env = {
49
+ "CONTENT_TYPE" => request_content_type,
50
+ "HTTP_HOST" => "localhost",
51
+ "PATH_INFO" => "#{@mount_path}/#{service.service_full_name}/#{rpc}",
52
+ "REQUEST_METHOD" => "POST"
53
+ }
54
+ if headers.present?
55
+ http_request = ActionDispatch::Request.new(env)
56
+ http_request.headers.merge! headers
57
+ end
58
+
59
+ input_class = service.rpcs[rpc][:input_class]
60
+ env["rack.input"] = StringIO.new(Twirp::Encoding.encode(request, input_class, request_content_type))
61
+ env
62
+ end
63
+
64
+ def request_content_type
65
+ Twirp::Encoding::PROTO
66
+ end
67
+
68
+ def decode_rack_response(service, rpc, status, headers, body)
69
+ body = body.join # body is an Enumerable
70
+
71
+ if status === 200
72
+ output_class = service.rpcs[rpc][:output_class]
73
+ Twirp::Encoding.decode(body, output_class, headers["Content-Type"])
74
+ else
75
+ Twirp::Client.error_from_response(Response.new(status, body, headers))
76
+ end
77
+ end
78
+
79
+ def set_controller_from_rack_env(env)
80
+ @controller = ActionDispatch::Request.new(env).controller_class
81
+ end
49
82
  end
50
83
  end
@@ -1,3 +1,3 @@
1
1
  module RailsTwirp
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_twirp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bouke van der Bijl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-20 00:00:00.000000000 Z
11
+ date: 2021-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -59,6 +59,9 @@ files:
59
59
  - lib/rails_twirp/base.rb
60
60
  - lib/rails_twirp/engine.rb
61
61
  - lib/rails_twirp/errors.rb
62
+ - lib/rails_twirp/implicit_render.rb
63
+ - lib/rails_twirp/instrumentation.rb
64
+ - lib/rails_twirp/log_subscriber.rb
62
65
  - lib/rails_twirp/mapper.rb
63
66
  - lib/rails_twirp/render_pb.rb
64
67
  - lib/rails_twirp/rescue.rb