Module: Bumbler::Hooks
- Defined in:
- lib/bumbler/hooks.rb
Class Attribute Summary collapse
-
.slow_requires ⇒ Object
readonly
Returns the value of attribute slow_requires.
-
.slow_threshold ⇒ Object
writeonly
Sets the attribute slow_threshold.
Class Method Summary collapse
- .benchmark(key) ⇒ Object
-
.handle_require(path, &block) ⇒ Object
Actually do something about a require here.
-
.hook_require! ⇒ Object
Inject our custom handling of require into the Kernel.
- .hooking_require? ⇒ Boolean
-
.watch_require! ⇒ Object
Even better: Other gems hook require as well.
Class Attribute Details
.slow_requires ⇒ Object (readonly)
Returns the value of attribute slow_requires.
12 13 14 |
# File 'lib/bumbler/hooks.rb', line 12 def slow_requires @slow_requires end |
.slow_threshold=(value) ⇒ Object (writeonly)
Sets the attribute slow_threshold
10 11 12 |
# File 'lib/bumbler/hooks.rb', line 10 def slow_threshold=(value) @slow_threshold = value end |
Class Method Details
.benchmark(key) ⇒ Object
78 79 80 81 82 83 84 |
# File 'lib/bumbler/hooks.rb', line 78 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, &block) ⇒ Object
Actually do something about a require here.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/bumbler/hooks.rb', line 58 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_require! ⇒ Object
Inject our custom handling of require into the Kernel.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/bumbler/hooks.rb', line 15 def hook_require! @hooking_require = true # There are two independent require methods. Joy! ::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 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 end @hooking_require = nil end |
.hooking_require? ⇒ Boolean
53 54 55 |
# File 'lib/bumbler/hooks.rb', line 53 def hooking_require? @hooking_require end |
.watch_require! ⇒ Object
Even better: Other gems hook require as well. The instance method one at least.
41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/bumbler/hooks.rb', line 41 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) if method_name == :require && !::Bumbler::Hooks.hooking_require? # Fix those hooks. ::Bumbler::Hooks.hook_require! end end end end |