Skip to content

Commit 056e657

Browse files
committed
Better handling of cluster sampling.
1 parent 18a13cc commit 056e657

File tree

5 files changed

+38
-5
lines changed

5 files changed

+38
-5
lines changed

lib/memory/leak/cluster.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def apply_limit!(total_size_limit = @total_size_limit)
8787
def sample!
8888
System.memory_usages(@processes.keys) do |process_id, memory_usage|
8989
if monitor = @processes[process_id]
90-
monitor.current_size = memory_usage
90+
monitor.sample!(memory_usage)
9191
end
9292
end
9393
end
@@ -96,8 +96,6 @@ def sample!
9696
#
9797
# @yields {|process_id, monitor| ...} each process ID and monitor that is leaking or exceeds the memory limit.
9898
def check!(&block)
99-
return to_enum(__method__) unless block_given?
100-
10199
self.sample!
102100

103101
leaking = []
@@ -110,10 +108,14 @@ def check!(&block)
110108
end
111109
end
112110

113-
leaking.each(&block)
111+
if block_given?
112+
leaking.each(&block)
113+
end
114114

115115
# Finally, apply any per-cluster memory limits:
116116
apply_limit!(@total_size_limit, &block) if @total_size_limit
117+
118+
return leaking
117119
end
118120
end
119121
end

lib/memory/leak/monitor.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ class Monitor
3333
def initialize(process_id = Process.pid, maximum_size: nil, maximum_size_limit: nil, threshold_size: DEFAULT_THRESHOLD_SIZE, increase_limit: DEFAULT_INCREASE_LIMIT)
3434
@process_id = process_id
3535

36+
@sample_count = 0
3637
@current_size = nil
3738
@maximum_size = maximum_size
3839
@maximum_size_limit = maximum_size_limit
40+
@maximum_observed_size = nil
3941

4042
@threshold_size = threshold_size
4143
@increase_count = 0
@@ -46,6 +48,7 @@ def initialize(process_id = Process.pid, maximum_size: nil, maximum_size_limit:
4648
def as_json(...)
4749
{
4850
process_id: @process_id,
51+
sample_count: @sample_count,
4952
current_size: @current_size,
5053
maximum_size: @maximum_size,
5154
maximum_size_limit: @maximum_size_limit,
@@ -83,6 +86,9 @@ def memory_usage
8386
System.memory_usage(@process_id)
8487
end
8588

89+
# @attribute [Integer] The number of samples taken.
90+
attr :sample_count
91+
8692
# @returns [Integer] The last sampled memory usage.
8793
def current_size
8894
@current_size ||= memory_usage
@@ -119,7 +125,9 @@ def leaking?
119125
# Capture a memory usage sample and yield if a memory leak is detected.
120126
#
121127
# @yields {|sample, monitor| ...} If a memory leak is detected.
122-
def sample!
128+
def sample!(memory_usage = self.memory_usage)
129+
@sample_count += 1
130+
123131
self.current_size = memory_usage
124132

125133
if @maximum_observed_size

releases.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Releases
22

3+
## Unreleased
4+
5+
- Added `sample_count` attribute to monitor to track number of samples taken.
6+
- `check!` method in cluster now returns an array of leaking monitors if no block is given.
7+
- `Cluster#check!` now invokes `Monitor#sample!` to ensure memory usage is updated before checking for leaks.
8+
39
## v0.5.0
410

511
- Improved variable names.

test/memory/leak/cluster.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@
4545

4646
attr :children
4747

48+
it "samples memory usage" do
49+
cluster.check!.to_a
50+
51+
children.each do |process_id, child|
52+
monitor = cluster.processes[process_id]
53+
expect(monitor).to have_attributes(
54+
sample_count: be > 0,
55+
current_size: be_a(Integer),
56+
)
57+
end
58+
end
59+
4860
it "can detect memory leaks" do
4961
child = children.values.first
5062
monitor = cluster.processes[child.process_id]
@@ -58,6 +70,10 @@
5870
monitor.sample!
5971
end
6072

73+
expect(monitor).to have_attributes(
74+
sample_count: be > 0,
75+
)
76+
6177
cluster.check! do |process_id, monitor|
6278
expect(process_id).to be == child.process_id
6379
expect(monitor.increase_count).to be == monitor.increase_limit

test/memory/leak/monitor.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
# It is very unlikely that in the above test, the threshold of the 2nd and 3rd samples will be greater than the threshold of the 1st sample.
3737
# Therefore, the count should be 0.
3838
expect(monitor.increase_count).to be == 0
39+
expect(monitor.sample_count).to be == 3
3940
end
4041

4142
with "a leaking child process" do

0 commit comments

Comments
 (0)