Sha256: b704792b83dd113f26e5188c56370e853f51f8f49f36eb16a439981d0dc388be

Contents?: true

Size: 1.69 KB

Versions: 1

Compression:

Stored size: 1.69 KB

Contents

# frozen_string_literal: true

require "dry/core/class_attributes"

module ROM
  module Plugins
    module Relation
      # Experimental plugin for configuring relations with an external
      # instrumentation system like dry-monitor or ActiveSupport::Notifications
      #
      # @api public
      module Instrumentation
        extend Dry::Core::ClassAttributes

        # This hooks sets up a relation class with injectible notifications object
        #
        # @api private
        def self.included(klass)
          super
          klass.option :notifications
          klass.extend(ClassInterface)
          klass.prepend(mixin)
          klass.instrument(:to_a)
        end

        defines :mixin
        mixin Module.new

        # Instrumentation extension for relation classes
        #
        # @api private
        module ClassInterface
          # Configure provided methods for instrumentation
          #
          # @param [Array<Symbol>] methods A list of method names
          #
          # @api public
          def instrument(*methods)
            (methods - Instrumentation.mixin.instance_methods).each do |meth|
              Instrumentation.mixin.send(:define_method, meth) do
                instrument { super() }
              end
            end
          end
        end

        # Execute a block using instrumentation
        #
        # @api public
        def instrument(&block)
          notifications.instrument(
            config.component.adapter,
            name: name.relation, **notification_payload(self), &block
          )
        end

        private

        # @api private
        def notification_payload(_relation)
          EMPTY_HASH
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rom-6.0.0.alpha1 lib/rom/plugins/relation/instrumentation.rb