Module: TrackOpenInstances::ClassMethods

Defined in:
lib/track_open_instances.rb

Overview

Contains class-level methods added to classes including TrackOpenInstances

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#open_instancesArray<Object> (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Direct access to the internal list of tracked instances

Note: This returns all instances ever tracked unless explicitly removed. Use unclosed_instances for checking leaks. Direct use is uncommon.

Examples:

# Assuming MyResource includes TrackOpenInstances
res1 = MyResource.new
res2 = MyResource.new
res1.close
MyResource.open_instances #=> [#<MyResource... object_id=res2>] (after res1 removed)

Returns:

  • (Array<Object>)

    The raw list of currently tracked instances



121
122
123
124
125
# File 'lib/track_open_instances.rb', line 121

def open_instances
  @open_instances_mutex.synchronize do
    @open_instances.dup.freeze
  end
end

Instance Method Details

#add_open_instance(instance)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Adds an instance to the tracking list (thread-safe)

Typically called automatically by the instance's initialize method.

Parameters:

  • instance (Object)

    The instance to add



136
137
138
139
140
# File 'lib/track_open_instances.rb', line 136

def add_open_instance(instance)
  @open_instances_mutex.synchronize do
    @open_instances[instance] = OpenInstance.new(instance, caller(3..))
  end
end

#assert_no_open_instances

This method returns an undefined value.

Asserts that no instances of the class remain unclosed

Raises a ProcessExecuter::Error with a detailed report if any instances are found to be unclosed. Commonly used in test suite teardown blocks.

Examples:

# In RSpec teardown (e.g., after(:each))
MyResource.assert_no_open_instances

Raises:

  • (RuntimeError)

    If any instances are found unclosed



244
245
246
247
# File 'lib/track_open_instances.rb', line 244

def assert_no_open_instances
  report = open_instances_report
  raise(report.to_s) if report
end

#open_instance_countInteger

The number of currently open instances

Examples:

res1 = MyResource.new
res2 = MyResource.new
MyResource.open_instance_count #=> 1

Returns:

  • (Integer)


168
169
170
171
172
# File 'lib/track_open_instances.rb', line 168

def open_instance_count
  @open_instances_mutex.synchronize do
    @open_instances.size
  end
end

#open_instances_reportString?

Generates a report string listing unclosed instances and their creation stacks

Useful for debugging resource leaks. Returns nil if no instances are unclosed.

Examples:

res = MyResource.new
puts MyResource.open_instances_report
There is 1 open MyResource instance(s):
- object_id=701
  Created at:
    (caller stack line 1)
    (caller stack line 2)\n..."

Returns:

  • (String, nil)

    A formatted report string or nil if none are open



190
191
192
193
194
195
196
197
198
199
# File 'lib/track_open_instances.rb', line 190

def open_instances_report
  @open_instances_mutex.synchronize do
    return nil if @open_instances.count.zero?

    String.new.tap do |report|
      report << open_instances_report_header
      report << open_instances_report_body
    end
  end
end

#open_instances_report_bodyString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The body of the report detailing each open instance

Returns:

  • (String)


220
221
222
223
224
225
226
227
228
# File 'lib/track_open_instances.rb', line 220

def open_instances_report_body
  String.new.tap do |body|
    @open_instances.each do |instance, open_instance|
      body << " - object_id=#{instance.object_id}\n"
      body << "   Call stack when created:\n"
      open_instance.creation_stack.reverse.each { |line| body << "     #{line}\n" }
    end
  end
end

#open_instances_report_headerString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The header string for the report

Returns:

  • (String)


207
208
209
210
211
212
# File 'lib/track_open_instances.rb', line 207

def open_instances_report_header
  count = @open_instances.count

  "There #{count == 1 ? 'is' : 'are'} #{count} " \
    "open #{self.class} instance#{count == 1 ? '' : 's'}:\n"
end

#remove_open_instance(instance)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Removes an instance from the tracking list (thread-safe)

Typically called automatically by the instance's close method.

Parameters:

  • instance (Object)

    The instance to remove



151
152
153
154
155
# File 'lib/track_open_instances.rb', line 151

def remove_open_instance(instance)
  @open_instances_mutex.synchronize do
    @open_instances.delete(instance)
  end
end