Class: Labkit::ExconPublisher
- Inherits:
-
Object
- Object
- Labkit::ExconPublisher
- Defined in:
- lib/labkit/excon_publisher.rb
Overview
A middleware for Excon HTTP library to publish a notification whenever a HTTP request is triggered.
Excon supports a middleware system that allows request/response interception freely. Whenever a new Excon connection is created, a list of default middlewares is injected. This list of middlewares can be altered thanks to Excon.defaults accessor. ExconPublisher is inserted into this list. It affects all connections created in future. There is a limitation that this approach doesn’t work if a user decides to override the default middleware list. It is unlikely though, at least in the dependency tree of GitLab.
ExconPublisher instance is created once and shared between all Excon connections later. Each connection may be triggered by different threads in parallel. In such cases, a connection objects creates multiple sockets for each thread. Therfore in the implementation of this middleware, the instrumation payload for each connection is stored inside a thread-isolated storage.
For more information: github.com/excon/excon/blob/81a0130537f2f8cd00d6daafb05d02d9a90dc9f7/lib/excon/middlewares/base.rb github.com/excon/excon/blob/fa3ec51e9bb062a12846a1cfff09534e76c99f4b/lib/excon/constants.rb#L146 github.com/excon/excon/blob/fa3ec51e9bb062a12846a1cfff09534e76c99f4b/lib/excon/connection.rb#L474
Class Method Summary collapse
Instance Method Summary collapse
- #error_call(datum) ⇒ Object
-
#initialize(stack) ⇒ ExconPublisher
constructor
A new instance of ExconPublisher.
- #request_call(datum) ⇒ Object
- #response_call(datum) ⇒ Object
Constructor Details
#initialize(stack) ⇒ ExconPublisher
Returns a new instance of ExconPublisher.
42 43 44 45 |
# File 'lib/labkit/excon_publisher.rb', line 42 def initialize(stack) @stack = stack @instrumenter = ActiveSupport::Notifications.instrumenter end |
Class Method Details
.labkit_prepend! ⇒ Object
31 32 33 34 35 36 37 38 39 40 |
# File 'lib/labkit/excon_publisher.rb', line 31 def self.labkit_prepend! @prepend_mutex.synchronize do return if !defined?(Excon) || @prepended defaults = Excon.defaults defaults[:middlewares] << ExconPublisher @prepended = true end end |
Instance Method Details
#error_call(datum) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/labkit/excon_publisher.rb', line 68 def error_call(datum) payload = fetch_connection_payload(datum) return @stack.error_call(datum) if payload.nil? calculate_duration(payload) if datum[:error].is_a?(Exception) payload[:exception] = [datum[:error].class.name, datum[:error].] payload[:exception_object] = datum[:error] elsif datum[:error].is_a?(String) exception = StandardError.new(datum[:error]) payload[:exception] = [exception.class.name, exception.] payload[:exception_object] = exception end @instrumenter.finish(::Labkit::EXTERNAL_HTTP_NOTIFICATION_TOPIC, payload) @stack.error_call(datum) ensure remove_connection_payload(datum) end |
#request_call(datum) ⇒ Object
47 48 49 50 51 52 |
# File 'lib/labkit/excon_publisher.rb', line 47 def request_call(datum) payload = start_payload(datum) store_connection_payload(datum, payload) @instrumenter.start(::Labkit::EXTERNAL_HTTP_NOTIFICATION_TOPIC, payload) @stack.request_call(datum) end |
#response_call(datum) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/labkit/excon_publisher.rb', line 54 def response_call(datum) payload = fetch_connection_payload(datum) return @stack.response_call(datum) if payload.nil? calculate_duration(payload) payload[:code] = datum[:response][:status].to_s @instrumenter.finish(::Labkit::EXTERNAL_HTTP_NOTIFICATION_TOPIC, payload) @stack.response_call(datum) ensure remove_connection_payload(datum) end |