timeasure 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 98176f0d699b3c9ca5cd0e101021edafe375e77d
4
- data.tar.gz: 7be9aa110d461fd15ebe5b449e307c5159df778d
3
+ metadata.gz: 646792d500a9a61b929dd067f9c1b48b9bf30b2d
4
+ data.tar.gz: 1c0b5af7065eb1a950e201521ca7ec2f5c644964
5
5
  SHA512:
6
- metadata.gz: '03826e4210bf05d86005e3245f35c90e02aa75e4771195b850a3ba9744535404d799474e56e7db7312bb48ae89ef70a2c455bc661a9c48e3156fa2932dc8ec55'
7
- data.tar.gz: 50bdd345a80bfc306eb3138f46c7a3f20493d8193d53ee73d0c538da92da86ffeca7eff5a3dc8d52e0890e8cfc014cd998e8f0efe3792947ad9829bb43c43762
6
+ metadata.gz: 81af656e98f415dddf152dbec13530c84d4506c64eac0fd13b6f217aad76598dd10251c18239de1c9b69eb8fabc18d732531ce45fe188a73a144453580be486a
7
+ data.tar.gz: b2062fb31932f6087a6ec43b7f8f7991a868f8b8ff4081e7579358fa9798a1438e377144a257cedc2d36aec0a6570ba772b3c07d8d2fc0bbc9d366b289cc7919
data/CHANGELOG.md ADDED
@@ -0,0 +1,30 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.2.0] - 2018-03-12
10
+ ### Added
11
+ - New class macros for tracking private methods in both inline and scoped visibility declaration.
12
+
13
+ ### Changed
14
+ - Start using `Process.clock_gettime(Process::CLOCK_MONOTONIC)` instead of `Time.now` for time tracking
15
+ - Bumped up required Ruby version from 2.0 to 2.1
16
+
17
+ ## [0.1.1] - 2018-02-24
18
+ ### Added
19
+ - Specs for describing the proper way to track private methods.
20
+
21
+ ### Fixed
22
+ - Minor performance issue in class macros
23
+
24
+ ## [0.1.0] - 2018-02-24
25
+ ### Added
26
+ - Timeasure main code
27
+ - Timeasure profiler
28
+
29
+ [0.2.0]: https://github.com/Riskified/timeasure/compare/v0.1.1...v0.2.0
30
+ [0.1.1]: https://github.com/Riskified/timeasure/compare/v0.1.0...v0.1.1
data/README.md CHANGED
@@ -39,7 +39,7 @@ Timeasure is developed and maintained by [Eliav Lavi](http://www.eliavlavi.com)
39
39
 
40
40
  ## Requirements
41
41
 
42
- Ruby 2.0 or a later version is mandatory. (Timeasure uses `Module#prepend` introduced in Ruby 2.0.)
42
+ Ruby 2.1 or a later version is mandatory. (Timeasure uses `Module#prepend` introduced in Ruby 2.0 and `Process::CLOCK_MONOTONIC` introduced in Ruby 2.1.)
43
43
 
44
44
  ## Installation
45
45
 
@@ -78,6 +78,70 @@ class Foo
78
78
  end
79
79
  end
80
80
  ```
81
+ **An Important Note Regarding Private Methods**
82
+
83
+ If you need to track any private methods - either class methods or instance methods - use the designated class macros for that:
84
+
85
+ ```ruby
86
+ class Foo
87
+ include Timeasure
88
+ tracked_class_methods :a_class_method_that_calls_private_methods
89
+ tracked_private_class_methods :a_scoped_private_class_method, :an_inline_private_class_method
90
+
91
+ class << self
92
+ def a_class_method_that_calls_private_methods
93
+ a_scoped_private_class_method
94
+ an_inline_private_class_method
95
+ end
96
+
97
+ def a_scoped_private_class_method
98
+ # some private class-level stuff that can benefit from measuring runtime...
99
+ end
100
+ end
101
+
102
+ def self.an_inline_private_class_method
103
+ # some other private class-level stuff that can benefit from measuring runtime...
104
+ end
105
+ end
106
+ ```
107
+
108
+ And the instance-level equivalent:
109
+
110
+ ```ruby
111
+ class Foo
112
+ include Timeasure
113
+ tracked_instance_methods :a_instance_method_that_calls_private_methods
114
+ tracked_private_instance_methods :a_scoped_private_instance_method, :an_inline_private_instance_method
115
+
116
+ class << self
117
+ def a_instance_method_that_calls_private_methods
118
+ a_scoped_private_instance_method
119
+ an_inline_private_instance_method
120
+ end
121
+
122
+ def a_scoped_private_instance_method
123
+ # some private instance-level stuff that can benefit from measuring runtime...
124
+ end
125
+ end
126
+
127
+ def self.an_inline_private_instance_method
128
+ # some other private instance-level stuff that can benefit from measuring runtime...
129
+ end
130
+ end
131
+ ```
132
+
133
+ **ATTENTION!**
134
+
135
+ **Declaring the tracking of private methods with `tracked_class_methods` or `tracked_instance_methods` will end up in `NoMethodError` upon calling their triggering method!**
136
+
137
+ Also, tracking your public methods with `tracked_private_class_methods` or `tracked_private_instance_methods` will make your class' interface inaccessible.
138
+ The reason for these two is that since Timeasure is declared at the top of the class,
139
+ it cannot know in advance which methods will be declared as private, so you need to specify this explicitly.
140
+
141
+ As a side note, it could be claimed that as a rule of thumb, if you find yourself measuring private methods,
142
+ this might be a good idea to invest in refactoring this area of code and [Extract Class](https://refactoring.guru/extract-class).
143
+ However, this is not always possible, of course, especially when working on legacy code.
144
+ Hence, this feature of Timeasure should be considered as somewhat of a last resort and be handled with care.
81
145
 
82
146
  #### 2. Define the Boundaries of the Tracked Transaction
83
147
  **Preparing for Method Tracking**
data/lib/timeasure.rb CHANGED
@@ -27,9 +27,9 @@ module Timeasure
27
27
  end
28
28
 
29
29
  def measure(klass_name: nil, method_name: nil, segment: nil, metadata: nil)
30
- t0 = Time.now.utc
30
+ t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
31
31
  block_return_value = yield if block_given?
32
- t1 = Time.now.utc
32
+ t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
33
33
 
34
34
  begin
35
35
  measurement = Timeasure::Measurement.new(klass_name: klass_name.to_s, method_name: method_name.to_s,
@@ -1,19 +1,27 @@
1
1
  module Timeasure
2
2
  module ClassMethods
3
3
  def tracked_instance_methods(*method_names)
4
- instance_interceptor = const_get("#{timeasure_name}InstanceInterceptor")
5
4
  method_names.each do |method_name|
6
5
  add_method_to_interceptor(instance_interceptor, method_name)
7
6
  end
8
7
  end
9
8
 
10
9
  def tracked_class_methods(*method_names)
11
- class_interceptor = const_get("#{timeasure_name}ClassInterceptor")
12
10
  method_names.each do |method_name|
13
11
  add_method_to_interceptor(class_interceptor, method_name)
14
12
  end
15
13
  end
16
14
 
15
+ def tracked_private_instance_methods(*method_names)
16
+ tracked_instance_methods(*method_names)
17
+ method_names.each { |method_name| privatize_interceptor_method(instance_interceptor, method_name) }
18
+ end
19
+
20
+ def tracked_private_class_methods(*method_names)
21
+ tracked_class_methods(*method_names)
22
+ method_names.each { |method_name| privatize_interceptor_method(class_interceptor, method_name) }
23
+ end
24
+
17
25
  def timeasure_name
18
26
  name.gsub('::', '_')
19
27
  end
@@ -29,5 +37,17 @@ module Timeasure
29
37
  end
30
38
  end
31
39
  end
40
+
41
+ def privatize_interceptor_method(interceptor, method_name)
42
+ interceptor.class_eval { private method_name }
43
+ end
44
+
45
+ def instance_interceptor
46
+ const_get("#{timeasure_name}InstanceInterceptor")
47
+ end
48
+
49
+ def class_interceptor
50
+ const_get("#{timeasure_name}ClassInterceptor")
51
+ end
32
52
  end
33
53
  end
@@ -1,3 +1,3 @@
1
1
  module Timeasure
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
data/timeasure.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.test_files = spec.files.grep(%r{^spec/})
20
20
  spec.require_paths = ['lib', 'lib/timeasure', 'lib/timeasure/profiling']
21
21
 
22
- spec.required_ruby_version = '>= 2.0'
22
+ spec.required_ruby_version = '>= 2.1'
23
23
  spec.add_development_dependency 'bundler', '~> 1.6'
24
24
  spec.add_development_dependency 'coveralls'
25
25
  spec.add_development_dependency 'rake', '~> 12.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timeasure
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eliav Lavi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-24 00:00:00.000000000 Z
11
+ date: 2018-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -79,6 +79,7 @@ files:
79
79
  - ".gitignore"
80
80
  - ".rspec"
81
81
  - ".rubocop.yml"
82
+ - CHANGELOG.md
82
83
  - Gemfile
83
84
  - LICENSE.txt
84
85
  - README.md
@@ -106,7 +107,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
106
107
  requirements:
107
108
  - - ">="
108
109
  - !ruby/object:Gem::Version
109
- version: '2.0'
110
+ version: '2.1'
110
111
  required_rubygems_version: !ruby/object:Gem::Requirement
111
112
  requirements:
112
113
  - - ">="