File: background_thread_registry.rb

package info (click to toggle)
ruby-mongo 2.21.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 14,764 kB
  • sloc: ruby: 108,806; makefile: 5; sh: 2
file content (60 lines) | stat: -rw-r--r-- 1,476 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# frozen_string_literal: true
# rubocop:todo all

require 'singleton'
require 'ostruct'

module Mongo
  module BackgroundThread

    alias :start_without_tracking! :start!

    def start!
      start_without_tracking!.tap do |thread|
        BackgroundThreadRegistry.instance.register(self, thread)
      end
    end
  end
end

class BackgroundThreadRegistry
  include Singleton

  def initialize
    @lock = Mutex.new
    @records = []
  end

  def register(object, thread)
    @lock.synchronize do
      @records << OpenStruct.new(
        thread: thread,
        object: object,
        # When rake spec:prepare is run, the current_example method is not defined
        example: RSpec.respond_to?(:current_example) ? RSpec.current_example : nil,
      )
    end
  end

  def verify_empty!
    @lock.synchronize do
      alive_thread_records = @records.select { |record| record.thread.alive? }
      if alive_thread_records.any?
        msg = +"Live background threads after closing all clients:"
        alive_thread_records.each do |record|
          msg << "\n  #{record.object}"
          if record.object.respond_to?(:options)
            msg << "\n  with options: #{record.object.options}"
          end
          if record.example
            msg << "\n  in #{record.example.id}: #{record.example.full_description}"
          else
            msg << "\n  not in an example"
          end
        end
        raise msg
      end
      @records.clear
    end
  end
end