benelux 0.2.0.001

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGES.txt ADDED
@@ -0,0 +1,4 @@
1
+ BENELUX, CHANGES
2
+
3
+
4
+ #### 0.2.0 (2009-09-??) ###############################
data/LICENSE.txt ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2009 Solutious Inc, Delano Mandelbaum
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,36 @@
1
+ = Benelux v0.1
2
+
3
+ <b></b>
4
+
5
+
6
+ == Features
7
+
8
+
9
+
10
+ == Installation
11
+
12
+ Get it in one of the following ways:
13
+
14
+ $ gem install benelux
15
+ $ git clone git://github.com/delano/benelux.git
16
+ $ gem install delano-benelux --source http://gems.github.com
17
+
18
+
19
+ == More Information
20
+
21
+ * Codes[http://github.com/delano/benelux]
22
+ * RDocs[http://delano.github.com/benelux]
23
+
24
+ == Credits
25
+
26
+ * Delano Mandelbaum (http://solutious.com)
27
+
28
+
29
+ == Thanks
30
+
31
+ * Alexis Sellier for fielding my Ruby questions
32
+
33
+
34
+ == License
35
+
36
+ See LICENSE.txt
data/Rakefile ADDED
@@ -0,0 +1,73 @@
1
+
2
+ require 'rake/clean'
3
+ require 'rake/gempackagetask'
4
+ require 'hanna/rdoctask'
5
+ require 'rake/testtask'
6
+ require 'shoulda/tasks'
7
+ require 'rake/runtest'
8
+ require 'monkeyspecdoc' # http://jgre.org/2008/09/03/monkeyspecdoc/
9
+ require 'fileutils'
10
+ include FileUtils
11
+
12
+ task :default => :test
13
+
14
+
15
+ # PACKAGE =============================================================
16
+
17
+ name = "benelux"
18
+ load "#{name}.gemspec"
19
+
20
+ version = @spec.version
21
+
22
+ Rake::GemPackageTask.new(@spec) do |p|
23
+ p.need_tar = true if RUBY_PLATFORM !~ /mswin/
24
+ end
25
+
26
+ task :release => [ "publish:gem", :clean, "publish:rdoc" ] do
27
+ $: << File.join(File.dirname(__FILE__), 'lib')
28
+ require "rudy"
29
+ abort if Drydock.debug?
30
+ end
31
+
32
+ task :install => [ :rdoc, :package ] do
33
+ sh %{sudo gem install pkg/#{name}-#{version}.gem}
34
+ end
35
+
36
+ task :uninstall => [ :clean ] do
37
+ sh %{sudo gem uninstall #{name}}
38
+ end
39
+
40
+
41
+ # Rubyforge Release / Publish Tasks ==================================
42
+
43
+ #about 'Publish website to rubyforge'
44
+ task 'publish:rdoc' => 'doc/index.html' do
45
+ sh "scp -rp doc/* rubyforge.org:/var/www/gforge-projects/#{name}/"
46
+ end
47
+
48
+ #about 'Public release to rubyforge'
49
+ task 'publish:gem' => [:package] do |t|
50
+ sh <<-end
51
+ rubyforge add_release -o Any -a CHANGES.txt -f -n README.rdoc #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.gem &&
52
+ rubyforge add_file -o Any -a CHANGES.txt -f -n README.rdoc #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.tgz
53
+ end
54
+ end
55
+
56
+
57
+ Rake::RDocTask.new do |t|
58
+ t.rdoc_dir = 'doc'
59
+ t.title = @spec.summary
60
+ t.options << '--line-numbers' << '-A cattr_accessor=object'
61
+ t.options << '--charset' << 'utf-8'
62
+ t.rdoc_files.include('LICENSE.txt')
63
+ t.rdoc_files.include('README.rdoc')
64
+ t.rdoc_files.include('CHANGES.txt')
65
+ #t.rdoc_files.include('Rudyfile') # why is the formatting f'd?
66
+ t.rdoc_files.include('bin/*')
67
+ t.rdoc_files.include('lib/**/*.rb')
68
+ end
69
+
70
+ CLEAN.include [ 'pkg', '*.gem', '.config', 'doc', 'coverage*' ]
71
+
72
+
73
+
data/benelux.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ @spec = Gem::Specification.new do |s|
2
+ s.name = "benelux"
3
+ s.rubyforge_project = 'benelux'
4
+ s.version = "0.2.0.001"
5
+ s.summary = "Benelux: Little freakin' timers for your Ruby codes"
6
+ s.description = s.summary
7
+ s.author = "Delano Mandelbaum"
8
+ s.email = "delano@solutious.com"
9
+ s.homepage = "http://github.com/delano/benelux"
10
+
11
+ s.extra_rdoc_files = %w[README.rdoc LICENSE.txt CHANGES.txt]
12
+ s.has_rdoc = true
13
+ s.rdoc_options = ["--line-numbers", "--title", s.summary, "--main", "README.rdoc"]
14
+ s.require_paths = %w[lib]
15
+
16
+ s.add_dependency 'hexoid'
17
+
18
+ # = MANIFEST =
19
+ # git ls-files
20
+ s.files = %w(
21
+ CHANGES.txt
22
+ LICENSE.txt
23
+ README.rdoc
24
+ Rakefile
25
+ benelux.gemspec
26
+ lib/benelux.rb
27
+ lib/benelux/mark.rb
28
+ lib/benelux/mixins/thread.rb
29
+ lib/benelux/timeline.rb
30
+ tryouts/basic_tryouts.rb
31
+ )
32
+
33
+
34
+ end
data/lib/benelux.rb ADDED
@@ -0,0 +1,130 @@
1
+ require 'attic'
2
+ require 'thread'
3
+ require 'hexoid'
4
+
5
+ module Benelux
6
+ NOTSUPPORTED = [Class, Object, Kernel]
7
+ SUFFIX_START = :a.freeze
8
+ SUFFIX_END = :z.freeze
9
+
10
+ require 'benelux/timeline'
11
+ require 'benelux/mark'
12
+ require 'benelux/mixins/thread'
13
+
14
+ @@timed_methods = {}
15
+ @@thread_timelines = []
16
+ @@timeline = Benelux::Timeline.new
17
+ @@mutex = Mutex.new
18
+
19
+ class BeneluxError < RuntimeError; end
20
+ class NotSupported < BeneluxError; end
21
+
22
+ def benelux_timers
23
+ Benelux.timed_methods[self.class]
24
+ end
25
+
26
+ def Benelux.supported?(klass)
27
+ !NOTSUPPORTED.member?(klass)
28
+ end
29
+
30
+ def Benelux.store_thread_reference
31
+ return if Benelux.thread_timelines.member? Thread.current
32
+ @@mutex.synchronize do
33
+ Benelux.thread_timelines << Thread.current
34
+ end
35
+ end
36
+
37
+ def Benelux.timed_methods
38
+ @@timed_methods
39
+ end
40
+
41
+ def Benelux.thread_timelines
42
+ @@thread_timelines
43
+ end
44
+
45
+ def Benelux.timeline
46
+ @@timeline = Benelux.generate_timeline if @@timeline.empty?
47
+ @@timeline
48
+ end
49
+
50
+ def Benelux.generate_timeline
51
+ @@mutex.synchronize do
52
+ timeline = Benelux::Timeline.new
53
+ Benelux.thread_timelines.each { |t| timeline << t.benelux }
54
+ timeline.flatten.sort
55
+ end
56
+ end
57
+
58
+ def Benelux.thread_timeline(thread_id=nil)
59
+ Thread.current.benelux ||= Benelux::Timeline.new
60
+ Thread.current.benelux
61
+ end
62
+
63
+
64
+ def Benelux.included(klass)
65
+ timed_methods[klass] = [] unless timed_methods.has_key? klass
66
+ end
67
+
68
+ def Benelux.timed_method? klass, meth
69
+ !timed_methods[klass].nil? && timed_methods[klass].member?(meth)
70
+ end
71
+
72
+ def Benelux.add_timer klass, meth
73
+ raise NotSupported, klass unless Benelux.supported? klass
74
+ raise AlreadyTimed, klass if Benelux.timed_method? klass, meth
75
+ prepare_object klass
76
+ meth_alias = rename_method klass, meth
77
+ timed_methods[klass] << meth
78
+ klass.module_eval generate_timer_str(meth_alias, meth)
79
+ end
80
+
81
+ def Benelux.add_tally obj, meth
82
+ end
83
+
84
+ def Benelux.name(*names)
85
+ names.flatten.collect { |n| n.to_s }.join('_')
86
+ end
87
+
88
+ private
89
+ def Benelux.prepare_object obj
90
+ obj.extend Attic unless obj.kind_of?(Attic)
91
+ unless obj.kind_of?(Benelux)
92
+ obj.attic :benelux
93
+ obj.send :include, Benelux
94
+ end
95
+ end
96
+
97
+ def Benelux.rename_method(obj, meth)
98
+ ## NOTE: This is commented out so we can include
99
+ ## Benelux definitions before all classes are loaded.
100
+ ##unless obj.respond_to? meth
101
+ ## raise NoMethodError, "undefined method `#{meth}' for #{obj}:Class"
102
+ ##end
103
+ thread_id, call_id = Thread.current.object_id.abs, obj.object_id.abs
104
+ meth_alias = "__benelux_#{meth}_#{thread_id}_#{call_id}"
105
+ obj.module_eval do
106
+ alias_method meth_alias, meth
107
+ end
108
+ meth_alias
109
+ end
110
+
111
+ def Benelux.generate_timer_str(meth_alias, meth)
112
+ %Q{
113
+ def #{meth}(*args, &block)
114
+ # We only need to do these things once.
115
+ if self.benelux.nil?
116
+ self.benelux = Benelux::Timeline.new
117
+ Benelux.store_thread_reference
118
+ end
119
+ ref = self.object_id.abs.to_s << args.object_id.abs.to_s
120
+ self.benelux.add_mark_open ref, :'#{meth}'
121
+ ret = #{meth_alias}(*args, &block)
122
+ self.benelux.add_mark_close ref, :'#{meth}'
123
+ ret
124
+ end
125
+ }
126
+ end
127
+
128
+ end
129
+
130
+
@@ -0,0 +1,37 @@
1
+ module Benelux
2
+ class Mark < Time
3
+ attr_accessor :name
4
+ attr_accessor :thread_id
5
+ attr_accessor :call_id
6
+ def self.now(n=nil,c=nil,t=nil)
7
+ v = super()
8
+ v.name, v.call_id, v.thread_id = n, c, t
9
+ v
10
+ end
11
+ def inspect(reftime=nil)
12
+ val = reftime.nil? ? self.to_f : (self.to_f - reftime.to_f)
13
+ args = [self.class, self.hexoid, self.name, val, thread_id, call_id]
14
+ "#<%s:%s name=%s at=%f thread_id=%s call_id=%s>" % args
15
+ end
16
+ def to_s(reftime=nil)
17
+ val = reftime.nil? ? self.to_f : (self.to_f - reftime.to_f)
18
+ val.to_s
19
+ end
20
+ def ==(other)
21
+ return false unless other.respond_to? :call_id
22
+ self.name == other.name &&
23
+ self.thread_id == other.thread_id &&
24
+ self.call_id == other.call_id &&
25
+ self.to_f == self.to_f
26
+ end
27
+ def same_timeline?(other)
28
+ return false unless other.respond_to? :thread_id
29
+ self.thread_id == other.thread_id
30
+ end
31
+ def same_call?(other)
32
+ return false unless other.respond_to? :call_id
33
+ self.thread_id == other.thread_id &&
34
+ self.call_id == other.call_id
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,6 @@
1
+
2
+
3
+ class Thread
4
+ extend Attic
5
+ attic :benelux
6
+ end
@@ -0,0 +1,84 @@
1
+
2
+ module Benelux
3
+ #
4
+ # |------+----+--+----+----|
5
+ # |
6
+ # 0.02
7
+ class Timeline < Array
8
+
9
+ def each(*args, &blk)
10
+ if args.empty?
11
+ super(&blk)
12
+ else
13
+ self.marks(*args).each(&blk)
14
+ end
15
+ end
16
+
17
+ ##def between(*names)
18
+ ## name_s, name_e = *names.collect { |n| Benelux.name n }
19
+ ## time_s, time_e = at(name_s), at(name_e)
20
+ ## time_e.first.to_f - time_s.first.to_f
21
+ ##end
22
+ ##def duration(*names)
23
+ ## name = Benelux.name *names
24
+ ## name_s, name_e = "#{name}_a", "#{name}_z"
25
+ ## between(name_s, name_e)
26
+ ##end
27
+
28
+ #
29
+ # obj.region(:execute) =>
30
+ # [[:execute_a, :execute_z], [:execute_a, :execute_z]]
31
+ #
32
+ def regions(*names)
33
+
34
+ end
35
+
36
+ #
37
+ # obj.marks(:execute_a, :execute_z, :do_request_a) =>
38
+ # [:execute_a, :do_request_a, :do_request_a, :execute_z]
39
+ #
40
+ def marks(*names)
41
+ names = names.flatten.collect { |n| n.to_s }
42
+ self.benelux.select do |mark|
43
+ names.member? mark.name.to_s
44
+ end
45
+ end
46
+
47
+ def duration(name)
48
+ name_s = Benelux.name name, SUFFIX_START
49
+ name_e = Benelux.name name, SUFFIX_END
50
+ end
51
+
52
+ def add_mark(call_id, name)
53
+ thread_id = Thread.current.object_id.abs
54
+ mark = Benelux::Mark.now(name, call_id, thread_id)
55
+ Benelux.thread_timeline << mark
56
+ self << mark
57
+ end
58
+
59
+ def add_mark_open(call_id, name)
60
+ add_mark call_id, Benelux.name(name, SUFFIX_START)
61
+ end
62
+
63
+ def add_mark_close(call_id, name)
64
+ add_mark call_id, Benelux.name(name, SUFFIX_END)
65
+ end
66
+
67
+ def to_line
68
+ marks = self.sort
69
+ str, prev = [], marks.first
70
+ marks.each do |mark|
71
+ str << "%s(%s):%.4f" % [mark.name, mark.thread_id, mark.to_s(prev)]
72
+ prev = mark
73
+ end
74
+ str.join('; ')
75
+ end
76
+ def +(other)
77
+ self << other
78
+ self.flatten
79
+ end
80
+ # Needs to compare thread id and call id.
81
+ #def <=>(other)
82
+ #end
83
+ end
84
+ end
@@ -0,0 +1,69 @@
1
+
2
+ group "Benelux"
3
+
4
+ library :benelux, 'lib'
5
+
6
+ tryouts "Basics" do
7
+
8
+ setup do
9
+ class ::Sleeper
10
+ def do_something() sleep rand/3 end
11
+ end
12
+ end
13
+
14
+ drill "Add timers to existing objects", true do
15
+ Benelux.add_timer Sleeper, :do_something
16
+ Sleeper.new.respond_to? :benelux
17
+ end
18
+
19
+ dream :class, Hash
20
+ dream { Hash[ Sleeper => [:do_something] ] }
21
+ drill "Benelux keeps track of timed objects" do
22
+ Benelux.timed_objects
23
+ end
24
+
25
+ dream [:do_something]
26
+ drill "A Benelux object has a benelux_timers method" do
27
+ Sleeper.new.benelux_timers
28
+ end
29
+
30
+ dream :class, Benelux::Timeline
31
+ dream :size, 10 # 5 * 2 = 10 (marks are stored for the method start and end)
32
+ drill "Creates a timeline" do
33
+ sleeper = Sleeper.new
34
+ 5.times { sleeper.do_something }
35
+ sleeper.benelux
36
+ end
37
+
38
+ dream :size, 4
39
+ drill "Timelines are stored per object" do
40
+ sleeper = Sleeper.new
41
+ Thread.new do
42
+ 2.times { sleeper.do_something }
43
+ end.join
44
+ sleeper.benelux
45
+ end
46
+
47
+ dream :class, Benelux::Timeline
48
+ dream :size, 10
49
+ drill "Creates a timeline for the thread" do
50
+ Benelux.thread_timeline
51
+ end
52
+
53
+ dream :class, Benelux::Timeline
54
+ dream :size, 14
55
+ drill "Creates a global timeline" do
56
+ Benelux.timeline
57
+ end
58
+
59
+ end
60
+
61
+
62
+ tryouts "Not supported" do
63
+
64
+ dream :exception, Benelux::NotSupported
65
+ drill "Class is not supported" do
66
+ Benelux.add_timer Class, :new
67
+ end
68
+
69
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: benelux
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0.001
5
+ platform: ruby
6
+ authors:
7
+ - Delano Mandelbaum
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-21 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hexoid
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: "Benelux: Little freakin' timers for your Ruby codes"
26
+ email: delano@solutious.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.rdoc
33
+ - LICENSE.txt
34
+ - CHANGES.txt
35
+ files:
36
+ - CHANGES.txt
37
+ - LICENSE.txt
38
+ - README.rdoc
39
+ - Rakefile
40
+ - benelux.gemspec
41
+ - lib/benelux.rb
42
+ - lib/benelux/mark.rb
43
+ - lib/benelux/mixins/thread.rb
44
+ - lib/benelux/timeline.rb
45
+ - tryouts/basic_tryouts.rb
46
+ has_rdoc: true
47
+ homepage: http://github.com/delano/benelux
48
+ licenses: []
49
+
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --line-numbers
53
+ - --title
54
+ - "Benelux: Little freakin' timers for your Ruby codes"
55
+ - --main
56
+ - README.rdoc
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ requirements: []
72
+
73
+ rubyforge_project: benelux
74
+ rubygems_version: 1.3.2
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: "Benelux: Little freakin' timers for your Ruby codes"
78
+ test_files: []
79
+