benelux 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,11 @@
1
1
  BENELUX, CHANGES
2
2
 
3
+ #### 0.5.2 (2009-11-02) ###############################
4
+
5
+ * ADDED: Selectable#rfilter
6
+ * ADDED: Timeline#messages
7
+
8
+
3
9
  #### 0.5.1 (2009-10-29) ###############################
4
10
 
5
11
  * FIXED: Timeline#clear
@@ -1,12 +1,14 @@
1
- = Benelux v0.4 (IN PROGRESS)
1
+ = Benelux v0.5
2
2
 
3
- <b>A madhouse of timers for your Ruby codes</b>
3
+ <b>A mad timeline for your Ruby codes</b>
4
4
 
5
5
 
6
6
  == Features
7
7
 
8
8
  * Create timers for any Ruby method
9
+ * Store arbitrary messages
9
10
  * Granular statistics
11
+ * Thread-safe
10
12
 
11
13
 
12
14
  == Installation
@@ -32,7 +34,7 @@ Get it in one of the following ways:
32
34
  == Thanks
33
35
 
34
36
  * Alexis Sellier for fielding my Ruby questions
35
- * Tara Dougans for the motivational speaches
37
+ * Tara Dougans for the motivational speeches
36
38
 
37
39
 
38
40
  == License
@@ -1,8 +1,8 @@
1
1
  @spec = Gem::Specification.new do |s|
2
2
  s.name = "benelux"
3
3
  s.rubyforge_project = 'benelux'
4
- s.version = "0.5.1"
5
- s.summary = "Benelux: Little freakin' timers for your Ruby codes"
4
+ s.version = "0.5.2"
5
+ s.summary = "Benelux: A mad timeline for Ruby codes"
6
6
  s.description = s.summary
7
7
  s.author = "Delano Mandelbaum"
8
8
  s.email = "delano@solutious.com"
@@ -29,7 +29,6 @@
29
29
  lib/benelux/mixins/thread.rb
30
30
  lib/benelux/packer.rb
31
31
  lib/benelux/range.rb
32
- lib/benelux/reporter.rb
33
32
  lib/benelux/stats.rb
34
33
  lib/benelux/timeline.rb
35
34
  lib/benelux/track.rb
@@ -5,7 +5,7 @@ require 'thwait'
5
5
  require 'selectable'
6
6
 
7
7
  module Benelux
8
- VERSION = "0.5.1"
8
+ VERSION = "0.5.2"
9
9
  NOTSUPPORTED = [Class, Object, Kernel]
10
10
 
11
11
  class BeneluxError < RuntimeError; end
@@ -76,7 +76,8 @@ module Benelux
76
76
  end
77
77
  Benelux.current_track :main
78
78
 
79
- # Only updates data from threads that are dead
79
+ # Only updates data from threads that
80
+ # are dead and rotated timelines.
80
81
  def Benelux.update_global_timeline
81
82
  @@mutex.synchronize do
82
83
  dthreads = Benelux.known_threads.select { |t|
@@ -21,6 +21,7 @@ module Benelux
21
21
  include Selectable
22
22
  attr_accessor :ranges
23
23
  attr_accessor :stats
24
+ attr_accessor :messages
24
25
  attr_accessor :default_tags
25
26
  attr_reader :caller
26
27
  def initialize(*args)
@@ -28,6 +29,7 @@ module Benelux
28
29
  @ranges = SelectableArray.new
29
30
  @default_tags = Selectable::Tags.new
30
31
  @stats = Benelux::Stats.new
32
+ @messages = SelectableArray.new
31
33
  add_default_tag :thread_id => Thread.current.object_id.abs
32
34
  super
33
35
  end
@@ -81,6 +83,7 @@ module Benelux
81
83
  next unless stat.tags >= tags
82
84
  stats += stat
83
85
  end
86
+ tl.messages = messages
84
87
  tl.stats = stats
85
88
  tl
86
89
  end
@@ -121,12 +124,28 @@ module Benelux
121
124
  end
122
125
  end
123
126
 
127
+ def messages(tags=Selectable::Tags.new)
128
+ ret = @messages.select do |msg|
129
+ (tags.nil? || msg.tags >= tags)
130
+ end
131
+ SelectableArray.new ret
132
+ end
133
+
124
134
  def clear
125
135
  @ranges.clear
126
136
  @stats.clear
137
+ @messages.clear
127
138
  super
128
139
  end
129
140
 
141
+ def add_message(str, tags={})
142
+ msg = TaggableString.new str
143
+ msg.add_tags self.default_tags
144
+ msg.add_tags tags
145
+ @messages << msg
146
+ msg
147
+ end
148
+
130
149
  def add_count(name, count, tags={})
131
150
  tags = tags.merge self.default_tags
132
151
  self.stats.add_group(name)
@@ -155,16 +174,18 @@ module Benelux
155
174
  def merge!(*timelines)
156
175
  timelines.each do |tl|
157
176
  self.push *tl
158
- self.ranges.push *tl.ranges
159
- self.stats += tl.stats
177
+ @ranges.push *tl.ranges
178
+ @messages.push *tl.messages
179
+ @stats += tl.stats
160
180
  end
161
181
  self
162
182
  end
163
183
 
164
184
  def +(other)
165
185
  self.push *other
166
- self.ranges.push *other.ranges
167
- self.stats += other.stats
186
+ @ranges.push *other.ranges
187
+ @messages.push *tl.messages
188
+ @stats += other.stats
168
189
  self
169
190
  end
170
191
  # Needs to compare thread id and call id.
@@ -51,8 +51,15 @@ module Selectable
51
51
  items = self.select { |obj| obj.tags >= tags }
52
52
  self.class.new items
53
53
  end
54
-
55
-
54
+
55
+ # Reverse filter.
56
+ def rfilter(*tags)
57
+ tags = Selectable.normalize tags
58
+ # select returns an Array. We want a Selectable.
59
+ items = self.select { |obj| obj.tags < tags }
60
+ self.class.new items
61
+ end
62
+
56
63
  def filter!(*tags)
57
64
  tags = Selectable.normalize tags
58
65
  self.delete_if { |obj| obj.tags < tags }
@@ -77,3 +84,7 @@ end
77
84
  class SelectableHash < Hash
78
85
  include Selectable
79
86
  end
87
+
88
+ class TaggableString < String
89
+ include Selectable::Object
90
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: benelux
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Delano Mandelbaum
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-29 00:00:00 -04:00
12
+ date: 2009-11-02 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,7 +22,7 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: "0"
24
24
  version:
25
- description: "Benelux: Little freakin' timers for your Ruby codes"
25
+ description: "Benelux: A mad timeline for Ruby codes"
26
26
  email: delano@solutious.com
27
27
  executables: []
28
28
 
@@ -44,7 +44,6 @@ files:
44
44
  - lib/benelux/mixins/thread.rb
45
45
  - lib/benelux/packer.rb
46
46
  - lib/benelux/range.rb
47
- - lib/benelux/reporter.rb
48
47
  - lib/benelux/stats.rb
49
48
  - lib/benelux/timeline.rb
50
49
  - lib/benelux/track.rb
@@ -69,7 +68,7 @@ post_install_message:
69
68
  rdoc_options:
70
69
  - --line-numbers
71
70
  - --title
72
- - "Benelux: Little freakin' timers for your Ruby codes"
71
+ - "Benelux: A mad timeline for Ruby codes"
73
72
  - --main
74
73
  - README.rdoc
75
74
  require_paths:
@@ -89,9 +88,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
88
  requirements: []
90
89
 
91
90
  rubyforge_project: benelux
92
- rubygems_version: 1.3.3
91
+ rubygems_version: 1.3.5
93
92
  signing_key:
94
93
  specification_version: 3
95
- summary: "Benelux: Little freakin' timers for your Ruby codes"
94
+ summary: "Benelux: A mad timeline for Ruby codes"
96
95
  test_files: []
97
96
 
@@ -1,93 +0,0 @@
1
-
2
- module Benelux
3
- class Reporter
4
- attr_reader :thread
5
- attr_reader :thwait
6
- @@mutex = Mutex.new
7
- def initialize(*threads)
8
- @thwait = ThreadsWait.new
9
- @abort, @running = false, false
10
- @tmerge = Benelux::Stats::Calculator.new
11
- add_threads *threads
12
- @tbd = []
13
- @thread = create_reporting_thread
14
- end
15
- def create_reporting_thread(priority=-3)
16
- t = Thread.new do
17
- 5.times { # Give the app 1 second to generate threads
18
- break if @start && !@thwait.empty?
19
- sleep 0.2
20
- }
21
-
22
- run_loop
23
- end
24
- t.priority = priority
25
- t
26
- end
27
- def add_threads(*threads)
28
- threads.each do |thread|
29
- raise BadRecursion, "Cannot report on self" if thread == @thread
30
- next if thread == Thread.main
31
- @thwait.join_nowait thread
32
- end
33
- @start = true
34
- end
35
- alias_method :add_thread, :add_threads
36
- def running_threads?
37
- # Any status that is not nil or false is running
38
- !@thwait.threads.select { |t| !t.nil? && t.status }.empty?
39
- end
40
-
41
- def run_loop
42
- loop do
43
- break if @abort
44
- process(@tbd)
45
- if @thwait.empty?
46
- sleep 0.01 # prevent mad thrashing.
47
- # If there are no threads running we can stop
48
- # because there are none waiting in the queue.
49
- running_threads? ? next : break
50
- end
51
- t = @thwait.next_wait
52
- @tbd << t.timeline
53
- end
54
- end
55
- def process(tbd)
56
- return if tbd.empty?
57
- (start = Time.now)
58
- Benelux.timeline.merge! *tbd
59
- (endt = Time.now)
60
- dur = (endt - start).to_f
61
- #p [:processed, tbd.size, dur]
62
- tbd.clear
63
- @tmerge.sample dur
64
- end
65
- # We don't add the main thread to the wait group
66
- # so we need to manually force processing for
67
- # that thread.
68
- def force_update
69
- @abort = false
70
- @tbd << Thread.current.timeline
71
- run_loop
72
- end
73
- # Call this once the active threads have stopped. It
74
- # increases the priority of the processing thread,
75
- # waits for it to finish and then calls force_update
76
- # to get the main threads stats into the timeline.
77
- def wait
78
- if @thread && Thread.current == Thread.main
79
- @abort = true
80
- @thread.priority = 0
81
- @thread.join if @thread.status
82
- force_update
83
- else
84
- msg = "Not main thread. Skipping call to wait from #{caller[0]}"
85
- Benelux.ld msg
86
- end
87
- end
88
- def stop() @abort = true end
89
- def done?() @done end
90
- def aborted?() @abort end
91
- def running?() @running end
92
- end
93
- end