mirror of
https://github.com/stripe/stripe-ruby.git
synced 2025-11-22 00:05:58 -05:00
Adds a new instrumentation callback called `request_begin` which, as the name suggests, is invoked before an HTTP request is dispatched. As outlined originally in #900, the idea is that this will enable a set of hooks that can be used for distributed tracing. The PR also renames the existing `request` callback to `request_end`, although the old name is still invoked for the time being for backwards compatibility. A special `user_data` property is passed to `request_begin` which allows subscribers to set custom data that will be passed through to `request_end` for any given request. This allows, for example, a user assigned ID to be set for the request and recognized on both ends. I chose the naming `_begin` and `_end` (as opposed to start/finish or any other combination) based on the naming conventions of Ruby itself. Fixes #900.
83 lines
2.4 KiB
Ruby
83 lines
2.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Stripe
|
|
class Instrumentation
|
|
# Event emitted on `request_begin` callback.
|
|
class RequestBeginEvent
|
|
attr_reader :method
|
|
attr_reader :path
|
|
|
|
# Arbitrary user-provided data in the form of a Ruby hash that's passed
|
|
# from subscribers on `request_begin` to subscribers on `request_end`.
|
|
# `request_begin` subscribers can set keys which will then be available
|
|
# in `request_end`.
|
|
#
|
|
# Note that all subscribers of `request_begin` share the same object, so
|
|
# they must be careful to set unique keys so as to not conflict with data
|
|
# set by other subscribers.
|
|
attr_reader :user_data
|
|
|
|
def initialize(method:, path:, user_data:)
|
|
@method = method
|
|
@path = path
|
|
@user_data = user_data
|
|
freeze
|
|
end
|
|
end
|
|
|
|
# Event emitted on `request_end` callback.
|
|
class RequestEndEvent
|
|
attr_reader :duration
|
|
attr_reader :http_status
|
|
attr_reader :method
|
|
attr_reader :num_retries
|
|
attr_reader :path
|
|
|
|
# Arbitrary user-provided data in the form of a Ruby hash that's passed
|
|
# from subscribers on `request_begin` to subscribers on `request_end`.
|
|
# `request_begin` subscribers can set keys which will then be available
|
|
# in `request_end`.
|
|
attr_reader :user_data
|
|
|
|
def initialize(duration:, http_status:, method:, num_retries:, path:,
|
|
user_data: nil)
|
|
@duration = duration
|
|
@http_status = http_status
|
|
@method = method
|
|
@num_retries = num_retries
|
|
@path = path
|
|
@user_data = user_data
|
|
freeze
|
|
end
|
|
end
|
|
|
|
# This class was renamed for consistency. This alias is here for backwards
|
|
# compatibility.
|
|
RequestEvent = RequestEndEvent
|
|
|
|
# Returns true if there are a non-zero number of subscribers on the given
|
|
# topic, and false otherwise.
|
|
def self.any_subscribers?(topic)
|
|
!subscribers[topic].empty?
|
|
end
|
|
|
|
def self.subscribe(topic, name = rand, &block)
|
|
subscribers[topic][name] = block
|
|
name
|
|
end
|
|
|
|
def self.unsubscribe(topic, name)
|
|
subscribers[topic].delete(name)
|
|
end
|
|
|
|
def self.notify(topic, event)
|
|
subscribers[topic].each_value { |subscriber| subscriber.call(event) }
|
|
end
|
|
|
|
def self.subscribers
|
|
@subscribers ||= Hash.new { |hash, key| hash[key] = {} }
|
|
end
|
|
private_class_method :subscribers
|
|
end
|
|
end
|