Class: Dboard::Collector

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/collector.rb

Constant Summary collapse

DEFAULT_MIN_INTERVAL =

seconds

30

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize ⇒ Collector

Returns a new instance of Collector.



36
37
38
39
40
41
42
43
44
45
# File 'lib/collector.rb', line 36

def initialize
  @sources = {}
  @after_update_callback = lambda {}
  @error_callback = lambda { |exception| }
  @mutex = Mutex.new
  @last_update_at = {}
  @active = {}
  @pending = {}
  @refresh_locks = {}
end

Instance Attribute Details

#sources ⇒ Object (readonly)

Returns the value of attribute sources.



14
15
16
# File 'lib/collector.rb', line 14

def sources
  @sources
end

Class Method Details

.register_after_update_callback(callback) ⇒ Object



20
21
22
# File 'lib/collector.rb', line 20

def self.register_after_update_callback(callback)
  instance.register_after_update_callback(callback)
end

.register_error_callback(callback) ⇒ Object



24
25
26
# File 'lib/collector.rb', line 24

def self.register_error_callback(callback)
  instance.register_error_callback(callback)
end

.register_source(key, source_instance) ⇒ Object



16
17
18
# File 'lib/collector.rb', line 16

def self.register_source(key, source_instance)
  instance.register_source(key, source_instance)
end

.request_update(key, arg = nil) ⇒ Object



28
29
30
# File 'lib/collector.rb', line 28

def self.request_update(key, arg = nil)
  instance.request_update(key, arg)
end

.start ⇒ Object



32
33
34
# File 'lib/collector.rb', line 32

def self.start
  instance.start
end

Instance Method Details

#register_after_update_callback(callback) ⇒ Object



66
67
68
# File 'lib/collector.rb', line 66

def register_after_update_callback(callback)
  @after_update_callback = callback
end

#register_error_callback(callback) ⇒ Object



70
71
72
# File 'lib/collector.rb', line 70

def register_error_callback(callback)
  @error_callback = callback
end

#register_source(key, instance) ⇒ Object



61
62
63
64
# File 'lib/collector.rb', line 61

def register_source(key, instance)
  @sources.merge!({ key => instance })
  @refresh_locks[key] = Mutex.new
end

#request_update(key, arg = nil) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/collector.rb', line 74

def request_update(key, arg = nil)
  instance = @sources.fetch(key)
  floor = min_interval_for(instance)
  entry = arg.nil? ? FULL : arg
  leading = nil
  delay = @mutex.synchronize {
    now = monotonic_now
    (@pending[key] ||= []) << entry
    case decide_request(@active[key], @last_update_at[key], floor, now)
    when :coalesce
      return
    when :refresh_now
      @active[key] = true
      leading = @pending[key]
      @pending[key] = []
      0
    when :schedule
      @active[key] = true
      floor - (now - @last_update_at[key])
    end
  }
  spawn { run_worker(key, instance, floor, delay, leading) }
end

#start ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/collector.rb', line 47

def start
  @sources.each do |source, instance|
    Thread.new do
      wait_a_little_bit_to_not_start_all_fetches_at_once

      loop do
        request_update(source)
        sleep instance.update_interval
      end
    end
  end
  loop { sleep 1 }
end

#update_source(source, instance, batch = nil) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/collector.rb', line 98

def update_source(source, instance, batch = nil)
  begin
    data = fetch_source(instance, batch)
    publish_data(source, data)
  ensure
    @after_update_callback.call
  end
rescue Exception => ex
  puts "Failed to update #{source}: #{ex.message}"
  puts ex.backtrace
  @error_callback.call(ex)
end