Class: Module
- Inherits:
-
Object
- Object
- Module
- Defined in:
- lib/mole/module.rb
Instance Method Summary collapse
-
#after_mole_filters ⇒ Object
————————————————————————- Holds after filters.
-
#apply_after_filters(filters, clazz, key, ret_val, *a, &b) ⇒ Object
:nodoc:.
-
#apply_before_filters(filters, clazz, key, *a, &b) ⇒ Object
:nodoc:.
-
#apply_perf_filters(elapsed, filters, clazz, key, ret_val, *a, &b) ⇒ Object
:nodoc:.
-
#apply_unchecked_filters(boom, filters, clazz, key, *a, &b) ⇒ Object
:nodoc:.
-
#before_mole_filters ⇒ Object
————————————————————————- Holds before filters.
-
#mole_after(opts = {}, &interceptor) ⇒ Object
intercepts a feature after the feature is called.
-
#mole_before(opts = {}, &interceptor) ⇒ Object
intercepts a feature before the feature is called.
-
#mole_dump(msg = nil) ⇒ Object
————————————————————————— Dumps moled feature info.
-
#mole_perf(opts = {}, &interceptor) ⇒ Object
intercepts a collection of features and wrap performance check based on the specified :perf_threshold.
-
#mole_unchecked(opts = {}, &interceptor) ⇒ Object
monitors a collections of features and wrap rescue logic to trap unchecked exceptions.
-
#perf_mole_filters ⇒ Object
————————————————————————- Holds perf around filters.
-
#unchecked_mole_filters ⇒ Object
————————————————————————- Holds unchecked exception filters.
-
#wrap(method) ⇒ Object
————————————————————————- Wrap method call TODO Add support for wrapping class methods ??.
-
#wrapped ⇒ Object
————————————————————————— Log wrapped class.
-
#wrapped?(which) ⇒ Boolean
————————————————————————— Check if method has been wrapped.
Instance Method Details
#after_mole_filters ⇒ Object
Holds after filters
181 182 183 |
# File 'lib/mole/module.rb', line 181 def after_mole_filters #:nodoc: @after_mole_filters ||= Hash.new{ |h,k| h[k] = [] } end |
#apply_after_filters(filters, clazz, key, ret_val, *a, &b) ⇒ Object
:nodoc:
252 253 254 255 256 257 258 259 |
# File 'lib/mole/module.rb', line 252 def apply_after_filters( filters, clazz, key, ret_val, *a, &b ) #:nodoc: begin filters.each { |r,m| r.send( m, clazz, key, ret_val, b, *a ) } rescue => ca_boom ::Mole.logger.error ">>> MOle Failure: After-Filter -- " + ca_boom ca_boom.backtrace.each { |l| ::Mole.logger.error l } end end |
#apply_before_filters(filters, clazz, key, *a, &b) ⇒ Object
:nodoc:
243 244 245 246 247 248 249 250 |
# File 'lib/mole/module.rb', line 243 def apply_before_filters( filters, clazz, key, *a, &b ) #:nodoc: begin filters.each { |r,m| r.send( m, clazz, key, b, *a ) } rescue => ca_boom ::Mole.logger.error ">>> MOle Failure: Before-Filter -- " + ca_boom ca_boom.backtrace.each { |l| ::Mole.logger.error l } end end |
#apply_perf_filters(elapsed, filters, clazz, key, ret_val, *a, &b) ⇒ Object
:nodoc:
261 262 263 264 265 266 267 268 269 270 |
# File 'lib/mole/module.rb', line 261 def apply_perf_filters( elapsed, filters, clazz, key, ret_val, *a, &b ) #:nodoc: begin if ( elapsed >= Mole.perf_threshold ) filters.each { |r,m| r.send( m, clazz, key, elapsed, ret_val, b, *a ) } end rescue => ca_boom ::Mole.logger.error ">>> MOle Failure: Perf-Filter -- " + ca_boom ca_boom.backtrace.each { |l| ::Mole.logger.error l } end end |
#apply_unchecked_filters(boom, filters, clazz, key, *a, &b) ⇒ Object
:nodoc:
272 273 274 275 276 277 278 279 |
# File 'lib/mole/module.rb', line 272 def apply_unchecked_filters( boom, filters, clazz, key, *a, &b ) #:nodoc: begin filters.each { |r,m| r.send( m, clazz, key, boom, b, *a ) } rescue => ca_boom ::Mole.logger.error ">>> MOle Failure: Unchecked-Filter -- " + ca_boom ca_boom.backtrace.each { |l| ::Mole.logger.error l } end end |
#before_mole_filters ⇒ Object
Holds before filters
175 176 177 |
# File 'lib/mole/module.rb', line 175 def before_mole_filters #:nodoc: @before_mole_filters ||= Hash.new{ |h,k| h[k] = [] } end |
#mole_after(opts = {}, &interceptor) ⇒ Object
intercepts a feature after the feature is called. During the callback you will have access to the object ( context ) on which the call is intercepted, as well as the arguments/block and return values the feature was issued with.
Example:
MyClass.mole_after( :feature => :blee ) do |context, feature, ret_val, block, *args|
Mole::Moler.mole_it( context, feature, context.session[:user_id],
:args => args )
end
This will wrap the method blee with an after interceptor. After the blee call is issued on MyClass, control will be handed to the after interceptor.
Options:
:feature
-
The name of the feature to be intercepted
:interceptor
-
The class name of your interceptor class. If no interceptor block is specified
:method
-
The name of the method to callback the interceptor on once an exception condition has been trapped.
126 127 128 129 130 131 132 133 134 135 |
# File 'lib/mole/module.rb', line 126 def mole_after(opts = {}, &interceptor) raise "Missing :feature option" if opts[:feature].nil? or opts[:feature].to_s.empty? opts[:interceptor] ||= interceptor opts[:method] ||= :call feature = opts[:feature].to_s if after_mole_filters[feature].empty? wrap feature after_mole_filters[feature] << [opts[:interceptor], opts[:method]] end end |
#mole_before(opts = {}, &interceptor) ⇒ Object
intercepts a feature before the feature is called. During the callback you will have access to the object ( context ) on which the call is intercepted, as well as the arguments/block, the feature was issued with.
Example:
MyClass.mole_before( :feature => :blee ) do |context, feature, block, *args|
Mole::Moler.mole_it( context, feature, context.session[:user_id],
:args => args )
end
This will wrap the method blee with a before interceptor. Before the blee call is issued on MyClass, control will be handed to the before interceptor.
Options:
:feature
-
The name of the feature to be intercepted
If you elect not to use the block form of the call, you can pass in the following arguments to the option hash:
:interceptor
-
The class name of your interceptor class. If no interceptor block is specified
:method
-
The name of the method to callback the interceptor on once an exception condition has been trapped.
96 97 98 99 100 101 102 103 104 105 |
# File 'lib/mole/module.rb', line 96 def mole_before(opts={}, &interceptor) raise "Missing :feature option" if opts[:feature].nil? or opts[:feature].to_s.empty? opts[:interceptor] ||= interceptor opts[:method] ||= :call feature = opts[:feature].to_s if before_mole_filters[feature].empty? wrap feature before_mole_filters[feature] << [opts[:interceptor], opts[:method]] end end |
#mole_dump(msg = nil) ⇒ Object
Dumps moled feature info
139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/mole/module.rb', line 139 def mole_dump( msg=nil ) puts "\n------------------------------------------------------------------" puts "From #{msg}" if msg puts "MOle Info for class <- #{self} ->" puts "\nBefore filters" before_mole_filters.keys.sort.each { |k| puts "\t#{k} --> #{before_mole_filters[k]}" } puts "\nAfter filters" after_mole_filters.keys.sort.each { |k| puts "\t#{k} --> #{after_mole_filters[k]}" } puts "\nUnchecked filters" unchecked_mole_filters.keys.sort.each { |k| puts "\t#{k} --> #{unchecked_mole_filters[k]}" } puts "\nPerf filters" perf_mole_filters.keys.sort.each { |k| puts "\t#{k} --> #{perf_mole_filters[k]}" } puts "---------------------------------------------------------------------\n" end |
#mole_perf(opts = {}, &interceptor) ⇒ Object
intercepts a collection of features and wrap performance check based on the specified :perf_threshold. The trigger defaults to 5 secs if not explicitly set.
Example:
MyClass.mole_perf do |context, action, elapsed_time, ret, block, *args|
Mole::DbMole.perf_it( context.session[:user_id],
:controller => context.class.name,
:action => action,
:elapsed_time => "%3.3f" % elapsed_time )
end
This will trap all public methods on the MyClass that takes more than :perf_threshold to complete. You can override this default by using the option :features => [m1,m2,…]. This is handy for controller moling rails and merb context.
If you elect not to use the block form of the call, you can pass in the following arguments to the option hash:
:interceptor
-
The class name of your interceptor class
:method
-
The name of the method to callback the interceptor on once a perf condition has been trapped.
30 31 32 33 34 35 36 37 38 |
# File 'lib/mole/module.rb', line 30 def mole_perf( opts={}, &interceptor ) opts[:interceptor] ||= interceptor opts[:method] ||= :call opts[:features] ||= instance_methods( false ) opts[:features].each do |feature| wrap feature perf_mole_filters[feature.to_s] << [opts[:interceptor], opts[:method]] end end |
#mole_unchecked(opts = {}, &interceptor) ⇒ Object
monitors a collections of features and wrap rescue logic to trap unchecked exceptions. You can handle to trap differently by either logging the event in the db or sending out email/IM notification.
Example:
MyClass.mole_unchecked do |context, action, boom, block, *args|
Mole::Moler.check_it( context.session[:user_id],
:controller => context.class.name,
:action => action,
:boom => boom )
end
This will wrap all public instance methods on MyClass. If any of these methods raises an unchecked exception, the MOle will surface the condition. This call also takes in a :features option to specify a list of methods if the default instance methods is not suitable, you can pass in a collection of methods that you wish to mole. This is handy in the case of Rails/Merb where conveniences are provided to gather controller actions
If you elect not to use the block form of the call, you can pass in the following arguments to the option hash:
:interceptor
-
The class name of your interceptor class
:method
-
The name of the method to callback the interceptor on once an exception condition has been trapped.
65 66 67 68 69 70 71 72 73 |
# File 'lib/mole/module.rb', line 65 def mole_unchecked( opts={}, &interceptor ) opts[:interceptor] ||= interceptor opts[:method] ||= :call opts[:features] ||= instance_methods( false ) opts[:features].each do |feature| wrap feature unchecked_mole_filters[feature.to_s] << [opts[:interceptor], opts[:method]] end end |
#perf_mole_filters ⇒ Object
Holds perf around filters
187 188 189 |
# File 'lib/mole/module.rb', line 187 def perf_mole_filters #:nodoc: @perf_mole_filters ||= Hash.new{ |h,k| h[k] = []} end |
#unchecked_mole_filters ⇒ Object
Holds unchecked exception filters
193 194 195 |
# File 'lib/mole/module.rb', line 193 def unchecked_mole_filters #:nodoc: @unchecked_mole_filters ||= Hash.new{ |h,k| h[k] = []} end |
#wrap(method) ⇒ Object
Wrap method call
TODO Add support for wrapping class methods ??
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/mole/module.rb', line 208 def wrap( method ) #:nodoc: return if wrapped?( method ) begin between = instance_method( method ) rescue # between = find_public_class_method( method ) raise "Unable to find moled feature `#{method}" unless(between) end method_name, punctuation = clean_method_name( method ) code = <<-code def #{method_name}_with_mole#{punctuation} (*a, &b) key = '#{method}' klass = self.class between = klass.wrapped[key] ret_val = nil klass.apply_before_filters( klass.before_mole_filters[key], self, key, *a, &b ) if klass.before_mole_filters[key] begin elapsed = Benchmark::realtime do ret_val = between.bind(self).call( *a, &b ) end klass.apply_perf_filters( elapsed, klass.perf_mole_filters[key], self, key, ret_val, *a, &b ) if klass.perf_mole_filters[key] rescue => boom klass.apply_unchecked_filters( boom, klass.unchecked_mole_filters[key], self, key, *a, &b ) if klass.unchecked_mole_filters[key] raise boom end klass.apply_after_filters( klass.after_mole_filters[key], self, key, ret_val, *a, &b ) if klass.after_mole_filters[key] ret_val end code module_eval code alias_method_chain method, "mole" wrapped[method.to_s] = between end |
#wrapped ⇒ Object
Log wrapped class
283 284 285 |
# File 'lib/mole/module.rb', line 283 def wrapped #:nodoc: @wrapped ||= {} end |
#wrapped?(which) ⇒ Boolean
Check if method has been wrapped
289 290 291 |
# File 'lib/mole/module.rb', line 289 def wrapped?(which) #:nodoc: wrapped.has_key?(which.to_s) end |