rails_twirp 0.5.0 → 0.6.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 +4 -4
- data/lib/rails_twirp.rb +1 -0
- data/lib/rails_twirp/base.rb +4 -3
- data/lib/rails_twirp/implicit_render.rb +11 -0
- data/lib/rails_twirp/instrumentation.rb +32 -0
- data/lib/rails_twirp/log_subscriber.rb +64 -0
- data/lib/rails_twirp/testing/integration_test.rb +49 -16
- data/lib/rails_twirp/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34fc8b4e84ba8c456ac2fa01c3c35dd0fd11224360d6e21b832b5d17ed1f57a5
|
4
|
+
data.tar.gz: 9626b771c35bfdd034fa1dccad6ef5ed921aad0abdf3086bfe27a6b3b26f50b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4621381feff50a031faf89079aa49054d246bd52f0e9d0fe4fe588f3014c2dd9a779f249aa16ac15340d9e259b61e273b393dd6a69ecaa15b5bf76c29578434
|
7
|
+
data.tar.gz: e91d714d2ef9c5e6a45e34911a29de4c1927d2e8442c5bf3538c5c43f137c10010b0282d9a5f2d4c5901d9c1733191cd0e7ff4e2764d8ae546233798ef81d64b
|
data/lib/rails_twirp.rb
CHANGED
data/lib/rails_twirp/base.rb
CHANGED
@@ -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,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
|
-
|
36
|
-
|
37
|
-
|
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
|
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
|
data/lib/rails_twirp/version.rb
CHANGED
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.
|
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-
|
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
|