module Bumbler::Hooks
Attributes
slow_requires[R]
slow_threshold[W]
Public Class Methods
benchmark(key) { || ... }
click to toggle source
# File lib/bumbler/hooks.rb, line 100 def benchmark(key) start = Process.clock_gettime(Process::CLOCK_MONOTONIC) result = yield time = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000 # ms @slow_requires[key] = time if time > @slow_threshold [time, result] end
handle_require(path) { || ... }
click to toggle source
Actually do something about a require here.
# File lib/bumbler/hooks.rb, line 80 def handle_require(path, &block) # break out early if we're already handling the path return yield if path == @previous_require @previous_require = path # ignore untracked gem return yield unless (gem_name = Bumbler::Bundler.gem_for_require(path)) # track load starts Bumbler::Bundler.require_started(gem_name) unless @started_items[gem_name] @started_items[gem_name] = true time, result = benchmark(path, &block) # TODO: for items with multiple paths we need to add the times Bumbler::Bundler.require_finished(gem_name, path, time) if result result end
hook_instance_require!()
click to toggle source
# File lib/bumbler/hooks.rb, line 20 def hook_instance_require! @hooking_instance_require = true ::Kernel.module_eval do orig_instance_require = instance_method(:require) define_method(:require) do |path, *args| ::Bumbler::Hooks.handle_require(path) do orig_instance_require.bind(self).call(path, *args) end end private :require end @hooking_instance_require = nil end
hook_require!()
click to toggle source
Inject our custom handling of require into the Kernel.
# File lib/bumbler/hooks.rb, line 15 def hook_require! hook_instance_require! hook_singleton_require! end
hook_singleton_require!()
click to toggle source
# File lib/bumbler/hooks.rb, line 36 def hook_singleton_require! @hooking_singleton_require = true ::Kernel.module_eval do class << self orig_public_require = Kernel.public_method(:require) define_method(:require) do |path, *args| ::Bumbler::Hooks.handle_require(path) do orig_public_require.call(path, *args) end end end end @hooking_singleton_require = nil end
hooking_instance_require?()
click to toggle source
# File lib/bumbler/hooks.rb, line 71 def hooking_instance_require? @hooking_instance_require end
hooking_singleton_require?()
click to toggle source
# File lib/bumbler/hooks.rb, line 75 def hooking_singleton_require? @hooking_singleton_require end
method_added(method_name, *_args)
click to toggle source
It isn’t previously defined in Kernel. This could be a bit dangerous, though.
# File lib/bumbler/hooks.rb, line 57 def self.method_added(method_name, *_args) # rubocop:disable Lint/MissingSuper if method_name == :require && !Bumbler::Hooks.hooking_instance_require? ::Bumbler::Hooks.hook_instance_require! end end
singleton_method_added(method_name, *_args)
click to toggle source
# File lib/bumbler/hooks.rb, line 63 def self.singleton_method_added(method_name, *_args) # rubocop:disable Lint/MissingSuper if method_name == :require && !Bumbler::Hooks.hooking_singleton_require? ::Bumbler::Hooks.hook_singleton_require! end end
watch_require!()
click to toggle source
Even better: Other gems hook require as well. The instance method one at least.
# File lib/bumbler/hooks.rb, line 54 def watch_require! ::Kernel.module_eval do # It isn't previously defined in Kernel. This could be a bit dangerous, though. def self.method_added(method_name, *_args) # rubocop:disable Lint/MissingSuper if method_name == :require && !Bumbler::Hooks.hooking_instance_require? ::Bumbler::Hooks.hook_instance_require! end end def self.singleton_method_added(method_name, *_args) # rubocop:disable Lint/MissingSuper if method_name == :require && !Bumbler::Hooks.hooking_singleton_require? ::Bumbler::Hooks.hook_singleton_require! end end end end