lib/bumbler/hooks.rb in bumbler-0.2.1 vs lib/bumbler/hooks.rb in bumbler-0.3.0
- old
+ new
@@ -1,43 +1,47 @@
module Bumbler
module Hooks
- SLOW_REQUIRE_THRESHOLD = 100.0
+ @slow_threshold = 100.0
@previous_gems = {}
@slow_requires = {}
-
+
# Everything's a class method (we're a singleton)
class << self
+ def slow_threshold=(time)
+ @slow_threshold = time
+ end
+
def slow_requires
@slow_requires
end
-
+
# Inject our custom handling of require into the Kernel.
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 = self.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
-
+
# Even better: Other gems hook require as well. The instance method one at least.
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)
@@ -46,38 +50,41 @@
::Bumbler::Hooks.hook_require!
end
end
end
end
-
+
def hooking_require?
@hooking_require
end
-
+
# Actually do something about a require here.
- def handle_require(path)
+ def handle_require(path, &block)
# break out early if we're already handling this
return yield if path == @previous_require
@previous_require = path
-
+
# Shortcut unless we're tracking the gem
gem_name = Bumbler::Bundler.gem_for_require(path)
return yield unless gem_name
-
+
# Track load starts
Bumbler::Bundler.require_started(path) unless @previous_gems[gem_name]
@previous_gems[gem_name] = true
-
- # Let's time them
+
+ time, result = benchmark(path, &block)
+
+ Bumbler::Bundler.require_finished(path, time) if result
+
+ result
+ end
+
+ def benchmark(key)
start = Time.now.to_f
result = yield
- require_time = (Time.now.to_f - start) * 1000 # ms
-
- @slow_requires[path] = require_time if require_time > SLOW_REQUIRE_THRESHOLD
-
- Bumbler::Bundler.require_finished(path, require_time) if result
-
- return result
+ time = (Time.now.to_f - start) * 1000 # ms
+ @slow_requires[key] = time if time > @slow_threshold
+ return time, result
end
end
end
end